diff options
author | Kévin PETIT <kevin.petit@arm.com> | 2013-12-18 16:44:24 +0000 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2014-01-30 15:55:33 -0800 |
commit | 4bb477205a2446c3ba9db8df0b0446173065d9eb (patch) | |
tree | 80007d072cccd7635b372d3d29fefac1a8c3e205 /debuggerd/utility.cpp | |
parent | caefe564a4b05e717a3baec155b8968ad36e58b6 (diff) | |
download | system_core-4bb477205a2446c3ba9db8df0b0446173065d9eb.zip system_core-4bb477205a2446c3ba9db8df0b0446173065d9eb.tar.gz system_core-4bb477205a2446c3ba9db8df0b0446173065d9eb.tar.bz2 |
debuggerd: a few generic improvements
This one makes dump_memory reasonably architecture-agnostic so it is
possible to share the code between architectures.
It also includes a few small improvements in tombstone.cpp.
Change-Id: Ib8a9599bfa420b41e80207988e87aee1b9d79541
Signed-off-by: Kévin PETIT <kevin.petit@arm.com>
Diffstat (limited to 'debuggerd/utility.cpp')
-rw-r--r-- | debuggerd/utility.cpp | 74 |
1 files changed, 74 insertions, 0 deletions
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); + } +} |