Use libunwindstack instead of libbacktrace.

Replace all instances of libbacktrace code with equivalent
libunwindstack code.

Test: Run 037-cfi test in optimized, interpreter, jit modes.
Test: Ran 004-ThreadStress in a loop for optimized, interpreter, jit modes.
Test: Forced an ANR and verified native stacks are correct, and that
Test: native stacks correctly stop before java stacks.
Change-Id: I642ffd61b731dae6a68a5ba9453485a79f608d28
diff --git a/Android.mk b/Android.mk
index 15c7989..6ae2e2d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -521,7 +521,6 @@
   lib/libart-disassembler.so \
   lib/libartpalette.so \
   lib/libart.so \
-  lib/libbacktrace.so \
   lib/libdexfile.so \
   lib/libdt_fd_forward.so \
   lib/libdt_socket.so \
@@ -551,7 +550,6 @@
   lib64/libart-disassembler.so \
   lib64/libartpalette.so \
   lib64/libart.so \
-  lib64/libbacktrace.so \
   lib64/libdexfile.so \
   lib64/libdt_fd_forward.so \
   lib64/libdt_socket.so \
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index d9a75e4..5fcc745 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -27,7 +27,7 @@
 
 # Manually add system libraries that we need to run the host ART tools.
 my_files += \
-  $(foreach lib, libbacktrace libbase libc++ libicu libicu_jni liblog libsigchain libunwindstack \
+  $(foreach lib, libbase libc++ libicu libicu_jni liblog libsigchain libunwindstack \
     libziparchive libjavacore libandroidio libopenjdkd liblz4 liblzma, \
     $(call intermediates-dir-for,SHARED_LIBRARIES,$(lib),HOST)/$(lib).so:lib64/$(lib).so \
     $(call intermediates-dir-for,SHARED_LIBRARIES,$(lib),HOST,,2ND)/$(lib).so:lib/$(lib).so) \
diff --git a/build/apex/art_apex_test.py b/build/apex/art_apex_test.py
index 556bb78..391b990 100755
--- a/build/apex/art_apex_test.py
+++ b/build/apex/art_apex_test.py
@@ -510,7 +510,6 @@
     # catch invalid dependencies on /system or other APEXes that should go
     # through an exported library with stubs (b/128708192 tracks implementing a
     # better approach for that).
-    self._checker.check_native_library('libbacktrace')
     self._checker.check_native_library('libbase')
     self._checker.check_native_library('libc++')
     self._checker.check_native_library('libdt_socket')
diff --git a/compiler/Android.bp b/compiler/Android.bp
index de98fdb..8916fa1 100644
--- a/compiler/Android.bp
+++ b/compiler/Android.bp
@@ -465,8 +465,8 @@
     ],
 
     shared_libs: [
-        "libbacktrace",
         "libnativeloader",
+        "libunwindstack",
     ],
 
     target: {
diff --git a/dexoptanalyzer/Android.bp b/dexoptanalyzer/Android.bp
index 1e37b8d..43953da 100644
--- a/dexoptanalyzer/Android.bp
+++ b/dexoptanalyzer/Android.bp
@@ -84,7 +84,7 @@
 art_cc_defaults {
     name: "art_dexoptanalyzer_tests_defaults",
     shared_libs: [
-        "libbacktrace",
+        "libunwindstack",
     ],
     data: [
         ":art-gtest-jars-LinkageTest",
diff --git a/libartbase/Android.bp b/libartbase/Android.bp
index 80c63c6..7ab7f5a 100644
--- a/libartbase/Android.bp
+++ b/libartbase/Android.bp
@@ -231,7 +231,7 @@
     ],
     shared_libs: [
         "libbase",
-        "libbacktrace",
+        "libunwindstack",
     ],
     header_libs: [
         "libnativehelper_header_only",
diff --git a/libdexfile/Android.bp b/libdexfile/Android.bp
index f7afe85..c6f18b6 100644
--- a/libdexfile/Android.bp
+++ b/libdexfile/Android.bp
@@ -293,7 +293,7 @@
     ],
     header_libs: ["jni_headers"],
     shared_libs: [
-        "libbacktrace",
+        "libunwindstack",
         "libziparchive",
     ],
 }
diff --git a/runtime/Android.bp b/runtime/Android.bp
index d11f8fa..7390953 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -465,7 +465,6 @@
     ],
     shared_libs: [
         "libartpalette",
-        "libbacktrace",
         "libbase", // For common macros.
         "liblog",
         "liblz4",
@@ -495,7 +494,6 @@
     name: "libart_static_base_defaults",
     whole_static_libs: [
         "libartpalette",
-        "libbacktrace",
         "libbase",
         "liblog",
         "liblz4",
@@ -847,7 +845,7 @@
         "verifier/reg_type_test.cc",
     ],
     shared_libs: [
-        "libbacktrace",
+        "libunwindstack",
     ],
     header_libs: [
         "art_cmdlineparser_headers", // For parsed_options_test.
diff --git a/runtime/backtrace_helper.h b/runtime/backtrace_helper.h
index a74d0e0..9be2550 100644
--- a/runtime/backtrace_helper.h
+++ b/runtime/backtrace_helper.h
@@ -26,7 +26,7 @@
 
 namespace art {
 
-// Using libbacktrace
+// Using libunwindstack
 class BacktraceCollector {
  public:
   BacktraceCollector(uintptr_t* out_frames, size_t max_depth, size_t skip_count)
diff --git a/runtime/native_stack_dump.cc b/runtime/native_stack_dump.cc
index 31deda1..30b5ee6 100644
--- a/runtime/native_stack_dump.cc
+++ b/runtime/native_stack_dump.cc
@@ -24,8 +24,7 @@
 #include "art_method.h"
 
 // For DumpNativeStack.
-#include <backtrace/Backtrace.h>
-#include <backtrace/BacktraceMap.h>
+#include <unwindstack/AndroidUnwinder.h>
 
 #if defined(__linux__)
 
@@ -324,27 +323,33 @@
 
 void DumpNativeStack(std::ostream& os,
                      pid_t tid,
-                     BacktraceMap* existing_map,
+                     const char* prefix,
+                     ArtMethod* current_method,
+                     void* ucontext_ptr,
+                     bool skip_frames) {
+  unwindstack::AndroidLocalUnwinder unwinder;
+  DumpNativeStack(os, unwinder, tid, prefix, current_method, ucontext_ptr, skip_frames);
+}
+
+void DumpNativeStack(std::ostream& os,
+                     unwindstack::AndroidLocalUnwinder& unwinder,
+                     pid_t tid,
                      const char* prefix,
                      ArtMethod* current_method,
                      void* ucontext_ptr,
                      bool skip_frames) {
   // Historical note: This was disabled when running under Valgrind (b/18119146).
 
-  BacktraceMap* map = existing_map;
-  std::unique_ptr<BacktraceMap> tmp_map;
-  if (map == nullptr) {
-    tmp_map.reset(BacktraceMap::Create(getpid()));
-    map = tmp_map.get();
+  unwindstack::AndroidUnwinderData data(!skip_frames /*show_all_frames*/);
+  bool unwind_ret;
+  if (ucontext_ptr != nullptr) {
+    unwind_ret = unwinder.Unwind(ucontext_ptr, data);
+  } else {
+    unwind_ret = unwinder.Unwind(tid, data);
   }
-  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid, map));
-  backtrace->SetSkipFrames(skip_frames);
-  if (!backtrace->Unwind(0, reinterpret_cast<ucontext*>(ucontext_ptr))) {
-    os << prefix << "(backtrace::Unwind failed for thread " << tid
-       << ": " <<  backtrace->GetErrorString(backtrace->GetError()) << ")" << std::endl;
-    return;
-  } else if (backtrace->NumFrames() == 0) {
-    os << prefix << "(no native stack frames for thread " << tid << ")" << std::endl;
+  if (!unwind_ret) {
+    os << prefix << "(Unwind failed for thread " << tid << ": "
+       <<  data.GetErrorString() << ")" << std::endl;
     return;
   }
 
@@ -359,9 +364,8 @@
   }
 
   std::unique_ptr<Addr2linePipe> addr2line_state;
-
-  for (Backtrace::const_iterator it = backtrace->begin();
-       it != backtrace->end(); ++it) {
+  data.DemangleFunctionNames();
+  for (const unwindstack::FrameData& frame : data.frames) {
     // We produce output like this:
     // ]    #00 pc 000075bb8  /system/lib/libc.so (unwind_backtrace_thread+536)
     // In order for parsing tools to continue to function, the stack dump
@@ -370,53 +374,55 @@
     // 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);
+    os << prefix << StringPrintf("#%02zu pc ", frame.num);
     bool try_addr2line = false;
-    if (!BacktraceMap::IsValid(it->map)) {
+    if (frame.map_info == nullptr) {
       os << StringPrintf(Is64BitInstructionSet(kRuntimeISA) ? "%016" PRIx64 "  ???"
                                                             : "%08" PRIx64 "  ???",
-                         it->pc);
+                         frame.pc);
     } else {
       os << StringPrintf(Is64BitInstructionSet(kRuntimeISA) ? "%016" PRIx64 "  "
                                                             : "%08" PRIx64 "  ",
-                         it->rel_pc);
-      if (it->map.name.empty()) {
-        os << StringPrintf("<anonymous:%" PRIx64 ">", it->map.start);
+                         frame.rel_pc);
+      const std::shared_ptr<unwindstack::MapInfo>& map_info = frame.map_info;
+      if (map_info->name().empty()) {
+        os << StringPrintf("<anonymous:%" PRIx64 ">", map_info->start());
       } else {
-        os << it->map.name;
+        os << map_info->name().c_str();
       }
-      if (it->map.offset != 0) {
-        os << StringPrintf(" (offset %" PRIx64 ")", it->map.offset);
+      if (map_info->elf_start_offset() != 0) {
+        os << StringPrintf(" (offset %" PRIx64 ")", map_info->elf_start_offset());
       }
       os << " (";
-      if (!it->func_name.empty()) {
-        os << it->func_name;
-        if (it->func_offset != 0) {
-          os << "+" << it->func_offset;
+      if (!frame.function_name.empty()) {
+        os << frame.function_name.c_str();
+        if (frame.function_offset != 0) {
+          os << "+" << frame.function_offset;
         }
         // Functions found using the gdb jit interface will be in an empty
         // map that cannot be found using addr2line.
-        if (!it->map.name.empty()) {
+        if (!map_info->name().empty()) {
           try_addr2line = true;
         }
       } else if (current_method != nullptr &&
           Locks::mutator_lock_->IsSharedHeld(Thread::Current()) &&
-          PcIsWithinQuickCode(current_method, it->pc)) {
+          PcIsWithinQuickCode(current_method, frame.pc)) {
         const void* start_of_code = current_method->GetEntryPointFromQuickCompiledCode();
         os << current_method->JniLongName() << "+"
-           << (it->pc - reinterpret_cast<uint64_t>(start_of_code));
+           << (frame.pc - reinterpret_cast<uint64_t>(start_of_code));
       } else {
         os << "???";
       }
       os << ")";
-      std::string build_id = map->GetBuildId(it->pc);
+      std::string build_id = map_info->GetPrintableBuildID();
       if (!build_id.empty()) {
         os << " (BuildId: " << build_id << ")";
       }
     }
     os << std::endl;
     if (try_addr2line && use_addr2line) {
-      Addr2line(it->map.name, it->rel_pc, os, prefix, &addr2line_state);
+      // Guaranteed that map_info is not nullptr and name is non-empty.
+      Addr2line(frame.map_info->name(), frame.rel_pc, os, prefix, &addr2line_state);
     }
   }
 
@@ -429,7 +435,15 @@
 
 void DumpNativeStack(std::ostream& os ATTRIBUTE_UNUSED,
                      pid_t tid ATTRIBUTE_UNUSED,
-                     BacktraceMap* existing_map ATTRIBUTE_UNUSED,
+                     const char* prefix ATTRIBUTE_UNUSED,
+                     ArtMethod* current_method ATTRIBUTE_UNUSED,
+                     void* ucontext_ptr ATTRIBUTE_UNUSED,
+                     bool skip_frames ATTRIBUTE_UNUSED) {
+}
+
+void DumpNativeStack(std::ostream& os ATTRIBUTE_UNUSED,
+                     unwindstack::AndroidLocalUnwinder& existing_map ATTRIBUTE_UNUSED,
+                     pid_t tid ATTRIBUTE_UNUSED,
                      const char* prefix ATTRIBUTE_UNUSED,
                      ArtMethod* current_method ATTRIBUTE_UNUSED,
                      void* ucontext_ptr ATTRIBUTE_UNUSED,
diff --git a/runtime/native_stack_dump.h b/runtime/native_stack_dump.h
index 4d4b36b..99fb59c 100644
--- a/runtime/native_stack_dump.h
+++ b/runtime/native_stack_dump.h
@@ -23,7 +23,9 @@
 
 #include "base/macros.h"
 
-class BacktraceMap;
+namespace unwindstack {
+class AndroidLocalUnwinder;
+}  // namespace unwindstack
 
 namespace art {
 
@@ -32,7 +34,15 @@
 // Dumps the native stack for thread 'tid' to 'os'.
 void DumpNativeStack(std::ostream& os,
                      pid_t tid,
-                     BacktraceMap* map = nullptr,
+                     const char* prefix = "",
+                     ArtMethod* current_method = nullptr,
+                     void* ucontext = nullptr,
+                     bool skip_frames = true)
+    NO_THREAD_SAFETY_ANALYSIS;
+
+void DumpNativeStack(std::ostream& os,
+                     unwindstack::AndroidLocalUnwinder& unwinder,
+                     pid_t tid,
                      const char* prefix = "",
                      ArtMethod* current_method = nullptr,
                      void* ucontext = nullptr,
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index e56d533..ebad371 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -543,7 +543,7 @@
     os << "Runtime aborting...\n";
     if (Runtime::Current() == nullptr) {
       os << "(Runtime does not yet exist!)\n";
-      DumpNativeStack(os, GetTid(), nullptr, "  native: ", nullptr);
+      DumpNativeStack(os, GetTid(), "  native: ", nullptr);
       return;
     }
     Thread* self = Thread::Current();
@@ -555,7 +555,7 @@
 
     if (self == nullptr) {
       os << "(Aborting thread was not attached to runtime!)\n";
-      DumpNativeStack(os, GetTid(), nullptr, "  native: ", nullptr);
+      DumpNativeStack(os, GetTid(), "  native: ", nullptr);
     } else {
       os << "Aborting thread:\n";
       if (Locks::mutator_lock_->IsExclusiveHeld(self) || Locks::mutator_lock_->IsSharedHeld(self)) {
diff --git a/runtime/runtime_common.h b/runtime/runtime_common.h
index 925594e..ec08907 100644
--- a/runtime/runtime_common.h
+++ b/runtime/runtime_common.h
@@ -42,7 +42,7 @@
   void Dump(std::ostream& os) const {
     // This is a backtrace from a crash, do not skip any frames in case the
     // crash is in the unwinder itself.
-    DumpNativeStack(os, GetTid(), nullptr, "\t", nullptr, raw_context_, false);
+    DumpNativeStack(os, GetTid(), "\t", nullptr, raw_context_, false);
   }
  private:
   // Stores the context of the signal that was unexpected and will terminate the runtime. The
diff --git a/runtime/thread.cc b/runtime/thread.cc
index e7c6bec..bc39d7f 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -41,6 +41,8 @@
 #include "android-base/stringprintf.h"
 #include "android-base/strings.h"
 
+#include "unwindstack/AndroidUnwinder.h"
+
 #include "arch/context-inl.h"
 #include "arch/context.h"
 #include "art_field-inl.h"
@@ -1391,10 +1393,15 @@
   tls32_.num_name_readers.fetch_sub(1 /* at least memory_order_release */);
 }
 
-void Thread::Dump(std::ostream& os, bool dump_native_stack, BacktraceMap* backtrace_map,
-                  bool force_dump_stack) const {
+void Thread::Dump(std::ostream& os, bool dump_native_stack, bool force_dump_stack) const {
   DumpState(os);
-  DumpStack(os, dump_native_stack, backtrace_map, force_dump_stack);
+  DumpStack(os, dump_native_stack, force_dump_stack);
+}
+
+void Thread::Dump(std::ostream& os, unwindstack::AndroidLocalUnwinder& unwinder,
+                  bool dump_native_stack, bool force_dump_stack) const {
+  DumpState(os);
+  DumpStack(os, unwinder, dump_native_stack, force_dump_stack);
 }
 
 ObjPtr<mirror::String> Thread::GetThreadName() const {
@@ -2280,7 +2287,14 @@
 
 void Thread::DumpStack(std::ostream& os,
                        bool dump_native_stack,
-                       BacktraceMap* backtrace_map,
+                       bool force_dump_stack) const {
+  unwindstack::AndroidLocalUnwinder unwinder;
+  DumpStack(os, unwinder, dump_native_stack, force_dump_stack);
+}
+
+void Thread::DumpStack(std::ostream& os,
+                       unwindstack::AndroidLocalUnwinder& unwinder,
+                       bool dump_native_stack,
                        bool force_dump_stack) const {
   // TODO: we call this code when dying but may not have suspended the thread ourself. The
   //       IsSuspended check is therefore racy with the use for dumping (normally we inhibit
@@ -2299,7 +2313,7 @@
           GetCurrentMethod(nullptr,
                            /*check_suspended=*/ !force_dump_stack,
                            /*abort_on_error=*/ !(dump_for_abort || force_dump_stack));
-      DumpNativeStack(os, GetTid(), backtrace_map, "  native: ", method);
+      DumpNativeStack(os, unwinder, GetTid(), "  native: ", method);
     }
     DumpJavaStack(os,
                   /*check_suspended=*/ !force_dump_stack,
diff --git a/runtime/thread.h b/runtime/thread.h
index 7ac4007..51d1fdc 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -48,7 +48,9 @@
 #include "runtime_stats.h"
 #include "thread_state.h"
 
-class BacktraceMap;
+namespace unwindstack {
+class AndroidLocalUnwinder;
+}  // namespace unwindstack
 
 namespace art {
 
@@ -270,7 +272,11 @@
   // Dumps the detailed thread state and the thread stack (used for SIGQUIT).
   void Dump(std::ostream& os,
             bool dump_native_stack = true,
-            BacktraceMap* backtrace_map = nullptr,
+            bool force_dump_stack = false) const
+      REQUIRES_SHARED(Locks::mutator_lock_);
+  void Dump(std::ostream& os,
+            unwindstack::AndroidLocalUnwinder& unwinder,
+            bool dump_native_stack = true,
             bool force_dump_stack = false) const
       REQUIRES_SHARED(Locks::mutator_lock_);
 
@@ -1492,7 +1498,11 @@
   void DumpState(std::ostream& os) const REQUIRES_SHARED(Locks::mutator_lock_);
   void DumpStack(std::ostream& os,
                  bool dump_native_stack = true,
-                 BacktraceMap* backtrace_map = nullptr,
+                 bool force_dump_stack = false) const
+      REQUIRES_SHARED(Locks::mutator_lock_);
+  void DumpStack(std::ostream& os,
+                 unwindstack::AndroidLocalUnwinder& unwinder,
+                 bool dump_native_stack = true,
                  bool force_dump_stack = false) const
       REQUIRES_SHARED(Locks::mutator_lock_);
 
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index bfde711..ca179ef 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -24,9 +24,9 @@
 #include <vector>
 
 #include "android-base/stringprintf.h"
-#include "backtrace/BacktraceMap.h"
 #include "nativehelper/scoped_local_ref.h"
 #include "nativehelper/scoped_utf_chars.h"
+#include "unwindstack/AndroidUnwinder.h"
 
 #include "base/aborting.h"
 #include "base/histogram-inl.h"
@@ -124,10 +124,10 @@
 
 void ThreadList::DumpNativeStacks(std::ostream& os) {
   MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
-  std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid()));
+  unwindstack::AndroidLocalUnwinder unwinder;
   for (const auto& thread : list_) {
     os << "DUMPING THREAD " << thread->GetTid() << "\n";
-    DumpNativeStack(os, thread->GetTid(), map.get(), "\t");
+    DumpNativeStack(os, unwinder, thread->GetTid(), "\t");
     os << "\n";
   }
 }
@@ -153,7 +153,7 @@
   // refactor DumpState to avoid skipping analysis.
   Thread::DumpState(os, nullptr, tid);
   if (dump_native_stack) {
-    DumpNativeStack(os, tid, nullptr, "  native: ");
+    DumpNativeStack(os, tid, "  native: ");
   }
   os << std::endl;
 }
@@ -195,11 +195,8 @@
         // Avoid verifying count in case a thread doesn't end up passing through the barrier.
         // This avoids a SIGABRT that would otherwise happen in the destructor.
         barrier_(0, /*verify_count_on_shutdown=*/false),
-        backtrace_map_(dump_native_stack ? BacktraceMap::Create(getpid()) : nullptr),
+        unwinder_(std::vector<std::string>{}, std::vector<std::string> {"oat", "odex"}),
         dump_native_stack_(dump_native_stack) {
-    if (backtrace_map_ != nullptr) {
-      backtrace_map_->SetSuffixesToIgnore(std::vector<std::string> { "oat", "odex" });
-    }
   }
 
   void Run(Thread* thread) override {
@@ -210,7 +207,7 @@
     std::ostringstream local_os;
     {
       ScopedObjectAccess soa(self);
-      thread->Dump(local_os, dump_native_stack_, backtrace_map_.get());
+      thread->Dump(local_os, unwinder_, dump_native_stack_);
     }
     {
       // Use the logging lock to ensure serialization when writing to the common ostream.
@@ -237,7 +234,7 @@
   // The barrier to be passed through and for the requestor to wait upon.
   Barrier barrier_;
   // A backtrace map, so that all threads use a shared info and don't reacquire/parse separately.
-  std::unique_ptr<BacktraceMap> backtrace_map_;
+  unwindstack::AndroidLocalUnwinder unwinder_;
   // Whether we should dump the native stack.
   const bool dump_native_stack_;
 };
@@ -486,7 +483,6 @@
               // Assume it's stuck and safe to dump its stack.
               thread->Dump(LOG_STREAM(FATAL_WITHOUT_ABORT),
                            /*dump_native_stack=*/ true,
-                           /*backtrace_map=*/ nullptr,
                            /*force_dump_stack=*/ true);
             }
           }
@@ -1324,7 +1320,7 @@
         std::string thread_name;
         self->GetThreadName(thread_name);
         std::ostringstream os;
-        DumpNativeStack(os, GetTid(), nullptr, "  native: ", nullptr);
+        DumpNativeStack(os, GetTid(), "  native: ", nullptr);
         LOG(ERROR) << "Request to unregister unattached thread " << thread_name << "\n" << os.str();
         break;
       } else {
diff --git a/test/137-cfi/cfi.cc b/test/137-cfi/cfi.cc
index 4e756d2..bf5cc76 100644
--- a/test/137-cfi/cfi.cc
+++ b/test/137-cfi/cfi.cc
@@ -28,7 +28,7 @@
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
-#include <backtrace/Backtrace.h>
+#include <unwindstack/AndroidUnwinder.h>
 
 #include "base/file_utils.h"
 #include "base/logging.h"
@@ -106,23 +106,25 @@
 
 // Helper to look for a sequence in the stack trace.
 #if __linux__
-static bool CheckStack(Backtrace* bt, const std::vector<std::string>& seq) {
+static bool CheckStack(unwindstack::AndroidUnwinder& unwinder,
+                       unwindstack::AndroidUnwinderData& data,
+                       const std::vector<std::string>& seq) {
   size_t cur_search_index = 0;  // The currently active index in seq.
   CHECK_GT(seq.size(), 0U);
 
   bool any_empty_name = false;
-  for (size_t i = 0; i < bt->NumFrames(); i++) {
-    const backtrace_frame_data_t* frame = bt->GetFrame(i);
-    if (BacktraceMap::IsValid(frame->map)) {
+  for (const unwindstack::FrameData& frame : data.frames) {
+    const std::string& function_name = frame.function_name;
+    if (frame.map_info != nullptr) {
       if (cur_search_index < seq.size()) {
-        LOG(INFO) << "Got " << frame->func_name << ", looking for " << seq[cur_search_index];
-        if (frame->func_name.find(seq[cur_search_index]) != std::string::npos) {
+        LOG(INFO) << "Got " << function_name << ", looking for " << seq[cur_search_index];
+        if (function_name.find(seq[cur_search_index]) != std::string::npos) {
           cur_search_index++;
         }
       }
     }
-    any_empty_name |= frame->func_name.empty();
-    if (frame->func_name == "main") {
+    any_empty_name |= function_name.empty();
+    if (function_name == "main") {
       break;
     }
   }
@@ -140,10 +142,8 @@
     return true;
   }
 
-  for (Backtrace::const_iterator it = bt->begin(); it != bt->end(); ++it) {
-    if (BacktraceMap::IsValid(it->map)) {
-      printf("  %s\n", Backtrace::FormatFrameData(&*it).c_str());
-    }
+  for (const unwindstack::FrameData& frame : data.frames) {
+    printf("  %s\n", unwinder.FormatFrame(frame).c_str());
   }
 
   return false;
@@ -166,13 +166,11 @@
 #if __linux__
   MutexLock mu(Thread::Current(), *GetNativeDebugInfoLock());  // Avoid races with the JIT thread.
 
-  std::unique_ptr<Backtrace> bt(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, GetTid()));
-  if (!bt->Unwind(0, nullptr)) {
+  unwindstack::AndroidLocalUnwinder unwinder;
+  unwindstack::AndroidUnwinderData data;
+  if (!unwinder.Unwind(data)) {
     printf("Cannot unwind in process.\n");
     return JNI_FALSE;
-  } else if (bt->NumFrames() == 0) {
-    printf("No frames for unwind in process.\n");
-    return JNI_FALSE;
   }
 
   // We cannot really parse an exact stack, as the optimizing compiler may inline some functions.
@@ -186,7 +184,7 @@
       "Main.main"                        // The Java entry method.
   };
 
-  bool result = CheckStack(bt.get(), seq);
+  bool result = CheckStack(unwinder, data, seq);
   if (!kCauseSegfault) {
     return result ? JNI_TRUE : JNI_FALSE;
   } else {
@@ -260,17 +258,13 @@
     return JNI_FALSE;
   }
 
-  std::unique_ptr<Backtrace> bt(Backtrace::Create(pid, BACKTRACE_CURRENT_THREAD));
   bool result = true;
-  if (!bt->Unwind(0, nullptr)) {
+  unwindstack::AndroidRemoteUnwinder unwinder(pid);
+  unwindstack::AndroidUnwinderData data;
+  if (!unwinder.Unwind(data)) {
     printf("Cannot unwind other process.\n");
     result = false;
-  } else if (bt->NumFrames() == 0) {
-    printf("No frames for unwind of other process.\n");
-    result = false;
-  }
-
-  if (result) {
+  } else {
     // See comment in unwindInProcess for non-exact stack matching.
     // "mini-debug-info" does not include parameters to save space.
     std::vector<std::string> seq = {
@@ -280,7 +274,7 @@
         "Main.main"                         // The Java entry method.
     };
 
-    result = CheckStack(bt.get(), seq);
+    result = CheckStack(unwinder, data, seq);
   }
 
   constexpr bool kSigQuitOnFail = true;
diff --git a/test/Android.bp b/test/Android.bp
index 8bca2c5..9907347 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -414,7 +414,6 @@
     ],
     shared_libs: [
         "libbase",
-        "libbacktrace",
         "liblog",
     ],
     target: {
@@ -596,7 +595,6 @@
     name: "libartagent-defaults",
     defaults: ["art_test_internal_library_defaults"],
     shared_libs: [
-        "libbacktrace",
         "libbase",
         "liblog",
         "libnativehelper",
@@ -964,10 +962,10 @@
         "common/stack_inspect.cc",
     ],
     shared_libs: [
-        "libbacktrace",
         "libbase",
         "liblog",
         "libnativehelper",
+        "libunwindstack",
     ],
 }
 
diff --git a/test/knownfailures.json b/test/knownfailures.json
index 83918a4..78f9fc5 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -1273,7 +1273,7 @@
         "tests": ["141-class-unload", "071-dexfile"],
         "variant": "gcstress",
         "bug": "b/111543628",
-        "description" : ["Test seems to timeout when run with gcstress due to slower unwinding by libbacktrace"]
+        "description" : ["Test seems to timeout when run with gcstress due to slower unwinding by libunwindstack"]
     },
     {
         "tests": ["708-jit-cache-churn"],
@@ -1285,7 +1285,7 @@
         "tests": ["712-varhandle-invocations"],
         "variant": "gcstress",
         "bug": "b/111630237",
-        "description": ["Test timing out under gcstress possibly due to slower unwinding by libbacktrace"]
+        "description": ["Test timing out under gcstress possibly due to slower unwinding by libunwindstack"]
     },
     {
         "tests": ["1336-short-finalizer-timeout"],
diff --git a/tools/buildbot-build.sh b/tools/buildbot-build.sh
index 7e736bf..421a71b 100755
--- a/tools/buildbot-build.sh
+++ b/tools/buildbot-build.sh
@@ -123,7 +123,7 @@
   # Indirect dependencies in the platform, e.g. through heapprofd_client_api.
   # These are built to go into system/lib(64) to be part of the system linker
   # namespace.
-  make_command+=" libbacktrace libnetd_client-target libprocinfo libtombstoned_client libunwindstack"
+  make_command+=" libnetd_client-target libprocinfo libtombstoned_client libunwindstack"
   # Stubs for other APEX SDKs, for use by vogar. Referenced from DEVICE_JARS in
   # external/vogar/src/vogar/ModeId.java.
   # Note these go into out/target/common/obj/JAVA_LIBRARIES which isn't removed
diff --git a/tools/public.libraries.buildbot.txt b/tools/public.libraries.buildbot.txt
index e23cf2c..9b0dc68 100644
--- a/tools/public.libraries.buildbot.txt
+++ b/tools/public.libraries.buildbot.txt
@@ -1,6 +1,6 @@
-libbacktrace.so
 libc.so
 libc++.so
 libdl.so
 libm.so
 libnativehelper.so
+libunwindstack.so
diff --git a/tools/signal_dumper/Android.bp b/tools/signal_dumper/Android.bp
index 33450d1..00948b8 100644
--- a/tools/signal_dumper/Android.bp
+++ b/tools/signal_dumper/Android.bp
@@ -48,18 +48,6 @@
     },
 }
 
-cc_defaults {
-    name: "signal_dumper_libbacktrace_static_deps",
-    defaults: [
-        "signal_dumper_libbase_static_deps",
-        "signal_dumper_libunwindstack_static_deps",
-    ],
-    static_libs: [
-        "libbase",
-        "libunwindstack",
-    ],
-}
-
 art_cc_binary {
     name: "signal_dumper",
 
@@ -73,14 +61,14 @@
 
     defaults: [
         "art_defaults",
-        "signal_dumper_libbacktrace_static_deps",
         "signal_dumper_libbase_static_deps",
+        "signal_dumper_libunwindstack_static_deps",
     ],
 
     srcs: ["signal_dumper.cc"],
 
     static_libs: [
-        "libbacktrace",
         "libbase",
+        "libunwindstack",
     ],
 }
diff --git a/tools/signal_dumper/signal_dumper.cc b/tools/signal_dumper/signal_dumper.cc
index e9a589e..e88ac19 100644
--- a/tools/signal_dumper/signal_dumper.cc
+++ b/tools/signal_dumper/signal_dumper.cc
@@ -15,6 +15,7 @@
  */
 
 #include <dirent.h>
+#include <inttypes.h>
 #include <poll.h>
 #include <sys/prctl.h>
 #include <sys/ptrace.h>
@@ -38,8 +39,7 @@
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
-#include <backtrace/Backtrace.h>
-#include <backtrace/BacktraceMap.h>
+#include <unwindstack/AndroidUnwinder.h>
 
 namespace art {
 namespace {
@@ -492,11 +492,10 @@
 constexpr bool kIs64Bit = false;
 #endif
 
-void DumpThread(pid_t pid,
+void DumpThread(unwindstack::AndroidRemoteUnwinder& unwinder, pid_t pid,
                 pid_t tid,
                 const std::string* addr2line_path,
-                const char* prefix,
-                BacktraceMap* map) {
+                const char* prefix) {
   LOG(ERROR) << std::endl << "=== pid: " << pid << " tid: " << tid << " ===" << std::endl;
 
   constexpr uint32_t kMaxWaitMicros = 1000 * 1000;  // 1s.
@@ -504,50 +503,41 @@
     LOG(ERROR) << "Failed to wait for sigstop on " << tid;
   }
 
-  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map));
-  if (backtrace == nullptr) {
-    LOG(ERROR) << prefix << "(failed to create Backtrace for thread " << tid << ")";
-    return;
-  }
-  backtrace->SetSkipFrames(false);
-  if (!backtrace->Unwind(0, nullptr)) {
-    LOG(ERROR) << prefix << "(backtrace::Unwind failed for thread " << tid
-               << ": " <<  backtrace->GetErrorString(backtrace->GetError()) << ")";
-    return;
-  }
-  if (backtrace->NumFrames() == 0) {
-    LOG(ERROR) << prefix << "(no native stack frames for thread " << tid << ")";
+  unwindstack::AndroidUnwinderData data;
+  if (!unwinder.Unwind(tid, data)) {
+    LOG(ERROR) << prefix << "(Unwind failed for thread " << tid << ": "
+               <<  data.GetErrorString() << ")";
     return;
   }
 
   std::unique_ptr<addr2line::Addr2linePipe> addr2line_state;
-
-  for (Backtrace::const_iterator it = backtrace->begin();
-      it != backtrace->end(); ++it) {
+  data.DemangleFunctionNames();
+  for (const unwindstack::FrameData& frame : data.frames) {
     std::ostringstream oss;
-    oss << prefix << StringPrintf("#%02zu pc ", it->num);
+    oss << prefix << StringPrintf("#%02zu pc ", frame.num);
     bool try_addr2line = false;
-    if (!BacktraceMap::IsValid(it->map)) {
-      oss << StringPrintf(kIs64Bit ? "%016" PRIx64 "  ???" : "%08" PRIx64 "  ???", it->pc);
+    if (frame.map_info == nullptr) {
+      oss << StringPrintf(kIs64Bit ? "%016" PRIx64 "  ???" : "%08" PRIx64 "  ???", frame.pc);
     } else {
-      oss << StringPrintf(kIs64Bit ? "%016" PRIx64 "  " : "%08" PRIx64 "  ", it->rel_pc);
-      if (it->map.name.empty()) {
-        oss << StringPrintf("<anonymous:%" PRIx64 ">", it->map.start);
+      oss << StringPrintf(kIs64Bit ? "%016" PRIx64 "  " : "%08" PRIx64 "  ", frame.rel_pc);
+      if (frame.map_info->name().empty()) {
+        oss << StringPrintf("<anonymous:%" PRIx64 ">", frame.map_info->start());
       } else {
-        oss << it->map.name;
+        oss << frame.map_info->name().c_str();
       }
-      if (it->map.offset != 0) {
-        oss << StringPrintf(" (offset %" PRIx64 ")", it->map.offset);
+      if (frame.map_info->offset() != 0) {
+        oss << StringPrintf(" (offset %" PRIx64 ")", frame.map_info->offset());
       }
       oss << " (";
-      if (!it->func_name.empty()) {
-        oss << it->func_name;
-        if (it->func_offset != 0) {
-          oss << "+" << it->func_offset;
+      const std::string& function_name = frame.function_name;
+      if (!function_name.empty()) {
+        oss << function_name;
+        if (frame.function_offset != 0) {
+          oss << "+" << frame.function_offset;
         }
         // Functions found using the gdb jit interface will be in an empty
         // map that cannot be found using addr2line.
-        if (!it->map.name.empty()) {
+        if (!frame.map_info->name().empty()) {
           try_addr2line = true;
         }
       } else {
@@ -558,8 +548,8 @@
     LOG(ERROR) << oss.str() << std::endl;
     if (try_addr2line && addr2line_path != nullptr) {
       addr2line::Addr2line(*addr2line_path,
-                           it->map.name,
-                           it->rel_pc,
+                           frame.map_info->name(),
+                           frame.rel_pc,
                            LOG_STREAM(ERROR),
                            prefix,
                            &addr2line_state);
@@ -593,14 +583,9 @@
     LOG(ERROR) << "Did not receive SIGSTOP for pid " << forked_pid;
   }
 
-  std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(forked_pid));
-  if (backtrace_map == nullptr) {
-    LOG(ERROR) << "Could not create BacktraceMap";
-    return;
-  }
-
+  unwindstack::AndroidRemoteUnwinder unwinder(forked_pid);
   for (pid_t tid : tids) {
-    DumpThread(forked_pid, tid, addr2line_path.get(), "  ", backtrace_map.get());
+    DumpThread(unwinder, forked_pid, tid, addr2line_path.get(), "  ");
   }
 }