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
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 000078f..b46192e 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2874,25 +2874,25 @@
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 397f2bd..82076d9 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -62,6 +62,7 @@
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 @@
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 @@
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 @@
"(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 @@
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 e8af1c1..41d47c5 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -107,6 +107,7 @@
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 fe1cafe..a9af027 100644
--- a/test/051-thread/src/Main.java
+++ b/test/051-thread/src/Main.java
@@ -187,6 +187,10 @@
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());