diff options
author | 2022-12-20 08:45:09 +0000 | |
---|---|---|
committer | 2022-12-20 13:28:18 +0000 | |
commit | 530524e8cba94d01ef9857ec5ab6d14a13923dfb (patch) | |
tree | 4d3c36a5edb1a0de7e55bfdc8c458dff5076b13c | |
parent | 4a3a8044c18e8a82bcfd7825a6a99be3aa86342c (diff) |
Skip `VMStack.getThreadStackTrace()` in stack traces.
Test: Added a check to run-test 051-thread.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 240140214
Change-Id: I14963fe9cc78a1fb5ac4e6624fa824c23cb572d0
-rw-r--r-- | runtime/thread.cc | 22 | ||||
-rw-r--r-- | runtime/well_known_classes.cc | 13 | ||||
-rw-r--r-- | runtime/well_known_classes.h | 1 | ||||
-rw-r--r-- | test/051-thread/src/Main.java | 4 |
4 files changed, 28 insertions, 12 deletions
diff --git a/runtime/thread.cc b/runtime/thread.cc index 000078ff6f..b46192eb20 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -2874,25 +2874,25 @@ class FetchStackTraceVisitor : public StackVisitor { max_saved_frames_(max_saved_frames) {} bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) { - // We want to skip frames up to and including the exception's constructor. - // Note we also skip the frame if it doesn't have a method (namely the callee - // save frame) ArtMethod* m = GetMethod(); - if (skipping_ && !m->IsRuntimeMethod() && - !GetClassRoot<mirror::Throwable>()->IsAssignableFrom(m->GetDeclaringClass())) { - skipping_ = false; - } - if (!skipping_) { - if (!m->IsRuntimeMethod()) { // Ignore runtime frames (in particular callee save). + // Ignore runtime frames (in particular callee save). + if (!m->IsRuntimeMethod()) { + // We want to skip frames up to and including the exception's constructor. + // We also want to skip the `VMStack.getThreadStackTrace()` if present. + if (skipping_ && + !GetClassRoot<mirror::Throwable>()->IsAssignableFrom(m->GetDeclaringClass()) && + m != WellKnownClasses::dalvik_system_VMStack_getThreadStackTrace) { + skipping_ = false; + } + if (!skipping_) { if (depth_ < max_saved_frames_) { saved_frames_[depth_].first = m; saved_frames_[depth_].second = m->IsProxyMethod() ? dex::kDexNoIndex : GetDexPc(); } ++depth_; } - } else { - ++skip_depth_; } + skip_depth_ += skipping_ ? 1u : 0u; // Including runtime frames. return true; } diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc index 397f2bd13e..82076d9acf 100644 --- a/runtime/well_known_classes.cc +++ b/runtime/well_known_classes.cc @@ -62,6 +62,7 @@ ArtMethod* WellKnownClasses::dalvik_system_DexClassLoader_init; ArtMethod* WellKnownClasses::dalvik_system_InMemoryDexClassLoader_init; ArtMethod* WellKnownClasses::dalvik_system_PathClassLoader_init; ArtMethod* WellKnownClasses::dalvik_system_VMRuntime_hiddenApiUsed; +ArtMethod* WellKnownClasses::dalvik_system_VMStack_getThreadStackTrace; ArtMethod* WellKnownClasses::java_lang_Boolean_valueOf; ArtMethod* WellKnownClasses::java_lang_BootClassLoader_init; ArtMethod* WellKnownClasses::java_lang_Byte_valueOf; @@ -352,7 +353,7 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { java_lang_Short_valueOf = CachePrimitiveBoxingMethod(class_linker, self, 'S', "Ljava/lang/Short;"); - StackHandleScope<39u> hs(self); + StackHandleScope<40u> hs(self); Handle<mirror::Class> d_s_bdcl = hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/BaseDexClassLoader;")); Handle<mirror::Class> d_s_dlcl = @@ -371,6 +372,8 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/PathClassLoader;")); Handle<mirror::Class> d_s_vmr = hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/VMRuntime;")); + Handle<mirror::Class> d_s_vms = + hs.NewHandle(FindSystemClass(class_linker, self, "Ldalvik/system/VMStack;")); Handle<mirror::Class> j_i_fd = hs.NewHandle(FindSystemClass(class_linker, self, "Ljava/io/FileDescriptor;")); Handle<mirror::Class> j_l_bcl = @@ -473,6 +476,13 @@ void WellKnownClasses::InitFieldsAndMethodsOnly(JNIEnv* env) { "(ILjava/lang/String;Ljava/lang/String;IZ)V", pointer_size); + dalvik_system_VMStack_getThreadStackTrace = CacheMethod( + d_s_vms.Get(), + /*is_static=*/ true, + "getThreadStackTrace", + "(Ljava/lang/Thread;)[Ljava/lang/StackTraceElement;", + pointer_size); + java_lang_BootClassLoader_init = CacheMethod(j_l_bcl.Get(), /*is_static=*/ false, "<init>", "()V", pointer_size); java_lang_ClassLoader_loadClass = CacheMethod( @@ -830,6 +840,7 @@ void WellKnownClasses::Clear() { dalvik_system_DexPathList_dexElements = nullptr; dalvik_system_DexPathList__Element_dexFile = nullptr; dalvik_system_VMRuntime_nonSdkApiUsageConsumer = nullptr; + dalvik_system_VMStack_getThreadStackTrace = nullptr; java_lang_ClassLoader_parent = nullptr; java_lang_Thread_parkBlocker = nullptr; java_lang_Thread_daemon = nullptr; diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h index e8af1c1015..41d47c50b8 100644 --- a/runtime/well_known_classes.h +++ b/runtime/well_known_classes.h @@ -107,6 +107,7 @@ struct WellKnownClasses { static ArtMethod* dalvik_system_InMemoryDexClassLoader_init; // Only for the declaring class. static ArtMethod* dalvik_system_PathClassLoader_init; // Only for the declaring class. static ArtMethod* dalvik_system_VMRuntime_hiddenApiUsed; + static ArtMethod* dalvik_system_VMStack_getThreadStackTrace; static ArtMethod* java_lang_Boolean_valueOf; static ArtMethod* java_lang_BootClassLoader_init; // Only for the declaring class. static ArtMethod* java_lang_Byte_valueOf; diff --git a/test/051-thread/src/Main.java b/test/051-thread/src/Main.java index fe1cafef56..a9af027992 100644 --- a/test/051-thread/src/Main.java +++ b/test/051-thread/src/Main.java @@ -187,6 +187,10 @@ public class Main { Iterator<StackTraceElement> it = list.iterator(); while (it.hasNext()) { StackTraceElement ste = it.next(); + if (ste.getClassName().equals("dalvik.system.VMStack") && + ste.getMethodName().equals("getThreadStackTrace")) { + throw new Error(ste.toString() + " should have been skipped."); + } if (ste.getClassName().equals("Main")) { if (!ste.getMethodName().equals("testMainThreadAllStackTraces")) { throw new RuntimeException(list.toString()); |