From 7b2078eeb4f68f3a81695de64ec8df003d3f8e3c Mon Sep 17 00:00:00 2001 From: Brigid Smith Date: Tue, 17 Jun 2014 14:55:47 -0700 Subject: [PATCH] Changed maps output in debuggerd. Now the map output is only sent to the tombstone, and the entire contents of /prod/$PID/maps is logged, not just 3 lines. Additionally, crasher now supports "crasher SIGSEGV-non-null", which attempts to write to a dereferenced function address, causing a SIGSEGV at a non-zero address. This new crasher mode can be used to test the new maps output. Bug: 15343662 Change-Id: I796d92e8352a6b9714bbbfe96f3143c56565ef2f --- debuggerd/crasher.c | 10 +++++++++- debuggerd/tombstone.cpp | 32 ++++---------------------------- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/debuggerd/crasher.c b/debuggerd/crasher.c index 4721da9cf..e11d9af7f 100644 --- a/debuggerd/crasher.c +++ b/debuggerd/crasher.c @@ -110,12 +110,19 @@ static void abuse_heap() { free((void*) buf); // GCC is smart enough to warn about this, but we're doing it deliberately. } +static void sigsegv_non_null() { + int* a = (int *)(&do_action); + *a = 42; +} + static int do_action(const char* arg) { fprintf(stderr,"crasher: init pid=%d tid=%d\n", getpid(), gettid()); if (!strncmp(arg, "thread-", strlen("thread-"))) { return do_action_on_thread(arg + strlen("thread-")); + } else if (!strcmp(arg, "SIGSEGV-non-null")) { + sigsegv_non_null(); } else if (!strcmp(arg, "smash-stack")) { return smash_stack(42); } else if (!strcmp(arg, "stack-overflow")) { @@ -166,7 +173,8 @@ static int do_action(const char* arg) fprintf(stderr, " LOG_ALWAYS_FATAL call LOG_ALWAYS_FATAL\n"); fprintf(stderr, " LOG_ALWAYS_FATAL_IF call LOG_ALWAYS_FATAL\n"); fprintf(stderr, " SIGPIPE cause a SIGPIPE\n"); - fprintf(stderr, " SIGSEGV cause a SIGSEGV (synonym: crash)\n"); + fprintf(stderr, " SIGSEGV cause a SIGSEGV at address 0x0 (synonym: crash)\n"); + fprintf(stderr, " SIGSEGV-non-null cause a SIGSEGV at a non-zero address\n"); fprintf(stderr, " SIGTRAP cause a SIGTRAP\n"); fprintf(stderr, "prefix any of the above with 'thread-' to not run\n"); fprintf(stderr, "on the process' main thread.\n"); diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp index a06effc74..37839aab2 100755 --- a/debuggerd/tombstone.cpp +++ b/debuggerd/tombstone.cpp @@ -343,14 +343,10 @@ static void dump_backtrace_and_stack(Backtrace* backtrace, log_t* log) { } } -static void dump_map(log_t* log, const backtrace_map_t* map, const char* what) { - if (map != NULL) { - _LOG(log, logtype::MAPS, " %" PRIPTR "-%" PRIPTR " %c%c%c %s\n", map->start, map->end, +static void dump_map(log_t* log, const backtrace_map_t* map) { + _LOG(log, logtype::MAPS, " %" 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 { - _LOG(log, logtype::MAPS, " (no %s)\n", what); - } } static void dump_nearby_maps(BacktraceMap* map, log_t* log, pid_t tid) { @@ -370,31 +366,11 @@ static void dump_nearby_maps(BacktraceMap* map, log_t* log, pid_t tid) { return; } - _LOG(log, logtype::MAPS, "\nmemory map around fault addr %" PRIPTR ":\n", - reinterpret_cast(si.si_addr)); + _LOG(log, logtype::MAPS, "\nmemory map:\n"); - // Search for a match, or for a hole where the match would be. The list - // is backward from the file content, so it starts at high addresses. - const backtrace_map_t* cur_map = NULL; - const backtrace_map_t* next_map = NULL; - const backtrace_map_t* prev_map = NULL; for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) { - if (addr >= it->start && addr < it->end) { - cur_map = &*it; - if (it != map->begin()) { - prev_map = &*(it-1); - } - if (++it != map->end()) { - next_map = &*it; - } - break; - } + dump_map(log, &*it); } - - // Show the map address in ascending order (like /proc/pid/maps). - dump_map(log, prev_map, "map below"); - dump_map(log, cur_map, "map for address"); - dump_map(log, next_map, "map above"); } static void dump_thread(