diff options
author | Jeff Hao <jeffhao@google.com> | 2014-03-13 22:39:26 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-03-13 22:39:26 +0000 |
commit | 773965c0168c5bd19d727ddb950c74382dcb9fa4 (patch) | |
tree | 3eef49f7cba5a088b970b893e075c0b0bfdf5415 | |
parent | 53fca11882e634b67aca4f112585413a1918b5ad (diff) | |
parent | 3addc29228cb3a2d263e1d91a0b7d4e0fe26e246 (diff) | |
download | android_art-773965c0168c5bd19d727ddb950c74382dcb9fa4.tar.gz android_art-773965c0168c5bd19d727ddb950c74382dcb9fa4.tar.bz2 android_art-773965c0168c5bd19d727ddb950c74382dcb9fa4.zip |
Merge "Fix stack trace for proxy methods and added test case." into klp-dev
-rw-r--r-- | runtime/thread.cc | 50 | ||||
-rw-r--r-- | test/044-proxy/expected.txt | 5 | ||||
-rw-r--r-- | test/044-proxy/src/BasicTest.java | 22 |
3 files changed, 52 insertions, 25 deletions
diff --git a/runtime/thread.cc b/runtime/thread.cc index 60a3bf8196..7fd40c945c 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -1332,7 +1332,7 @@ class BuildInternalStackTraceVisitor : public StackVisitor { return true; // Ignore runtime frames (in particular callee save). } method_trace_->Set(count_, m); - dex_pc_trace_->Set(count_, GetDexPc()); + dex_pc_trace_->Set(count_, m->IsProxyMethod() ? DexFile::kDexNoIndex : GetDexPc()); ++count_; return true; } @@ -1384,7 +1384,6 @@ jobjectArray Thread::InternalStackTraceToStackTraceElementArray(JNIEnv* env, job mirror::ObjectArray<mirror::Object>* method_trace = soa.Decode<mirror::ObjectArray<mirror::Object>*>(internal); int32_t depth = method_trace->GetLength() - 1; - mirror::IntArray* pc_trace = down_cast<mirror::IntArray*>(method_trace->Get(depth)); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); @@ -1413,19 +1412,32 @@ jobjectArray Thread::InternalStackTraceToStackTraceElementArray(JNIEnv* env, job for (int32_t i = 0; i < depth; ++i) { // Prepare parameters for StackTraceElement(String cls, String method, String file, int line) mirror::ArtMethod* method = down_cast<mirror::ArtMethod*>(method_trace->Get(i)); - mh.ChangeMethod(method); - uint32_t dex_pc = pc_trace->Get(i); - int32_t line_number = mh.GetLineNumFromDexPC(dex_pc); - // Allocate element, potentially triggering GC - // TODO: reuse class_name_object via Class::name_? - const char* descriptor = mh.GetDeclaringClassDescriptor(); - CHECK(descriptor != NULL); - std::string class_name(PrettyDescriptor(descriptor)); - SirtRef<mirror::String> class_name_object(soa.Self(), - mirror::String::AllocFromModifiedUtf8(soa.Self(), - class_name.c_str())); - if (class_name_object.get() == NULL) { - return NULL; + MethodHelper mh(method); + int32_t line_number; + SirtRef<mirror::String> class_name_object(soa.Self(), NULL); + SirtRef<mirror::String> source_name_object(soa.Self(), NULL); + if (method->IsProxyMethod()) { + line_number = -1; + class_name_object.reset(method->GetDeclaringClass()->GetName()); + // source_name_object intentionally left null for proxy methods + } else { + mirror::IntArray* pc_trace = down_cast<mirror::IntArray*>(method_trace->Get(depth)); + uint32_t dex_pc = pc_trace->Get(i); + line_number = mh.GetLineNumFromDexPC(dex_pc); + // Allocate element, potentially triggering GC + // TODO: reuse class_name_object via Class::name_? + const char* descriptor = mh.GetDeclaringClassDescriptor(); + CHECK(descriptor != NULL); + std::string class_name(PrettyDescriptor(descriptor)); + class_name_object.reset(mirror::String::AllocFromModifiedUtf8(soa.Self(), class_name.c_str())); + if (class_name_object.get() == NULL) { + return NULL; + } + const char* source_file = mh.GetDeclaringClassSourceFile(); + source_name_object.reset(mirror::String::AllocFromModifiedUtf8(soa.Self(), source_file)); + if (source_name_object.get() == NULL) { + return NULL; + } } const char* method_name = mh.GetName(); CHECK(method_name != NULL); @@ -1435,14 +1447,8 @@ jobjectArray Thread::InternalStackTraceToStackTraceElementArray(JNIEnv* env, job if (method_name_object.get() == NULL) { return NULL; } - const char* source_file = mh.GetDeclaringClassSourceFile(); - SirtRef<mirror::String> source_name_object(soa.Self(), mirror::String::AllocFromModifiedUtf8(soa.Self(), - source_file)); mirror::StackTraceElement* obj = mirror::StackTraceElement::Alloc(soa.Self(), - class_name_object.get(), - method_name_object.get(), - source_name_object.get(), - line_number); + class_name_object.get(), method_name_object.get(), source_name_object.get(), line_number); if (obj == NULL) { return NULL; } diff --git a/test/044-proxy/expected.txt b/test/044-proxy/expected.txt index eafaf1d188..400a1619cd 100644 --- a/test/044-proxy/expected.txt +++ b/test/044-proxy/expected.txt @@ -42,6 +42,7 @@ Invoke public abstract java.lang.String Shapes.blob() (no args) --- blob Success: method blob res=mix +$Proxy1.getTrace null:-1 Invoke public abstract void Shapes.upChuck() (no args) Got expected ioobe @@ -49,8 +50,8 @@ Invoke public abstract void Shapes.upCheck() throws java.lang.InterruptedExcepti (no args) Got expected ie -Proxy interfaces: [interface Quads, interface Colors] -Proxy methods: [public final java.lang.String $Proxy1.blob(), public final double $Proxy1.blue(int), public final R0a $Proxy1.checkMe(), public final R0aa $Proxy1.checkMe(), public final R0base $Proxy1.checkMe(), public final void $Proxy1.circle(int), public final boolean $Proxy1.equals(java.lang.Object), public final int $Proxy1.green(double), public final int $Proxy1.hashCode(), public final int $Proxy1.mauve(java.lang.String), public final int $Proxy1.rectangle(int,int), public final int $Proxy1.red(float), public final int $Proxy1.square(int,int), public final java.lang.String $Proxy1.toString(), public final int $Proxy1.trapezoid(int,double,int), public final void $Proxy1.upCheck() throws java.lang.InterruptedException, public final void $Proxy1.upChuck()] +Proxy interfaces: [interface Quads, interface Colors, interface Trace] +Proxy methods: [public final java.lang.String $Proxy1.blob(), public final double $Proxy1.blue(int), public final R0a $Proxy1.checkMe(), public final R0aa $Proxy1.checkMe(), public final R0base $Proxy1.checkMe(), public final void $Proxy1.circle(int), public final boolean $Proxy1.equals(java.lang.Object), public final void $Proxy1.getTrace(), public final int $Proxy1.green(double), public final int $Proxy1.hashCode(), public final int $Proxy1.mauve(java.lang.String), public final int $Proxy1.rectangle(int,int), public final int $Proxy1.red(float), public final int $Proxy1.square(int,int), public final java.lang.String $Proxy1.toString(), public final int $Proxy1.trapezoid(int,double,int), public final void $Proxy1.upCheck() throws java.lang.InterruptedException, public final void $Proxy1.upChuck()] Decl annos: [] Param annos (0) : [] Dupe threw expected exception diff --git a/test/044-proxy/src/BasicTest.java b/test/044-proxy/src/BasicTest.java index 46aa3feea2..ea46f49f2b 100644 --- a/test/044-proxy/src/BasicTest.java +++ b/test/044-proxy/src/BasicTest.java @@ -51,6 +51,8 @@ public class BasicTest { colors.blue(777); colors.mauve("sorry"); colors.blob(); + Trace trace = (Trace) proxy; + trace.getTrace(); try { shapes.upChuck(); @@ -96,7 +98,7 @@ public class BasicTest { /* create the proxy class */ Class proxyClass = Proxy.getProxyClass(Shapes.class.getClassLoader(), - new Class[] { Quads.class, Colors.class }); + new Class[] { Quads.class, Colors.class, Trace.class }); /* create a proxy object, passing the handler object in */ Object proxy = null; @@ -156,6 +158,10 @@ interface Colors { public R0aa checkMe(); } +interface Trace { + public void getTrace(); +} + /* * Some return types. */ @@ -248,6 +254,20 @@ class MyInvocationHandler implements InvocationHandler { throw new RuntimeException("huh?"); } + if (method.getDeclaringClass() == Trace.class) { + if (method.getName().equals("getTrace")) { + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + for (int i = 0; i < stackTrace.length; i++) { + StackTraceElement ste = stackTrace[i]; + if (ste.getMethodName().equals("getTrace")) { + System.out.println(ste.getClassName() + "." + ste.getMethodName() + " " + + ste.getFileName() + ":" + ste.getLineNumber()); + } + } + return null; + } + } + System.out.println("Invoke " + method); if (args == null || args.length == 0) { System.out.println(" (no args)"); |