backtrace: use Java stack to help decode native
Before change:
native: usb_host_run+16 [0x400a43f9] (/libusbhost.so)
native: android::Vector<int>::do_move_forward(void*, void const*, unsigned int) const+54 [0x501b1c5b] (/libandroid_servers.so)
native: ??? [0x624de480] (/system@framework@boot.oat)
at com.android.server.usb.UsbHostManager.monitorUsbHostBus(Native method)
at com.android.server.usb.UsbHostManager.access$000(UsbHostManager.java:38)
After change:
native: usb_host_run+16 [0x400933f9] (libusbhost.so)
native: android::Vector<int>::do_move_forward(void*, void const*, unsigned int) const+54 [0x4e984c5b] (libandroid_servers.so)
native: Java_com_android_server_usb_UsbHostManager_monitorUsbHostBus__+92 [0x624de480] (system@framework@boot.oat)
at com.android.server.usb.UsbHostManager.monitorUsbHostBus(Native method)
at com.android.server.usb.UsbHostManager.access$000(UsbHostManager.java:38)
Change-Id: Iea550a251a12e9ba7df9582fd454093bfa4e90e0
diff --git a/runtime/utils.cc b/runtime/utils.cc
index 237d217..d2d23e8 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -38,6 +38,7 @@
#include "mirror/string.h"
#include "object_utils.h"
#include "os.h"
+#include "scoped_thread_state_change.h"
#include "utf-inl.h"
#if !defined(HAVE_POSIX_CLOCKS)
@@ -1052,7 +1053,12 @@
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, bool include_count,
+ 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) {
+ Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
+ }
UniquePtr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid));
if (!backtrace->Unwind(0)) {
os << prefix << "(backtrace::Unwind failed for thread " << tid << ")\n";
@@ -1073,7 +1079,11 @@
if (!it->func_name.empty()) {
os << it->func_name;
} else {
- os << "???";
+ if (current_method != nullptr && current_method->IsWithinQuickCode(it->pc)) {
+ os << JniLongName(current_method) << "+" << (it->pc - current_method->GetQuickOatCodeOffset());
+ } else {
+ os << "???";
+ }
}
if (it->func_offset != 0) {
os << "+" << it->func_offset;