summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/debugger.cc17
-rw-r--r--runtime/debugger.h3
-rw-r--r--runtime/dex_file_annotations.cc34
-rw-r--r--runtime/dex_file_annotations.h2
-rw-r--r--runtime/jdwp/jdwp_handler.cc15
-rwxr-xr-xtools/run-jdwp-tests.sh13
6 files changed, 78 insertions, 6 deletions
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 63794bff6f..d0b50fe820 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -1092,6 +1092,23 @@ JDWP::JdwpError Dbg::GetSignature(JDWP::RefTypeId class_id, std::string* signatu
return JDWP::ERR_NONE;
}
+JDWP::JdwpError Dbg::GetSourceDebugExtension(JDWP::RefTypeId class_id,
+ std::string* extension_data) {
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(class_id, &error);
+ if (c == nullptr) {
+ return error;
+ }
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::Class> klass(hs.NewHandle(c));
+ const char* data = annotations::GetSourceDebugExtension(klass);
+ if (data == nullptr) {
+ return JDWP::ERR_ABSENT_INFORMATION;
+ }
+ *extension_data = data;
+ return JDWP::ERR_NONE;
+}
+
JDWP::JdwpError Dbg::GetSourceFile(JDWP::RefTypeId class_id, std::string* result) {
JDWP::JdwpError error;
mirror::Class* c = DecodeClass(class_id, &error);
diff --git a/runtime/debugger.h b/runtime/debugger.h
index 27124e19fb..4f3ff40e86 100644
--- a/runtime/debugger.h
+++ b/runtime/debugger.h
@@ -288,6 +288,9 @@ class Dbg {
REQUIRES_SHARED(Locks::mutator_lock_);
static JDWP::JdwpError GetSignature(JDWP::RefTypeId ref_type_id, std::string* signature)
REQUIRES_SHARED(Locks::mutator_lock_);
+ static JDWP::JdwpError GetSourceDebugExtension(JDWP::RefTypeId ref_type_id,
+ std::string* extension_data)
+ REQUIRES_SHARED(Locks::mutator_lock_);
static JDWP::JdwpError GetSourceFile(JDWP::RefTypeId ref_type_id, std::string* source_file)
REQUIRES_SHARED(Locks::mutator_lock_);
static JDWP::JdwpError GetObjectTag(JDWP::ObjectId object_id, uint8_t* tag)
diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc
index 6b9654dc49..7d56bca6ce 100644
--- a/runtime/dex_file_annotations.cc
+++ b/runtime/dex_file_annotations.cc
@@ -1420,6 +1420,40 @@ mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForClass(Handle<mirro
return GetSignatureValue(data, annotation_set);
}
+const char* GetSourceDebugExtension(Handle<mirror::Class> klass) {
+ ClassData data(klass);
+ const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
+ if (annotation_set == nullptr) {
+ return nullptr;
+ }
+ const DexFile::AnnotationItem* annotation_item = SearchAnnotationSet(
+ data.GetDexFile(),
+ annotation_set,
+ "Ldalvik/annotation/SourceDebugExtension;",
+ DexFile::kDexVisibilitySystem);
+ if (annotation_item == nullptr) {
+ return nullptr;
+ }
+ const uint8_t* annotation =
+ SearchEncodedAnnotation(data.GetDexFile(), annotation_item->annotation_, "value");
+ if (annotation == nullptr) {
+ return nullptr;
+ }
+ DexFile::AnnotationValue annotation_value;
+ if (!ProcessAnnotationValue<false>(data,
+ &annotation,
+ &annotation_value,
+ ScopedNullHandle<mirror::Class>(),
+ DexFile::kAllRaw)) {
+ return nullptr;
+ }
+ if (annotation_value.type_ != DexFile::kDexAnnotationString) {
+ return nullptr;
+ }
+ dex::StringIndex index(static_cast<uint32_t>(annotation_value.value_.GetI()));
+ return data.GetDexFile().StringDataByIdx(index);
+}
+
bool IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class> annotation_class) {
ClassData data(klass);
const DexFile::AnnotationSetItem* annotation_set = FindAnnotationSetForClass(data);
diff --git a/runtime/dex_file_annotations.h b/runtime/dex_file_annotations.h
index c66c5bdb8b..651c9844eb 100644
--- a/runtime/dex_file_annotations.h
+++ b/runtime/dex_file_annotations.h
@@ -89,6 +89,8 @@ bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags)
REQUIRES_SHARED(Locks::mutator_lock_);
mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForClass(Handle<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_);
+const char* GetSourceDebugExtension(Handle<mirror::Class> klass)
+ REQUIRES_SHARED(Locks::mutator_lock_);
bool IsClassAnnotationPresent(Handle<mirror::Class> klass,
Handle<mirror::Class> annotation_class)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc
index 971d03958c..e8a9904dc6 100644
--- a/runtime/jdwp/jdwp_handler.cc
+++ b/runtime/jdwp/jdwp_handler.cc
@@ -335,7 +335,7 @@ static JdwpError VM_CapabilitiesNew(JdwpState*, Request* request, ExpandBuf* rep
expandBufAdd1(reply, false); // canUnrestrictedlyRedefineClasses
expandBufAdd1(reply, false); // canPopFrames
expandBufAdd1(reply, true); // canUseInstanceFilters
- expandBufAdd1(reply, false); // canGetSourceDebugExtension
+ expandBufAdd1(reply, true); // canGetSourceDebugExtension
expandBufAdd1(reply, false); // canRequestVMDeathEvent
expandBufAdd1(reply, false); // canSetDefaultStratum
expandBufAdd1(reply, true); // 1.6: canGetInstanceInfo
@@ -499,13 +499,18 @@ static JdwpError RT_ClassObject(JdwpState*, Request* request, ExpandBuf* pReply)
/*
* Returns the value of the SourceDebugExtension attribute.
- *
- * JDB seems interested, but DEX files don't currently support this.
*/
-static JdwpError RT_SourceDebugExtension(JdwpState*, Request*, ExpandBuf*)
+static JdwpError RT_SourceDebugExtension(JdwpState*, Request* request, ExpandBuf* pReply)
REQUIRES_SHARED(Locks::mutator_lock_) {
/* referenceTypeId in, string out */
- return ERR_ABSENT_INFORMATION;
+ RefTypeId refTypeId = request->ReadRefTypeId();
+ std::string extension_data;
+ JdwpError status = Dbg::GetSourceDebugExtension(refTypeId, &extension_data);
+ if (status != ERR_NONE) {
+ return status;
+ }
+ expandBufAddUtf8String(pReply, extension_data);
+ return ERR_NONE;
}
static JdwpError RT_Signature(JdwpState*, Request* request, ExpandBuf* pReply, bool with_generic)
diff --git a/tools/run-jdwp-tests.sh b/tools/run-jdwp-tests.sh
index 07c300e7a7..720b1d2f5d 100755
--- a/tools/run-jdwp-tests.sh
+++ b/tools/run-jdwp-tests.sh
@@ -108,6 +108,17 @@ while true; do
fi
done
+# The JDWP tests include a class with a SourceDebugExtension attribute. Convert this class into
+# a DEX so the JDWP SourceDebugExtension can be tested. There is no corresponding java file as by
+# definition the class file is generated from a different language.
+jsr45_dex=$ANDROID_HOST_OUT/jsr45-test.dex
+(cd $ANDROID_BUILD_TOP/external/apache-harmony/jdwp/src/test/resources &&
+ dx --dex --output=$jsr45_dex org/apache/harmony/jpda/tests/jdwp/Events/SourceDebugExtensionMockClass.class )
+if [ $? -ne 0 ]; then
+ echo Failed to convert class file to DEX. >&2
+ exit 1
+fi
+
# For the host:
#
# If, on the other hand, there is a variant set, use it to modify the art_debugee parameter to
@@ -160,7 +171,7 @@ vogar $vm_command \
--vm-arg -Djpda.settings.waitingTime=$jdwp_test_timeout \
--vm-arg -Djpda.settings.transportAddress=127.0.0.1:55107 \
--vm-arg -Djpda.settings.debuggeeJavaPath="$art_debugee $image $debuggee_args" \
- --classpath $test_jack \
+ --classpath $test_jack --resource-classpath $jsr45_dex \
--toolchain jack --language JN \
--vm-arg -Xcompiler-option --vm-arg --debuggable \
--jack-arg -g \