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/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;