diff options
author | Elliott Hughes <enh@google.com> | 2014-01-30 23:56:55 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-01-30 23:56:55 +0000 |
commit | e97dad0d95ae1305686bf4294029da947fc2dcf2 (patch) | |
tree | 543b751ef1bc60395d3d6b807b4697b9ce769d8a | |
parent | 8623972dc0055ae878df24cf93a663e60a6787f1 (diff) | |
parent | 4bb477205a2446c3ba9db8df0b0446173065d9eb (diff) | |
download | system_core-e97dad0d95ae1305686bf4294029da947fc2dcf2.zip system_core-e97dad0d95ae1305686bf4294029da947fc2dcf2.tar.gz system_core-e97dad0d95ae1305686bf4294029da947fc2dcf2.tar.bz2 |
Merge "debuggerd: a few generic improvements"
-rw-r--r-- | debuggerd/arm/machine.cpp | 59 | ||||
-rw-r--r-- | debuggerd/mips/machine.cpp | 55 | ||||
-rw-r--r-- | debuggerd/tombstone.cpp | 32 | ||||
-rw-r--r-- | debuggerd/utility.cpp | 74 | ||||
-rw-r--r-- | debuggerd/utility.h | 13 |
5 files changed, 104 insertions, 129 deletions
diff --git a/debuggerd/arm/machine.cpp b/debuggerd/arm/machine.cpp index 3fba6db..fd2f69b 100644 --- a/debuggerd/arm/machine.cpp +++ b/debuggerd/arm/machine.cpp @@ -38,65 +38,6 @@ #endif #endif -static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scope_flags) { - char code_buffer[64]; // actual 8+1+((8+1)*4) + 1 == 45 - char ascii_buffer[32]; // actual 16 + 1 == 17 - uintptr_t p, end; - - p = addr & ~3; - p -= 32; - if (p > addr) { - // catch underflow - p = 0; - } - // Dump more memory content for the crashing thread. - end = p + 256; - // catch overflow; 'end - p' has to be multiples of 16 - while (end < p) - end -= 16; - - // Dump the code around PC as: - // addr contents ascii - // 00008d34 ef000000 e8bd0090 e1b00000 512fff1e ............../Q - // 00008d44 ea00b1f9 e92d0090 e3a070fc ef000000 ......-..p...... - while (p < end) { - char* asc_out = ascii_buffer; - - sprintf(code_buffer, "%08x ", p); - - int i; - for (i = 0; i < 4; i++) { - // If we see (data == -1 && errno != 0), we know that the ptrace - // call failed, probably because we're dumping memory in an - // unmapped or inaccessible page. I don't know if there's - // value in making that explicit in the output -- it likely - // just complicates parsing and clarifies nothing for the - // enlightened reader. - long data = ptrace(PTRACE_PEEKTEXT, tid, reinterpret_cast<void*>(p), NULL); - sprintf(code_buffer + strlen(code_buffer), "%08lx ", data); - - // Enable the following code blob to dump ASCII values -#if 0 - int j; - for (j = 0; j < 4; j++) { - // Our isprint() allows high-ASCII characters that display - // differently (often badly) in different viewers, so we - // just use a simpler test. - char val = (data >> (j*8)) & 0xff; - if (val >= 0x20 && val < 0x7f) { - *asc_out++ = val; - } else { - *asc_out++ = '.'; - } - } -#endif - p += 4; - } - *asc_out = '\0'; - _LOG(log, scope_flags, " %s %s\n", code_buffer, ascii_buffer); - } -} - // If configured to do so, dump memory around *all* registers // for the crashing thread. void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) { diff --git a/debuggerd/mips/machine.cpp b/debuggerd/mips/machine.cpp index d1a7f2d..7b4e29e 100644 --- a/debuggerd/mips/machine.cpp +++ b/debuggerd/mips/machine.cpp @@ -34,61 +34,6 @@ #define R(x) (static_cast<unsigned int>(x)) -static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scope_flags) { - char code_buffer[64]; // actual 8+1+((8+1)*4) + 1 == 45 - char ascii_buffer[32]; // actual 16 + 1 == 17 - uintptr_t p, end; - - p = addr & ~3; - p -= 32; - if (p > addr) { - // catch underflow - p = 0; - } - end = p + 80; - // catch overflow; 'end - p' has to be multiples of 16 - while (end < p) - end -= 16; - - // Dump the code around PC as: - // addr contents ascii - // 00008d34 ef000000 e8bd0090 e1b00000 512fff1e ............../Q - // 00008d44 ea00b1f9 e92d0090 e3a070fc ef000000 ......-..p...... - while (p < end) { - char* asc_out = ascii_buffer; - - sprintf(code_buffer, "%08x ", p); - - int i; - for (i = 0; i < 4; i++) { - // If we see (data == -1 && errno != 0), we know that the ptrace - // call failed, probably because we're dumping memory in an - // unmapped or inaccessible page. I don't know if there's - // value in making that explicit in the output -- it likely - // just complicates parsing and clarifies nothing for the - // enlightened reader. - long data = ptrace(PTRACE_PEEKTEXT, tid, (void*)p, NULL); - sprintf(code_buffer + strlen(code_buffer), "%08lx ", data); - - int j; - for (j = 0; j < 4; j++) { - // Our isprint() allows high-ASCII characters that display - // differently (often badly) in different viewers, so we - // just use a simpler test. - char val = (data >> (j*8)) & 0xff; - if (val >= 0x20 && val < 0x7f) { - *asc_out++ = val; - } else { - *asc_out++ = '.'; - } - } - p += 4; - } - *asc_out = '\0'; - _LOG(log, scope_flags, " %s %s\n", code_buffer, ascii_buffer); - } -} - // If configured to do so, dump memory around *all* registers // for the crashing thread. void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) { diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp index 11e9af5..7bda5c5 100644 --- 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: @@ -675,7 +674,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 +695,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 +738,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; diff --git a/debuggerd/utility.cpp b/debuggerd/utility.cpp index 35f061e..100324a 100644 --- a/debuggerd/utility.cpp +++ b/debuggerd/utility.cpp @@ -127,3 +127,77 @@ void wait_for_stop(pid_t tid, int* total_sleep_time_usec) { *total_sleep_time_usec += sleep_time_usec; } } + +#if defined (__mips__) +#define DUMP_MEMORY_AS_ASCII 1 +#else +#define DUMP_MEMORY_AS_ASCII 0 +#endif + +void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scope_flags) { + char code_buffer[64]; + char ascii_buffer[32]; + uintptr_t p, end; + + p = addr & ~(sizeof(long) - 1); + /* Dump 32 bytes before addr */ + p -= 32; + if (p > addr) { + /* catch underflow */ + p = 0; + } + /* Dump 256 bytes */ + end = p + 256; + /* catch overflow; 'end - p' has to be multiples of 16 */ + while (end < p) { + end -= 16; + } + + /* Dump the code around PC as: + * addr contents ascii + * 0000000000008d34 ef000000e8bd0090 e1b00000512fff1e ............../Q + * 0000000000008d44 ea00b1f9e92d0090 e3a070fcef000000 ......-..p...... + * On 32-bit machines, there are still 16 bytes per line but addresses and + * words are of course presented differently. + */ + while (p < end) { + char* asc_out = ascii_buffer; + + int len = snprintf(code_buffer, sizeof(code_buffer), "%" PRIPTR " ", p); + + for (size_t i = 0; i < 16/sizeof(long); i++) { + long data = ptrace(PTRACE_PEEKTEXT, tid, (void*)p, NULL); + if (data == -1 && errno != 0) { + // ptrace failed, probably because we're dumping memory in an + // unmapped or inaccessible page. +#ifdef __LP64__ + len += sprintf(code_buffer + len, "---------------- "); +#else + len += sprintf(code_buffer + len, "-------- "); +#endif + } else { + len += sprintf(code_buffer + len, "%" PRIPTR " ", + static_cast<uintptr_t>(data)); + } + +#if DUMP_MEMORY_AS_ASCII + for (size_t j = 0; j < sizeof(long); j++) { + /* + * Our isprint() allows high-ASCII characters that display + * differently (often badly) in different viewers, so we + * just use a simpler test. + */ + char val = (data >> (j*8)) & 0xff; + if (val >= 0x20 && val < 0x7f) { + *asc_out++ = val; + } else { + *asc_out++ = '.'; + } + } +#endif + p += sizeof(long); + } + *asc_out = '\0'; + _LOG(log, scope_flags, " %s %s\n", code_buffer, ascii_buffer); + } +} diff --git a/debuggerd/utility.h b/debuggerd/utility.h index 1f006ed..232b7bc 100644 --- a/debuggerd/utility.h +++ b/debuggerd/utility.h @@ -18,8 +18,9 @@ #ifndef _DEBUGGERD_UTILITY_H #define _DEBUGGERD_UTILITY_H -#include <stddef.h> +#include <inttypes.h> #include <stdbool.h> +#include <stddef.h> typedef struct { /* tombstone file descriptor */ @@ -60,7 +61,17 @@ void _LOG(log_t* log, int scopeFlags, const char *fmt, ...) #define XLOG2(fmt...) do {} while(0) #endif +#if __LP64__ +#define PRIPTR "016" PRIxPTR +typedef uint64_t word_t; +#else +#define PRIPTR "08" PRIxPTR +typedef uint32_t word_t; +#endif + int wait_for_signal(pid_t tid, int* total_sleep_time_usec); void wait_for_stop(pid_t tid, int* total_sleep_time_usec); +void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scope_flags); + #endif // _DEBUGGERD_UTILITY_H |