diff options
author | Christopher Ferris <cferris@google.com> | 2022-01-07 13:38:10 -0800 |
---|---|---|
committer | Christopher Ferris <cferris@google.com> | 2022-03-03 15:23:25 -0800 |
commit | 459eecb28b68f9b8f2a71ca9765b291f11007030 (patch) | |
tree | 96a636854aa41bdfca0adfe4ac98bd1923ece7a4 /libfdtrack | |
parent | 39837afad7ba9411445677497f8c60b01a0b4195 (diff) | |
download | bionic-459eecb28b68f9b8f2a71ca9765b291f11007030.tar.gz |
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
Diffstat (limited to 'libfdtrack')
-rw-r--r-- | libfdtrack/Android.bp | 1 | ||||
-rw-r--r-- | libfdtrack/fdtrack.cpp | 52 |
2 files changed, 35 insertions, 18 deletions
diff --git a/libfdtrack/Android.bp b/libfdtrack/Android.bp index fb28623ef..83ea7cb4b 100644 --- a/libfdtrack/Android.bp +++ b/libfdtrack/Android.bp @@ -38,4 +38,5 @@ cc_test { 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 2e9cfbcd0..2d114f23e 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 @@ static void fd_hook(android_fdtrack_event* event); // 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 @@ __attribute__((constructor)) static void ctor() { 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 @@ static void fd_hook(android_fdtrack_event* event) { 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 @@ void fdtrack_iterate(fdtrack_callback_t callback, void* arg) { 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 @@ static void fdtrack_dump_impl(bool fatal) { 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; |