summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debuggerd/arm/machine.cpp59
-rw-r--r--debuggerd/mips/machine.cpp55
-rw-r--r--debuggerd/tombstone.cpp32
-rw-r--r--debuggerd/utility.cpp74
-rw-r--r--debuggerd/utility.h13
5 files changed, 104 insertions, 129 deletions
diff --git a/debuggerd/arm/machine.cpp b/debuggerd/arm/machine.cpp
index 3fba6dbff..fd2f69b60 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 d1a7f2d3c..7b4e29e46 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 11e9af5ef..7bda5c5cd 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 35f061e70..100324abd 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 1f006ed5d..232b7bcad 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