Loading debuggerd/arm/machine.cpp +0 −59 Original line number Diff line number Diff line Loading @@ -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) { Loading debuggerd/mips/machine.cpp +0 −55 Original line number Diff line number Diff line Loading @@ -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) { Loading debuggerd/tombstone.cpp +18 −14 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading @@ -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" Loading @@ -60,7 +60,6 @@ typeof(y) __dummy2; \ (void)(&__dummy1 == &__dummy2); } static bool signal_has_address(int sig) { switch (sig) { case SIGILL: Loading Loading @@ -669,7 +668,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) { Loading @@ -690,7 +689,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)); Loading Loading @@ -733,8 +732,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; Loading debuggerd/utility.cpp +74 −0 Original line number Diff line number Diff line Loading @@ -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); } } debuggerd/utility.h +12 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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 Loading
debuggerd/arm/machine.cpp +0 −59 Original line number Diff line number Diff line Loading @@ -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) { Loading
debuggerd/mips/machine.cpp +0 −55 Original line number Diff line number Diff line Loading @@ -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) { Loading
debuggerd/tombstone.cpp +18 −14 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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> Loading @@ -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" Loading @@ -60,7 +60,6 @@ typeof(y) __dummy2; \ (void)(&__dummy1 == &__dummy2); } static bool signal_has_address(int sig) { switch (sig) { case SIGILL: Loading Loading @@ -669,7 +668,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) { Loading @@ -690,7 +689,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)); Loading Loading @@ -733,8 +732,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; Loading
debuggerd/utility.cpp +74 −0 Original line number Diff line number Diff line Loading @@ -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); } }
debuggerd/utility.h +12 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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