Skip to content

Commit

Permalink
Add more logging to sigchainlib to debug missing backtraces
Browse files Browse the repository at this point in the history
Bug: 303039968
Bug: 314729187
Test: check that extra stack gets printed (with local modifications)
Change-Id: Idf1f5103292241073dce991826f629cfc9c6e711
  • Loading branch information
dsrbecky committed Dec 4, 2023
1 parent 04ccad0 commit e274b0a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 9 deletions.
1 change: 1 addition & 0 deletions sigchainlib/Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ cc_library {
android: {
header_libs: ["bionic_libc_platform_headers"],
static_libs: ["libasync_safe"],
shared_libs: ["libunwindstack"],
},

linux_bionic: {
Expand Down
8 changes: 5 additions & 3 deletions sigchainlib/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@

#include <async_safe/log.h>

#define log(...) async_safe_format_log(ANDROID_LOG_ERROR, "libsigchain", __VA_ARGS__)
#define LogError(...) async_safe_format_log(ANDROID_LOG_ERROR, "libsigchain", __VA_ARGS__)
#define fatal async_safe_fatal

#else

#include <stdarg.h>
#include <stdio.h>

static void log(const char* format, ...) {
static void LogError(const char* format, ...) {
va_list ap;
va_start(ap, format);
vprintf(format, ap);
Expand All @@ -38,7 +38,9 @@ static void log(const char* format, ...) {
printf("\n");
}

#define fatal(...) log(__VA_ARGS__); abort()
#define fatal(...) \
LogError(__VA_ARGS__); \
abort()

#endif

Expand Down
34 changes: 32 additions & 2 deletions sigchainlib/sigchain.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include <dlfcn.h>
#include <errno.h>
#include <inttypes.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
Expand All @@ -24,6 +25,7 @@

#if defined(__BIONIC__)
#include <bionic/macros.h>
#include <unwindstack/AndroidUnwinder.h>
#endif

#include <algorithm>
Expand Down Expand Up @@ -96,6 +98,28 @@ static int sigorset(SigsetType* dest, SigsetType* left, SigsetType* right) {
return 0;
}

void LogStack() {
#if defined(__BIONIC__)
unwindstack::AndroidLocalUnwinder unwinder;
unwindstack::AndroidUnwinderData data;
if (!unwinder.Unwind(data)) {
LogError("Failed to get callstack.");
return;
}
data.DemangleFunctionNames();
for (const unwindstack::FrameData& frame : data.frames) {
auto& map = frame.map_info;
LogError(" #%02zu pc %08" PRIx64 " %s (%s+%" PRIu64 ") (BuildId: %s)",
frame.num,
frame.rel_pc,
map != nullptr ? map->name().c_str() : "???",
frame.function_name.c_str(),
frame.function_offset,
map != nullptr ? map->GetPrintableBuildID().c_str() : "???");
}
#endif
}

namespace art {

static decltype(&sigaction) linked_sigaction;
Expand Down Expand Up @@ -490,7 +514,8 @@ void SignalChain::Handler(int signo, siginfo_t* siginfo, void* ucontext_raw) {
// the crash will have no way to know our ucontext, and thus no way to dump the original crash
// stack (since we're on an alternate stack.) Let's remove our handler and return. Then the
// pre-crash state is restored, the crash happens again, and the next handler gets a chance.
log("reverting to SIG_DFL handler for signal %d, ucontext %p", signo, ucontext);
LogError("reverting to SIG_DFL handler for signal %d, ucontext %p", signo, ucontext);
LogStack();
struct sigaction dfl = {};
dfl.sa_handler = SIG_DFL;
linked_sigaction(signo, &dfl, nullptr);
Expand Down Expand Up @@ -519,6 +544,11 @@ static int __sigaction(int signal, const SigactionType* new_action,
return -1;
}

if (signal == SIGSEGV && new_action != nullptr && new_action->sa_handler == SIG_DFL) {
LogError("Setting SIGSEGV to SIG_DFL");
LogStack();
}

if (chains[signal].IsClaimed()) {
SigactionType saved_action = chains[signal].GetAction<SigactionType>();
if (new_action != nullptr) {
Expand Down Expand Up @@ -672,7 +702,7 @@ extern "C" void EnsureFrontOfChain(int signal) {
// If the sigactions don't match then we put the current action on the chain and make ourself as
// the main action.
if (current_action.sa_sigaction != SignalChain::Handler) {
log("Warning: Unexpected sigaction action found %p\n", current_action.sa_sigaction);
LogError("Warning: Unexpected sigaction action found %p\n", current_action.sa_sigaction);
chains[signal].Register(signal);
}
}
Expand Down
8 changes: 4 additions & 4 deletions sigchainlib/sigchain_fake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,24 @@
namespace art {

extern "C" void EnsureFrontOfChain([[maybe_unused]] int signal) {
log("EnsureFrontOfChain is not exported by the main executable.");
LogError("EnsureFrontOfChain is not exported by the main executable.");
abort();
}

extern "C" void AddSpecialSignalHandlerFn([[maybe_unused]] int signal,
[[maybe_unused]] SigchainAction* sa) {
log("SetSpecialSignalHandlerFn is not exported by the main executable.");
LogError("SetSpecialSignalHandlerFn is not exported by the main executable.");
abort();
}

extern "C" void RemoveSpecialSignalHandlerFn([[maybe_unused]] int signal,
[[maybe_unused]] bool (*fn)(int, siginfo_t*, void*)) {
log("SetSpecialSignalHandlerFn is not exported by the main executable.");
LogError("SetSpecialSignalHandlerFn is not exported by the main executable.");
abort();
}

extern "C" void SkipAddSignalHandler([[maybe_unused]] bool value) {
log("SkipAddSignalHandler is not exported by the main executable.");
LogError("SkipAddSignalHandler is not exported by the main executable.");
abort();
}

Expand Down

0 comments on commit e274b0a

Please sign in to comment.