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;