Update for LocalUnwinder object removal.

Modify libfdtrack to use the normal Unwinder object. In addition,
update the libfdtrack so that it doesn't record frames in
libfdtrack.so rather than skipping frames it thinks will be in
the library.

Modify the malloc debug code to use the normal Unwinder object.

Bug: 120606663

Test: All unit tests pass.
Change-Id: I3c9612dd10e62389e6219e68045ee87f7b2625f5
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index 90c9136..b982c0a 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -66,7 +66,8 @@
 std::unordered_map<FrameKeyType, size_t> PointerData::key_to_index_ GUARDED_BY(
     PointerData::frame_mutex_);
 std::unordered_map<size_t, FrameInfoType> PointerData::frames_ GUARDED_BY(PointerData::frame_mutex_);
-std::unordered_map<size_t, std::vector<unwindstack::LocalFrameData>> PointerData::backtraces_info_ GUARDED_BY(PointerData::frame_mutex_);
+std::unordered_map<size_t, std::vector<unwindstack::FrameData>> PointerData::backtraces_info_
+    GUARDED_BY(PointerData::frame_mutex_);
 constexpr size_t kBacktraceEmptyIndex = 1;
 size_t PointerData::cur_hash_index_ GUARDED_BY(PointerData::frame_mutex_);
 
@@ -136,7 +137,7 @@
 
 size_t PointerData::AddBacktrace(size_t num_frames) {
   std::vector<uintptr_t> frames;
-  std::vector<unwindstack::LocalFrameData> frames_info;
+  std::vector<unwindstack::FrameData> frames_info;
   if (g_debug->config().options() & BACKTRACE_FULL) {
     if (!Unwind(&frames, &frames_info, num_frames)) {
       return kBacktraceEmptyIndex;
@@ -386,7 +387,7 @@
     REQUIRES(pointer_mutex_, frame_mutex_) {
   for (const auto& entry : pointers_) {
     FrameInfoType* frame_info = nullptr;
-    std::vector<unwindstack::LocalFrameData>* backtrace_info = nullptr;
+    std::vector<unwindstack::FrameData>* backtrace_info = nullptr;
     size_t hash_index = entry.second.hash_index;
     if (hash_index > kBacktraceEmptyIndex) {
       auto frame_entry = frames_.find(hash_index);
diff --git a/libc/malloc_debug/PointerData.h b/libc/malloc_debug/PointerData.h
index 37d87db..92d2653 100644
--- a/libc/malloc_debug/PointerData.h
+++ b/libc/malloc_debug/PointerData.h
@@ -39,7 +39,7 @@
 #include <vector>
 
 #include <platform/bionic/macros.h>
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Unwinder.h>
 
 #include "OptionData.h"
 #include "UnwindBacktrace.h"
@@ -109,7 +109,7 @@
   size_t size;
   bool zygote_child_alloc;
   FrameInfoType* frame_info;
-  std::vector<unwindstack::LocalFrameData>* backtrace_info;
+  std::vector<unwindstack::FrameData>* backtrace_info;
 };
 
 class PointerData : public OptionData {
@@ -181,7 +181,7 @@
   static std::mutex frame_mutex_;
   static std::unordered_map<FrameKeyType, size_t> key_to_index_;
   static std::unordered_map<size_t, FrameInfoType> frames_;
-  static std::unordered_map<size_t, std::vector<unwindstack::LocalFrameData>> backtraces_info_;
+  static std::unordered_map<size_t, std::vector<unwindstack::FrameData>> backtraces_info_;
   static size_t cur_hash_index_;
 
   static std::mutex free_pointer_mutex_;
diff --git a/libc/malloc_debug/UnwindBacktrace.cpp b/libc/malloc_debug/UnwindBacktrace.cpp
index a7036d9..f6c3e69 100644
--- a/libc/malloc_debug/UnwindBacktrace.cpp
+++ b/libc/malloc_debug/UnwindBacktrace.cpp
@@ -36,8 +36,12 @@
 #include <vector>
 
 #include <android-base/stringprintf.h>
-#include <unwindstack/LocalUnwinder.h>
 #include <unwindstack/MapInfo.h>
+#include <unwindstack/Maps.h>
+#include <unwindstack/Memory.h>
+#include <unwindstack/Regs.h>
+#include <unwindstack/RegsGetLocal.h>
+#include <unwindstack/Unwinder.h>
 
 #include "UnwindBacktrace.h"
 #include "debug_log.h"
@@ -52,42 +56,56 @@
 
 static pthread_once_t g_setup_once = PTHREAD_ONCE_INIT;
 
-static unwindstack::LocalUnwinder* g_unwinder;
-
-static void Setup() {
+static unwindstack::LocalUpdatableMaps* g_maps;
+static std::shared_ptr<unwindstack::Memory> g_process_memory;
 #if defined(__LP64__)
-  std::vector<std::string> skip_libraries{"/system/lib64/libunwindstack.so", "/system/lib64/libc_malloc_debug.so"};
+static std::vector<std::string> g_skip_libraries{"/system/lib64/libunwindstack.so",
+                                                 "/system/lib64/libc_malloc_debug.so"};
 #else
-  std::vector<std::string> skip_libraries{"/system/lib/libunwindstack.so", "/system/lib/libc_malloc_debug.so"};
+static std::vector<std::string> g_skip_libraries{"/system/lib/libunwindstack.so",
+                                                 "/system/lib/libc_malloc_debug.so"};
 #endif
 
-  g_unwinder = new unwindstack::LocalUnwinder(skip_libraries);
-  g_unwinder->Init();
+static void Setup() {
+  g_maps = new unwindstack::LocalUpdatableMaps;
+  if (!g_maps->Parse()) {
+    delete g_maps;
+    g_maps = nullptr;
+  }
+
+  g_process_memory = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid());
 }
 
-bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::LocalFrameData>* frame_info, size_t max_frames) {
+bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* frame_info,
+            size_t max_frames) {
   pthread_once(&g_setup_once, Setup);
 
-  if (g_unwinder == nullptr) {
+  if (g_maps == nullptr) {
     return false;
   }
 
-  if (!g_unwinder->Unwind(frame_info, max_frames)) {
+  std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal());
+  unwindstack::RegsGetLocal(regs.get());
+  unwindstack::Unwinder unwinder(max_frames, g_maps, regs.get(), g_process_memory);
+  unwinder.Unwind(&g_skip_libraries);
+  if (unwinder.NumFrames() == 0) {
     frames->clear();
     frame_info->clear();
     return false;
   }
+  *frame_info = unwinder.ConsumeFrames();
 
-  for (const auto& frame : *frame_info) {
-    frames->push_back(frame.pc);
+  frames->resize(frame_info->size());
+  for (size_t i = 0; i < frame_info->size(); i++) {
+    frames->at(i) = frame_info->at(i).pc;
   }
   return true;
 }
 
-void UnwindLog(const std::vector<unwindstack::LocalFrameData>& frame_info) {
+void UnwindLog(const std::vector<unwindstack::FrameData>& frame_info) {
   for (size_t i = 0; i < frame_info.size(); i++) {
-    const unwindstack::LocalFrameData* info = &frame_info[i];
-    std::shared_ptr<unwindstack::MapInfo> map_info = info->map_info;
+    const unwindstack::FrameData* info = &frame_info[i];
+    auto map_info = info->map_info;
 
     std::string line = android::base::StringPrintf("          #%0zd  pc %" PAD_PTR "  ", i, info->rel_pc);
     if (map_info != nullptr && map_info->offset() != 0) {
diff --git a/libc/malloc_debug/UnwindBacktrace.h b/libc/malloc_debug/UnwindBacktrace.h
index 4c6c8d4..7f89907 100644
--- a/libc/malloc_debug/UnwindBacktrace.h
+++ b/libc/malloc_debug/UnwindBacktrace.h
@@ -33,9 +33,10 @@
 #include <string>
 #include <vector>
 
-#include <unwindstack/LocalUnwinder.h>
 #include <unwindstack/MapInfo.h>
+#include <unwindstack/Unwinder.h>
 
-bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::LocalFrameData>* info, size_t max_frames);
+bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* info,
+            size_t max_frames);
 
-void UnwindLog(const std::vector<unwindstack::LocalFrameData>& frame_info);
+void UnwindLog(const std::vector<unwindstack::FrameData>& frame_info);
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index d23ab15..9f38946 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -49,6 +49,7 @@
 #include <platform/bionic/reserved_signals.h>
 #include <private/MallocXmlElem.h>
 #include <private/bionic_malloc_dispatch.h>
+#include <unwindstack/Unwinder.h>
 
 #include "Config.h"
 #include "DebugData.h"
@@ -193,7 +194,7 @@
 void BacktraceAndLog() {
   if (g_debug->config().options() & BACKTRACE_FULL) {
     std::vector<uintptr_t> frames;
-    std::vector<unwindstack::LocalFrameData> frames_info;
+    std::vector<unwindstack::FrameData> frames_info;
     if (!Unwind(&frames, &frames_info, 256)) {
       error_log("  Backtrace failed to get any frames.");
     } else {
diff --git a/libc/malloc_debug/tests/backtrace_fake.cpp b/libc/malloc_debug/tests/backtrace_fake.cpp
index ad16c02..f54bae8 100644
--- a/libc/malloc_debug/tests/backtrace_fake.cpp
+++ b/libc/malloc_debug/tests/backtrace_fake.cpp
@@ -20,7 +20,7 @@
 #include <vector>
 #include <utility>
 
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Unwinder.h>
 
 #include "backtrace.h"
 #include "backtrace_fake.h"
@@ -60,17 +60,17 @@
   }
 }
 
-static std::deque<std::vector<unwindstack::LocalFrameData>> g_fake_local_frame_data;
+static std::deque<std::vector<unwindstack::FrameData>> g_fake_local_frame_data;
 
 void BacktraceUnwindFakeClearAll() {
   g_fake_local_frame_data.clear();
 }
 
-void BacktraceUnwindFake(const std::vector<unwindstack::LocalFrameData>& frames) {
+void BacktraceUnwindFake(const std::vector<unwindstack::FrameData>& frames) {
   g_fake_local_frame_data.push_back(frames);
 }
 
-bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::LocalFrameData>* info, size_t) {
+bool Unwind(std::vector<uintptr_t>* frames, std::vector<unwindstack::FrameData>* info, size_t) {
   if (g_fake_local_frame_data.empty()) {
     return false;
   }
@@ -85,5 +85,4 @@
   return true;
 }
 
-void UnwindLog(const std::vector<unwindstack::LocalFrameData>& /*frame_info*/) {
-}
+void UnwindLog(const std::vector<unwindstack::FrameData>& /*frame_info*/) {}
diff --git a/libc/malloc_debug/tests/backtrace_fake.h b/libc/malloc_debug/tests/backtrace_fake.h
index a9ee97d..246fc61 100644
--- a/libc/malloc_debug/tests/backtrace_fake.h
+++ b/libc/malloc_debug/tests/backtrace_fake.h
@@ -21,12 +21,12 @@
 
 #include <vector>
 
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Unwinder.h>
 
 void backtrace_fake_clear_all();
 void backtrace_fake_add(const std::vector<uintptr_t>& ips);
 
 void BacktraceUnwindFakeClearAll();
-void BacktraceUnwindFake(const std::vector<unwindstack::LocalFrameData>& frames);
+void BacktraceUnwindFake(const std::vector<unwindstack::FrameData>& frames);
 
 #endif // MALLOC_DEBUG_TESTS_BACKTRACE_FAKE_H
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 7b58f31..46de3e9 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -44,6 +44,8 @@
 #include <platform/bionic/macros.h>
 #include <private/bionic_malloc_dispatch.h>
 
+#include <unwindstack/Unwinder.h>
+
 #include "Config.h"
 #include "malloc_debug.h"
 
@@ -1530,16 +1532,18 @@
   if ((pid = fork()) == 0) {
     std::shared_ptr<unwindstack::MapInfo> empty_map;
     Init("backtrace=4 backtrace_full backtrace_dump_on_exit");
-    BacktraceUnwindFake(std::vector<unwindstack::LocalFrameData>{
-        {empty_map, 0x1100, 0x100, "fake1", 10}, {empty_map, 0x1200, 0x200, "fake2", 20}});
+    BacktraceUnwindFake(
+        std::vector<unwindstack::FrameData>{{0, 0x100, 0x1100, 0, "fake1", 10, empty_map},
+                                            {1, 0x200, 0x1200, 0, "fake2", 20, empty_map}});
     std::shared_ptr<unwindstack::MapInfo> map_info =
         unwindstack::MapInfo::Create(0x10000, 0x20000, 0, PROT_READ | PROT_EXEC, "/data/fake.so");
-    BacktraceUnwindFake(std::vector<unwindstack::LocalFrameData>{
-        {map_info, 0x1a000, 0xa000, "level1", 0}, {map_info, 0x1b000, 0xb000, "level2", 10}});
     BacktraceUnwindFake(
-        std::vector<unwindstack::LocalFrameData>{{empty_map, 0x1a000, 0xa000, "func1", 0},
-                                                 {empty_map, 0x1b000, 0xb000, "func2", 10},
-                                                 {empty_map, 0x1c000, 0xc000, "", 30}});
+        std::vector<unwindstack::FrameData>{{0, 0xa000, 0x1a000, 0, "level1", 0, map_info},
+                                            {1, 0xb000, 0x1b000, 0, "level2", 10, map_info}});
+    BacktraceUnwindFake(
+        std::vector<unwindstack::FrameData>{{0, 0xa000, 0x1a000, 0, "func1", 0, empty_map},
+                                            {1, 0xb000, 0x1b000, 0, "func2", 10, empty_map},
+                                            {2, 0xc000, 0x1c000, 0, "", 30, empty_map}});
 
     std::vector<void*> pointers;
     pointers.push_back(debug_malloc(300));
diff --git a/libfdtrack/Android.bp b/libfdtrack/Android.bp
index fb28623..83ea7cb 100644
--- a/libfdtrack/Android.bp
+++ b/libfdtrack/Android.bp
@@ -38,4 +38,5 @@
     whole_static_libs: ["libBionicCtsGtestMain"],
     static_libs: ["liblog"],
     test_suites: ["device-tests"],
+    runtime_libs: ["libfdtrack"],
 }
diff --git a/libfdtrack/fdtrack.cpp b/libfdtrack/fdtrack.cpp
index 2e9cfbc..2d114f2 100644
--- a/libfdtrack/fdtrack.cpp
+++ b/libfdtrack/fdtrack.cpp
@@ -31,6 +31,8 @@
 
 #include <array>
 #include <mutex>
+#include <string>
+#include <string_view>
 #include <thread>
 #include <utility>
 #include <vector>
@@ -43,11 +45,14 @@
 #include <android-base/thread_annotations.h>
 #include <async_safe/log.h>
 #include <bionic/reserved_signals.h>
-#include <unwindstack/LocalUnwinder.h>
+#include <unwindstack/Maps.h>
+#include <unwindstack/Regs.h>
+#include <unwindstack/RegsGetLocal.h>
+#include <unwindstack/Unwinder.h>
 
 struct FdEntry {
   std::mutex mutex;
-  std::vector<unwindstack::LocalFrameData> backtrace GUARDED_BY(mutex);
+  std::vector<unwindstack::FrameData> backtrace GUARDED_BY(mutex);
 };
 
 extern "C" void fdtrack_dump();
@@ -62,15 +67,21 @@
 // Backtraces for the first 4k file descriptors ought to be enough to diagnose an fd leak.
 static constexpr size_t kFdTableSize = 4096;
 
-// 32 frames, plus two to skip from fdtrack itself.
-static constexpr size_t kStackDepth = 34;
-static constexpr size_t kStackFrameSkip = 2;
+// Only unwind up to 32 frames outside of libfdtrack.so.
+static constexpr size_t kStackDepth = 32;
+
+// Skip any initial frames from libfdtrack.so.
+static std::vector<std::string> kSkipFdtrackLib [[clang::no_destroy]] = {"libfdtrack.so"};
 
 static bool installed = false;
 static std::array<FdEntry, kFdTableSize> stack_traces [[clang::no_destroy]];
-static unwindstack::LocalUnwinder& Unwinder() {
-  static android::base::NoDestructor<unwindstack::LocalUnwinder> unwinder;
-  return *unwinder.get();
+static unwindstack::LocalUpdatableMaps& Maps() {
+  static android::base::NoDestructor<unwindstack::LocalUpdatableMaps> maps;
+  return *maps.get();
+}
+static std::shared_ptr<unwindstack::Memory>& ProcessMemory() {
+  static android::base::NoDestructor<std::shared_ptr<unwindstack::Memory>> process_memory;
+  return *process_memory.get();
 }
 
 __attribute__((constructor)) static void ctor() {
@@ -89,7 +100,8 @@
   sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
   sigaction(BIONIC_SIGNAL_FDTRACK, &sa, nullptr);
 
-  if (Unwinder().Init()) {
+  if (Maps().Parse()) {
+    ProcessMemory() = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid());
     android_fdtrack_hook_t expected = nullptr;
     installed = android_fdtrack_compare_exchange_hook(&expected, &fd_hook);
   }
@@ -116,7 +128,12 @@
     if (FdEntry* entry = GetFdEntry(event->fd); entry) {
       std::lock_guard<std::mutex> lock(entry->mutex);
       entry->backtrace.clear();
-      Unwinder().Unwind(&entry->backtrace, kStackDepth);
+
+      std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::CreateFromLocal());
+      unwindstack::RegsGetLocal(regs.get());
+      unwindstack::Unwinder unwinder(kStackDepth, &Maps(), regs.get(), ProcessMemory());
+      unwinder.Unwind(&kSkipFdtrackLib);
+      entry->backtrace = unwinder.ConsumeFrames();
     }
   } else if (event->type == ANDROID_FDTRACK_EVENT_TYPE_CLOSE) {
     if (FdEntry* entry = GetFdEntry(event->fd); entry) {
@@ -153,14 +170,13 @@
       continue;
     }
 
-    for (size_t i = kStackFrameSkip; i < entry->backtrace.size(); ++i) {
-      size_t j = i - kStackFrameSkip;
-      function_names[j] = entry->backtrace[i].function_name.c_str();
-      function_offsets[j] = entry->backtrace[i].function_offset;
+    for (size_t i = 0; i < entry->backtrace.size(); ++i) {
+      function_names[i] = entry->backtrace[i].function_name.c_str();
+      function_offsets[i] = entry->backtrace[i].function_offset;
     }
 
-    bool should_continue = callback(fd, function_names, function_offsets,
-                                    entry->backtrace.size() - kStackFrameSkip, arg);
+    bool should_continue =
+        callback(fd, function_names, function_offsets, entry->backtrace.size(), arg);
 
     entry->mutex.unlock();
 
@@ -200,8 +216,8 @@
     size_t count = 0;
 
     size_t stack_depth = 0;
-    const char* function_names[kStackDepth - kStackFrameSkip];
-    uint64_t function_offsets[kStackDepth - kStackFrameSkip];
+    const char* function_names[kStackDepth];
+    uint64_t function_offsets[kStackDepth];
   };
   struct StackList {
     size_t count = 0;