diff options
Diffstat (limited to 'debuggerd/tombstone.cpp')
-rwxr-xr-x[-rw-r--r--] | debuggerd/tombstone.cpp | 83 |
1 files changed, 41 insertions, 42 deletions
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp index 11e9af5..c630020 100644..100755 --- a/debuggerd/tombstone.cpp +++ b/debuggerd/tombstone.cpp @@ -14,18 +14,20 @@ * limitations under the License. */ +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <inttypes.h> +#include <signal.h> #include <stddef.h> +#include <stdio.h> #include <stdlib.h> -#include <signal.h> #include <string.h> -#include <stdio.h> -#include <fcntl.h> -#include <errno.h> -#include <dirent.h> #include <time.h> #include <sys/ptrace.h> +#include <sys/socket.h> #include <sys/stat.h> -#include <inttypes.h> +#include <sys/un.h> #include <private/android_filesystem_config.h> @@ -36,9 +38,6 @@ #include <backtrace/Backtrace.h> #include <backtrace/BacktraceMap.h> -#include <sys/socket.h> -#include <linux/un.h> - #include <selinux/android.h> #include <UniquePtr.h> @@ -51,6 +50,7 @@ #define MAX_TOMBSTONES 10 #define TOMBSTONE_DIR "/data/tombstones" +#define TOMBSTONE_TEMPLATE (TOMBSTONE_DIR"/tombstone_%02d") // Must match the path defined in NativeCrashListener.java #define NCRASH_SOCKET_PATH "/data/system/ndebugsocket" @@ -60,7 +60,6 @@ typeof(y) __dummy2; \ (void)(&__dummy1 == &__dummy2); } - static bool signal_has_address(int sig) { switch (sig) { case SIGILL: @@ -180,9 +179,9 @@ static void dump_fault_addr(log_t* log, pid_t tid, int sig) { if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si)){ _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 %0*" PRIxPTR "\n", + _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), - sizeof(uintptr_t)*2, reinterpret_cast<uintptr_t>(si.si_addr)); + reinterpret_cast<uintptr_t>(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)); @@ -227,7 +226,7 @@ static void dump_thread_info(log_t* log, pid_t pid, pid_t tid, int scope_flags) static void dump_stack_segment( Backtrace* backtrace, log_t* log, int scope_flags, uintptr_t* sp, size_t words, int label) { for (size_t i = 0; i < words; i++) { - uint32_t stack_content; + word_t stack_content; if (!backtrace->ReadWord(*sp, &stack_content)) { break; } @@ -244,32 +243,32 @@ static void dump_stack_segment( if (!func_name.empty()) { if (!i && label >= 0) { if (offset) { - _LOG(log, scope_flags, " #%02d %08x %08x %s (%s+%u)\n", + _LOG(log, scope_flags, " #%02d %" PRIPTR " %" PRIPTR " %s (%s+%" PRIuPTR ")\n", label, *sp, stack_content, map_name, func_name.c_str(), offset); } else { - _LOG(log, scope_flags, " #%02d %08x %08x %s (%s)\n", + _LOG(log, scope_flags, " #%02d %" PRIPTR " %" PRIPTR " %s (%s)\n", label, *sp, stack_content, map_name, func_name.c_str()); } } else { if (offset) { - _LOG(log, scope_flags, " %08x %08x %s (%s+%u)\n", + _LOG(log, scope_flags, " %" PRIPTR " %" PRIPTR " %s (%s+%" PRIuPTR ")\n", *sp, stack_content, map_name, func_name.c_str(), offset); } else { - _LOG(log, scope_flags, " %08x %08x %s (%s)\n", + _LOG(log, scope_flags, " %" PRIPTR " %" PRIPTR " %s (%s)\n", *sp, stack_content, map_name, func_name.c_str()); } } } else { if (!i && label >= 0) { - _LOG(log, scope_flags, " #%02d %08x %08x %s\n", + _LOG(log, scope_flags, " #%02d %" PRIPTR " %" PRIPTR " %s\n", label, *sp, stack_content, map_name); } else { - _LOG(log, scope_flags, " %08x %08x %s\n", + _LOG(log, scope_flags, " %" PRIPTR " %" PRIPTR " %s\n", *sp, stack_content, map_name); } } - *sp += sizeof(uint32_t); + *sp += sizeof(word_t); } } @@ -292,7 +291,7 @@ static void dump_stack(Backtrace* backtrace, log_t* log, int scope_flags) { scope_flags |= SCOPE_SENSITIVE; // Dump a few words before the first frame. - uintptr_t sp = backtrace->GetFrame(first)->sp - STACK_WORDS * sizeof(uint32_t); + word_t sp = backtrace->GetFrame(first)->sp - STACK_WORDS * sizeof(word_t); dump_stack_segment(backtrace, log, scope_flags, &sp, STACK_WORDS, -1); // Dump a few words from all successive frames. @@ -312,7 +311,7 @@ static void dump_stack(Backtrace* backtrace, log_t* log, int scope_flags) { _LOG(log, scope_flags, " ........ ........\n"); } } else { - size_t words = frame->stack_size / sizeof(uint32_t); + size_t words = frame->stack_size / sizeof(word_t); if (words == 0) { words = 1; } else if (words > STACK_WORDS) { @@ -335,7 +334,7 @@ static void dump_backtrace_and_stack(Backtrace* backtrace, log_t* log, int scope static void dump_map(log_t* log, const backtrace_map_t* map, const char* what, int scope_flags) { if (map != NULL) { - _LOG(log, scope_flags, " %08x-%08x %c%c%c %s\n", map->start, map->end, + _LOG(log, scope_flags, " %" PRIPTR "-%" PRIPTR " %c%c%c %s\n", map->start, map->end, (map->flags & PROT_READ) ? 'r' : '-', (map->flags & PROT_WRITE) ? 'w' : '-', (map->flags & PROT_EXEC) ? 'x' : '-', map->name.c_str()); } else { @@ -361,7 +360,7 @@ static void dump_nearby_maps(BacktraceMap* map, log_t* log, pid_t tid, int scope return; } - _LOG(log, scope_flags, "\nmemory map around fault addr %" PRIxPTR ":\n", + _LOG(log, scope_flags, "\nmemory map around fault addr %" PRIPTR ":\n", reinterpret_cast<uintptr_t>(si.si_addr)); // Search for a match, or for a hole where the match would be. The list @@ -574,24 +573,15 @@ static void dump_abort_message(Backtrace* backtrace, log_t* log, uintptr_t addre memset(msg, 0, sizeof(msg)); char* p = &msg[0]; while (p < &msg[sizeof(msg)]) { - uint32_t data; + word_t data; + size_t len = sizeof(word_t); if (!backtrace->ReadWord(address, &data)) { break; } - address += sizeof(uint32_t); + address += sizeof(word_t); - if ((*p++ = (data >> 0) & 0xff) == 0) { - break; - } - if ((*p++ = (data >> 8) & 0xff) == 0) { - break; - } - if ((*p++ = (data >> 16) & 0xff) == 0) { - break; - } - if ((*p++ = (data >> 24) & 0xff) == 0) { - break; - } + while (len > 0 && (*p++ = (data >> (sizeof(word_t) - len) * 8) & 0xff) != 0) + len--; } msg[sizeof(msg) - 1] = '\0'; @@ -663,7 +653,11 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t a // // Returns the path of the tombstone file, allocated using malloc(). Caller must free() it. static char* find_and_open_tombstone(int* fd) { +#ifdef __aarch64__ + long mtime = LONG_MAX; +#else unsigned long mtime = ULONG_MAX; +#endif struct stat sb; // XXX: Our stat.st_mtime isn't time_t. If it changes, as it probably ought @@ -675,7 +669,7 @@ static char* find_and_open_tombstone(int* fd) { char path[128]; int oldest = 0; for (int i = 0; i < MAX_TOMBSTONES; i++) { - snprintf(path, sizeof(path), TOMBSTONE_DIR"/tombstone_%02d", i); + snprintf(path, sizeof(path), TOMBSTONE_TEMPLATE, i); if (!stat(path, &sb)) { if (sb.st_mtime < mtime) { @@ -696,7 +690,7 @@ static char* find_and_open_tombstone(int* fd) { } // we didn't find an available file, so we clobber the oldest one - snprintf(path, sizeof(path), TOMBSTONE_DIR"/tombstone_%02d", oldest); + snprintf(path, sizeof(path), TOMBSTONE_TEMPLATE, oldest); *fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600); if (*fd < 0) { LOG("failed to open tombstone file '%s': %s\n", path, strerror(errno)); @@ -739,8 +733,13 @@ static int activity_manager_connect() { 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) { - mkdir(TOMBSTONE_DIR, 0755); - chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM); + if ((mkdir(TOMBSTONE_DIR, 0755) == -1) && (errno != EEXIST)) { + LOG("failed to create %s: %s\n", TOMBSTONE_DIR, strerror(errno)); + } + + if (chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM) == -1) { + LOG("failed to change ownership of %s: %s\n", TOMBSTONE_DIR, strerror(errno)); + } if (selinux_android_restorecon(TOMBSTONE_DIR) == -1) { *detach_failed = false; |