Loading debuggerd/arm/machine.c +103 −54 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ #include "utility.h" /* enable to dump memory pointed to by every register */ #define DUMP_MEM_FOR_ALL_REGS 0 #ifdef WITH_VFP #ifdef WITH_VFP_D32 #define NUM_VFP_REGS 32 Loading Loading @@ -117,82 +120,128 @@ static void show_nearby_maps(int tfd, int pid, mapinfo *map) } } void dump_stack_and_code(int tfd, int pid, mapinfo *map, int unwind_depth, unsigned int sp_list[], bool at_fault) /* * Dumps a few bytes of memory, starting a bit before and ending a bit * after the specified address. */ static void dump_memory(int tfd, int pid, uintptr_t addr, bool only_in_tombstone) { unsigned int sp, pc, lr, p, end, data; struct pt_regs r; int sp_depth; bool only_in_tombstone = !at_fault; char code_buffer[80]; if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return; sp = r.ARM_sp; pc = r.ARM_pc; lr = r.ARM_lr; _LOG(tfd, only_in_tombstone, "\ncode around pc:\n"); 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 = pc & ~3; p = addr & ~3; p -= 32; if (p > pc) if (p > addr) { /* catch underflow */ p = 0; } end = p + 80; /* 'end - p' has to be multiples of 16 */ /* catch overflow; 'end - p' has to be multiples of 16 */ while (end < p) end -= 16; /* Dump the code around PC as: * addr contents * 00008d34 fffffcd0 4c0eb530 b0934a0e 1c05447c * 00008d44 f7ff18a0 490ced94 68035860 d0012b00 * addr contents ascii * 00008d34 ef000000 e8bd0090 e1b00000 512fff1e ............../Q * 00008d44 ea00b1f9 e92d0090 e3a070fc ef000000 ......-..p...... */ while (p < end) { int i; char* asc_out = ascii_buffer; sprintf(code_buffer, "%08x ", p); int i; for (i = 0; i < 4; i++) { data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); sprintf(code_buffer + strlen(code_buffer), "%08x ", data); /* * 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, pid, (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; } _LOG(tfd, only_in_tombstone, "%s\n", code_buffer); *asc_out = '\0'; _LOG(tfd, only_in_tombstone, "%s %s\n", code_buffer, ascii_buffer); } if (lr != pc) { _LOG(tfd, only_in_tombstone, "\ncode around lr:\n"); } p = lr & ~3; p -= 32; if (p > lr) p = 0; end = p + 80; /* 'end - p' has to be multiples of 16 */ while (end < p) end -= 16; void dump_stack_and_code(int tfd, int pid, mapinfo *map, int unwind_depth, unsigned int sp_list[], bool at_fault) { struct pt_regs r; int sp_depth; bool only_in_tombstone = !at_fault; if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return; /* Dump the code around LR as: * addr contents * 00008d34 fffffcd0 4c0eb530 b0934a0e 1c05447c * 00008d44 f7ff18a0 490ced94 68035860 d0012b00 if (DUMP_MEM_FOR_ALL_REGS && at_fault) { /* * If configured to do so, dump memory around *all* registers * for the crashing thread. * * TODO: remove duplicates. */ while (p < end) { int i; static const char REG_NAMES[] = "R0R1R2R3R4R5R6R7R8R9SLFPIPSPLRPC"; sprintf(code_buffer, "%08x ", p); for (i = 0; i < 4; i++) { data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); sprintf(code_buffer + strlen(code_buffer), "%08x ", data); p += 4; int reg; for (reg = 0; reg < 16; reg++) { /* this may not be a valid way to access, but it'll do for now */ uintptr_t addr = r.uregs[reg]; /* * Don't bother if it looks like a small int or ~= null, or if * it's in the kernel area. */ if (addr < 4096 || addr >= 0xc0000000) { continue; } _LOG(tfd, only_in_tombstone, "\nmem near %.2s:\n", ®_NAMES[reg*2]); dump_memory(tfd, pid, addr, false); } _LOG(tfd, only_in_tombstone, "%s\n", code_buffer); } else { unsigned int pc, lr; pc = r.ARM_pc; lr = r.ARM_lr; _LOG(tfd, only_in_tombstone, "\ncode around pc:\n"); dump_memory(tfd, pid, (uintptr_t) pc, only_in_tombstone); if (lr != pc) { _LOG(tfd, only_in_tombstone, "\ncode around lr:\n"); dump_memory(tfd, pid, (uintptr_t) lr, only_in_tombstone); } } show_nearby_maps(tfd, pid, map); unsigned int p, end; unsigned int sp = r.ARM_sp; p = sp - 64; if (p > sp) p = 0; Loading Loading @@ -227,7 +276,7 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map, while (p <= end) { char *prompt; char level[16]; data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); long data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); if (p == sp_list[sp_depth]) { sprintf(level, "#%02d", sp_depth++); prompt = level; Loading @@ -252,7 +301,7 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map, end = ~7; while (p <= end) { data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); long data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); _LOG(tfd, (sp_depth > 2) || only_in_tombstone, " %08x %08x %s\n", p, data, map_to_name(map, data, "")); Loading Loading
debuggerd/arm/machine.c +103 −54 Original line number Diff line number Diff line Loading @@ -36,6 +36,9 @@ #include "utility.h" /* enable to dump memory pointed to by every register */ #define DUMP_MEM_FOR_ALL_REGS 0 #ifdef WITH_VFP #ifdef WITH_VFP_D32 #define NUM_VFP_REGS 32 Loading Loading @@ -117,82 +120,128 @@ static void show_nearby_maps(int tfd, int pid, mapinfo *map) } } void dump_stack_and_code(int tfd, int pid, mapinfo *map, int unwind_depth, unsigned int sp_list[], bool at_fault) /* * Dumps a few bytes of memory, starting a bit before and ending a bit * after the specified address. */ static void dump_memory(int tfd, int pid, uintptr_t addr, bool only_in_tombstone) { unsigned int sp, pc, lr, p, end, data; struct pt_regs r; int sp_depth; bool only_in_tombstone = !at_fault; char code_buffer[80]; if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return; sp = r.ARM_sp; pc = r.ARM_pc; lr = r.ARM_lr; _LOG(tfd, only_in_tombstone, "\ncode around pc:\n"); 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 = pc & ~3; p = addr & ~3; p -= 32; if (p > pc) if (p > addr) { /* catch underflow */ p = 0; } end = p + 80; /* 'end - p' has to be multiples of 16 */ /* catch overflow; 'end - p' has to be multiples of 16 */ while (end < p) end -= 16; /* Dump the code around PC as: * addr contents * 00008d34 fffffcd0 4c0eb530 b0934a0e 1c05447c * 00008d44 f7ff18a0 490ced94 68035860 d0012b00 * addr contents ascii * 00008d34 ef000000 e8bd0090 e1b00000 512fff1e ............../Q * 00008d44 ea00b1f9 e92d0090 e3a070fc ef000000 ......-..p...... */ while (p < end) { int i; char* asc_out = ascii_buffer; sprintf(code_buffer, "%08x ", p); int i; for (i = 0; i < 4; i++) { data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); sprintf(code_buffer + strlen(code_buffer), "%08x ", data); /* * 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, pid, (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; } _LOG(tfd, only_in_tombstone, "%s\n", code_buffer); *asc_out = '\0'; _LOG(tfd, only_in_tombstone, "%s %s\n", code_buffer, ascii_buffer); } if (lr != pc) { _LOG(tfd, only_in_tombstone, "\ncode around lr:\n"); } p = lr & ~3; p -= 32; if (p > lr) p = 0; end = p + 80; /* 'end - p' has to be multiples of 16 */ while (end < p) end -= 16; void dump_stack_and_code(int tfd, int pid, mapinfo *map, int unwind_depth, unsigned int sp_list[], bool at_fault) { struct pt_regs r; int sp_depth; bool only_in_tombstone = !at_fault; if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return; /* Dump the code around LR as: * addr contents * 00008d34 fffffcd0 4c0eb530 b0934a0e 1c05447c * 00008d44 f7ff18a0 490ced94 68035860 d0012b00 if (DUMP_MEM_FOR_ALL_REGS && at_fault) { /* * If configured to do so, dump memory around *all* registers * for the crashing thread. * * TODO: remove duplicates. */ while (p < end) { int i; static const char REG_NAMES[] = "R0R1R2R3R4R5R6R7R8R9SLFPIPSPLRPC"; sprintf(code_buffer, "%08x ", p); for (i = 0; i < 4; i++) { data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); sprintf(code_buffer + strlen(code_buffer), "%08x ", data); p += 4; int reg; for (reg = 0; reg < 16; reg++) { /* this may not be a valid way to access, but it'll do for now */ uintptr_t addr = r.uregs[reg]; /* * Don't bother if it looks like a small int or ~= null, or if * it's in the kernel area. */ if (addr < 4096 || addr >= 0xc0000000) { continue; } _LOG(tfd, only_in_tombstone, "\nmem near %.2s:\n", ®_NAMES[reg*2]); dump_memory(tfd, pid, addr, false); } _LOG(tfd, only_in_tombstone, "%s\n", code_buffer); } else { unsigned int pc, lr; pc = r.ARM_pc; lr = r.ARM_lr; _LOG(tfd, only_in_tombstone, "\ncode around pc:\n"); dump_memory(tfd, pid, (uintptr_t) pc, only_in_tombstone); if (lr != pc) { _LOG(tfd, only_in_tombstone, "\ncode around lr:\n"); dump_memory(tfd, pid, (uintptr_t) lr, only_in_tombstone); } } show_nearby_maps(tfd, pid, map); unsigned int p, end; unsigned int sp = r.ARM_sp; p = sp - 64; if (p > sp) p = 0; Loading Loading @@ -227,7 +276,7 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map, while (p <= end) { char *prompt; char level[16]; data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); long data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); if (p == sp_list[sp_depth]) { sprintf(level, "#%02d", sp_depth++); prompt = level; Loading @@ -252,7 +301,7 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map, end = ~7; while (p <= end) { data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); long data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); _LOG(tfd, (sp_depth > 2) || only_in_tombstone, " %08x %08x %s\n", p, data, map_to_name(map, data, "")); Loading