Modify unwind to comply with stack parser tools.
Bug: 14081592
Change-Id: I6906b2575c74d64f1c3ba7602779b3a789de1c69
diff --git a/runtime/runtime_linux.cc b/runtime/runtime_linux.cc
index da1b2ca..960d332 100644
--- a/runtime/runtime_linux.cc
+++ b/runtime/runtime_linux.cc
@@ -33,7 +33,7 @@
struct Backtrace {
void Dump(std::ostream& os) {
- DumpNativeStack(os, GetTid(), "\t", true);
+ DumpNativeStack(os, GetTid(), "\t");
}
};
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 8691dec..3408dd3 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -939,7 +939,7 @@
if (dump_for_abort || ShouldShowNativeStack(this)) {
DumpKernelStack(os, GetTid(), " kernel: ", false);
SirtRef<mirror::ArtMethod> method_ref(Thread::Current(), GetCurrentMethod(nullptr));
- DumpNativeStack(os, GetTid(), " native: ", false, method_ref.get());
+ DumpNativeStack(os, GetTid(), " native: ", method_ref.get());
}
DumpJavaStack(os);
} else {
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 270deb0..6f93566 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -78,7 +78,7 @@
MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
for (const auto& thread : list_) {
os << "DUMPING THREAD " << thread->GetTid() << "\n";
- DumpNativeStack(os, thread->GetTid(), "\t", true);
+ DumpNativeStack(os, thread->GetTid(), "\t");
os << "\n";
}
}
@@ -99,7 +99,7 @@
// TODO: Reenable this when the native code in system_server can handle it.
// Currently "adb shell kill -3 `pid system_server`" will cause it to exit.
if (false) {
- DumpNativeStack(os, tid, " native: ", false);
+ DumpNativeStack(os, tid, " native: ");
}
os << "\n";
}
diff --git a/runtime/utils.cc b/runtime/utils.cc
index afbcbb7..c4d1a78 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -1041,20 +1041,7 @@
return "";
}
-static std::string CleanMapName(const backtrace_map_t* map) {
- if (map == NULL || map->name.empty()) {
- return "???";
- }
- // Turn "/usr/local/google/home/enh/clean-dalvik-dev/out/host/linux-x86/lib/libartd.so"
- // into "libartd.so".
- size_t last_slash = map->name.rfind('/');
- if (last_slash == std::string::npos) {
- return map->name;
- }
- return map->name.substr(last_slash + 1);
-}
-
-void DumpNativeStack(std::ostream& os, pid_t tid, const char* prefix, bool include_count,
+void DumpNativeStack(std::ostream& os, pid_t tid, const char* prefix,
mirror::ArtMethod* current_method) {
// We may be called from contexts where current_method is not null, so we must assert this.
if (current_method != nullptr) {
@@ -1072,27 +1059,34 @@
for (Backtrace::const_iterator it = backtrace->begin();
it != backtrace->end(); ++it) {
// We produce output like this:
- // ] #00 unwind_backtrace_thread+536 [0x55d75bb8] (libbacktrace.so)
- os << prefix;
- if (include_count) {
- os << StringPrintf("#%02zu ", it->num);
- }
- if (!it->func_name.empty()) {
- os << it->func_name;
+ // ] #00 pc 000075bb8 /system/lib/libc.so (unwind_backtrace_thread+536)
+ // In order for parsing tools to continue to function, the stack dump
+ // format must at least adhere to this format:
+ // #XX pc <RELATIVE_ADDR> <FULL_PATH_TO_SHARED_LIBRARY> ...
+ // The parsers require a single space before and after pc, and two spaces
+ // after the <RELATIVE_ADDR>. There can be any prefix data before the
+ // #XX. <RELATIVE_ADDR> has to be a hex number but with no 0x prefix.
+ os << prefix << StringPrintf("#%02zu pc ", it->num);
+ if (!it->map) {
+ os << StringPrintf("%08" PRIxPTR " ???", it->pc);
} else {
- if (current_method != nullptr && current_method->IsWithinQuickCode(it->pc)) {
+ os << StringPrintf("%08" PRIxPTR " ", it->pc - it->map->start)
+ << it->map->name << " (";
+ if (!it->func_name.empty()) {
+ os << it->func_name;
+ if (it->func_offset != 0) {
+ os << "+" << it->func_offset;
+ }
+ } else if (current_method != nullptr && current_method->IsWithinQuickCode(it->pc)) {
const void* start_of_code = current_method->GetEntryPointFromQuickCompiledCode();
os << JniLongName(current_method) << "+"
<< (it->pc - reinterpret_cast<uintptr_t>(start_of_code));
} else {
os << "???";
}
+ os << ")";
}
- if (it->func_offset != 0) {
- os << "+" << it->func_offset;
- }
- os << StringPrintf(" [%p]", reinterpret_cast<void*>(it->pc));
- os << " (" << CleanMapName(it->map) << ")\n";
+ os << "\n";
}
}
diff --git a/runtime/utils.h b/runtime/utils.h
index 5def66b..6ab1013 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -382,7 +382,7 @@
// Dumps the native stack for thread 'tid' to 'os'.
void DumpNativeStack(std::ostream& os, pid_t tid, const char* prefix = "",
- bool include_count = true, mirror::ArtMethod* current_method = nullptr)
+ mirror::ArtMethod* current_method = nullptr)
NO_THREAD_SAFETY_ANALYSIS;
// Dumps the kernel stack for thread 'tid' to 'os'. Note that this is only available on linux-x86.