aboutsummaryrefslogtreecommitdiff
path: root/libfdtrack
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2022-01-07 13:38:10 -0800
committerChristopher Ferris <cferris@google.com>2022-03-03 15:23:25 -0800
commit459eecb28b68f9b8f2a71ca9765b291f11007030 (patch)
tree96a636854aa41bdfca0adfe4ac98bd1923ece7a4 /libfdtrack
parent39837afad7ba9411445677497f8c60b01a0b4195 (diff)
downloadbionic-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.bp1
-rw-r--r--libfdtrack/fdtrack.cpp52
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;