summaryrefslogtreecommitdiffstats
path: root/debuggerd/tombstone.cpp
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2014-04-25 16:05:34 -0700
committerElliott Hughes <enh@google.com>2014-04-25 20:20:39 -0700
commit855fcc3114c20ff9fd286fe1723d1413fec9685a (patch)
tree012f6de674c3ba210b9f1de42d9c7607a6e9862d /debuggerd/tombstone.cpp
parent2317287d18fae3f9ae0f3beb7748a804f06b5720 (diff)
downloadsystem_core-855fcc3114c20ff9fd286fe1723d1413fec9685a.zip
system_core-855fcc3114c20ff9fd286fe1723d1413fec9685a.tar.gz
system_core-855fcc3114c20ff9fd286fe1723d1413fec9685a.tar.bz2
Use the si_code value bionic passes us.
Bionic needs to re-raise various signals, which means the si_code debuggerd sees has been clobbered. If bionic sends us the original si_code value, we can use that instead of the one we see when the ptrace the crashed process' siginfo. Change-Id: If116a6bc667d55a6fb39b74f96673292af4e4c8c
Diffstat (limited to 'debuggerd/tombstone.cpp')
-rwxr-xr-xdebuggerd/tombstone.cpp47
1 files changed, 27 insertions, 20 deletions
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 83df37f..f95e572 100755
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -55,7 +55,7 @@
// Must match the path defined in NativeCrashListener.java
#define NCRASH_SOCKET_PATH "/data/system/ndebugsocket"
-static bool signal_has_address(int sig) {
+static bool signal_has_si_addr(int sig) {
switch (sig) {
case SIGILL:
case SIGFPE:
@@ -75,7 +75,7 @@ static const char* get_signame(int sig) {
case SIGFPE: return "SIGFPE";
case SIGSEGV: return "SIGSEGV";
case SIGPIPE: return "SIGPIPE";
-#ifdef SIGSTKFLT
+#if defined(SIGSTKFLT)
case SIGSTKFLT: return "SIGSTKFLT";
#endif
case SIGSTOP: return "SIGSTOP";
@@ -171,20 +171,26 @@ static void dump_build_info(log_t* log) {
_LOG(log, SCOPE_AT_FAULT, "Build fingerprint: '%s'\n", fingerprint);
}
-static void dump_fault_addr(log_t* log, pid_t tid, int sig) {
+static void dump_signal_info(log_t* log, pid_t tid, int signal, int si_code) {
siginfo_t si;
-
memset(&si, 0, sizeof(si));
- if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si)){
+ if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si) == -1) {
_LOG(log, SCOPE_AT_FAULT, "cannot get siginfo: %s\n", strerror(errno));
- } else if (signal_has_address(sig)) {
- _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr %" PRIPTR "\n",
- sig, get_signame(sig), si.si_code, get_sigcode(sig, si.si_code),
- reinterpret_cast<uintptr_t>(si.si_addr));
+ return;
+ }
+
+ // bionic has to re-raise some signals, which overwrites the si_code with SI_TKILL.
+ si.si_code = si_code;
+
+ char addr_desc[32]; // ", fault addr 0x1234"
+ if (signal_has_si_addr(signal)) {
+ snprintf(addr_desc, sizeof(addr_desc), "%p", si.si_addr);
} else {
- _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr --------\n",
- sig, get_signame(sig), si.si_code, get_sigcode(sig, si.si_code));
+ snprintf(addr_desc, sizeof(addr_desc), "--------");
}
+
+ _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr %s\n",
+ signal, get_signame(signal), si.si_code, get_sigcode(signal, si.si_code), addr_desc);
}
static void dump_thread_info(log_t* log, pid_t pid, pid_t tid, int scope_flags) {
@@ -349,7 +355,7 @@ static void dump_nearby_maps(BacktraceMap* map, log_t* log, pid_t tid, int scope
_LOG(log, scope_flags, "cannot get siginfo for %d: %s\n", tid, strerror(errno));
return;
}
- if (!signal_has_address(si.si_signo)) {
+ if (!signal_has_si_addr(si.si_signo)) {
return;
}
@@ -588,8 +594,9 @@ static void dump_abort_message(Backtrace* backtrace, log_t* log, uintptr_t addre
}
// Dumps all information about the specified pid to the tombstone.
-static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t abort_msg_address,
- bool dump_sibling_threads, int* total_sleep_time_usec) {
+static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, int si_code,
+ uintptr_t abort_msg_address, bool dump_sibling_threads,
+ int* total_sleep_time_usec) {
// don't copy log messages to tombstone unless this is a dev device
char value[PROPERTY_VALUE_MAX];
property_get("ro.debuggable", value, "0");
@@ -611,7 +618,7 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t a
dump_revision_info(log);
dump_thread_info(log, pid, tid, SCOPE_AT_FAULT);
if (signal) {
- dump_fault_addr(log, tid, signal);
+ dump_signal_info(log, tid, signal, si_code);
}
UniquePtr<BacktraceMap> map(BacktraceMap::Create(pid));
@@ -725,9 +732,9 @@ static int activity_manager_connect() {
return amfd;
}
-char* engrave_tombstone(
- pid_t pid, pid_t tid, int signal, uintptr_t abort_msg_address, bool dump_sibling_threads,
- bool quiet, bool* detach_failed, int* total_sleep_time_usec) {
+char* engrave_tombstone(pid_t pid, pid_t tid, int signal, int original_si_code,
+ uintptr_t abort_msg_address, bool dump_sibling_threads, bool quiet,
+ bool* detach_failed, int* total_sleep_time_usec) {
if ((mkdir(TOMBSTONE_DIR, 0755) == -1) && (errno != EEXIST)) {
LOG("failed to create %s: %s\n", TOMBSTONE_DIR, strerror(errno));
}
@@ -752,8 +759,8 @@ char* engrave_tombstone(
log.tfd = fd;
log.amfd = activity_manager_connect();
log.quiet = quiet;
- *detach_failed = dump_crash(
- &log, pid, tid, signal, abort_msg_address, dump_sibling_threads, total_sleep_time_usec);
+ *detach_failed = dump_crash(&log, pid, tid, signal, original_si_code, abort_msg_address,
+ dump_sibling_threads, total_sleep_time_usec);
close(log.amfd);
close(fd);