| Bruce Beare | 6cc4923 | 2010-10-13 16:11:15 -0700 | [diff] [blame] | 1 | #include <cutils/logd.h> | 
|  | 2 | #include <sys/ptrace.h> | 
|  | 3 | #include "../utility.h" | 
|  | 4 | #include "x86_utility.h" | 
|  | 5 |  | 
|  | 6 |  | 
|  | 7 | int unwind_backtrace_with_ptrace_x86(int tfd, pid_t pid, mapinfo *map, | 
|  | 8 | bool at_fault) | 
|  | 9 | { | 
|  | 10 | struct pt_regs_x86 r; | 
|  | 11 | unsigned int stack_level = 0; | 
|  | 12 | unsigned int stack_depth = 0; | 
|  | 13 | unsigned int rel_pc; | 
|  | 14 | unsigned int stack_ptr; | 
|  | 15 | unsigned int stack_content; | 
|  | 16 |  | 
|  | 17 | if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return 0; | 
|  | 18 | unsigned int eip = (unsigned int)r.eip; | 
|  | 19 | unsigned int ebp = (unsigned int)r.ebp; | 
|  | 20 | unsigned int cur_sp = (unsigned int)r.esp; | 
|  | 21 | const mapinfo *mi; | 
|  | 22 | const struct symbol* sym = 0; | 
|  | 23 |  | 
|  | 24 |  | 
|  | 25 | //ebp==0, it indicates that the stack is poped to the bottom or there is no stack at all. | 
|  | 26 | while (ebp) { | 
| Bruce Beare | 6cc4923 | 2010-10-13 16:11:15 -0700 | [diff] [blame] | 27 | mi = pc_to_mapinfo(map, eip, &rel_pc); | 
|  | 28 |  | 
|  | 29 | /* See if we can determine what symbol this stack frame resides in */ | 
|  | 30 | if (mi != 0 && mi->symbols != 0) { | 
|  | 31 | sym = symbol_table_lookup(mi->symbols, rel_pc); | 
|  | 32 | } | 
|  | 33 | if (sym) { | 
| Vladimir Chtchetkine | 714d9de | 2011-06-07 09:24:03 -0700 | [diff] [blame] | 34 | _LOG(tfd, !at_fault, "    #%02d  eip: %08x  %s (%s)\n", | 
|  | 35 | stack_level, eip, mi ? mi->name : "", sym->name); | 
| Bruce Beare | 6cc4923 | 2010-10-13 16:11:15 -0700 | [diff] [blame] | 36 | } else { | 
| Vladimir Chtchetkine | 714d9de | 2011-06-07 09:24:03 -0700 | [diff] [blame] | 37 | _LOG(tfd, !at_fault, "    #%02d  eip: %08x  %s\n", | 
|  | 38 | stack_level, eip, mi ? mi->name : ""); | 
| Bruce Beare | 6cc4923 | 2010-10-13 16:11:15 -0700 | [diff] [blame] | 39 | } | 
|  | 40 |  | 
|  | 41 | stack_level++; | 
|  | 42 | if (stack_level >= STACK_DEPTH || eip == 0) | 
|  | 43 | break; | 
|  | 44 | eip = ptrace(PTRACE_PEEKTEXT, pid, (void*)(ebp + 4), NULL); | 
|  | 45 | ebp = ptrace(PTRACE_PEEKTEXT, pid, (void*)ebp, NULL); | 
|  | 46 | } | 
|  | 47 | ebp = (unsigned int)r.ebp; | 
|  | 48 | stack_depth = stack_level; | 
|  | 49 | stack_level = 0; | 
|  | 50 | if (ebp) | 
|  | 51 | _LOG(tfd, !at_fault, "stack: \n"); | 
|  | 52 | while (ebp) { | 
| Bruce Beare | 6cc4923 | 2010-10-13 16:11:15 -0700 | [diff] [blame] | 53 | stack_ptr = cur_sp; | 
|  | 54 | while((int)(ebp - stack_ptr) >= 0) { | 
|  | 55 | stack_content = ptrace(PTRACE_PEEKTEXT, pid, (void*)stack_ptr, NULL); | 
|  | 56 | mi = pc_to_mapinfo(map, stack_content, &rel_pc); | 
|  | 57 |  | 
|  | 58 | /* See if we can determine what symbol this stack frame resides in */ | 
|  | 59 | if (mi != 0 && mi->symbols != 0) { | 
|  | 60 | sym = symbol_table_lookup(mi->symbols, rel_pc); | 
|  | 61 | } | 
|  | 62 | if (sym) { | 
| Vladimir Chtchetkine | 714d9de | 2011-06-07 09:24:03 -0700 | [diff] [blame] | 63 | _LOG(tfd, !at_fault, "    #%02d  %08x  %08x  %s (%s)\n", | 
|  | 64 | stack_level, stack_ptr, stack_content, mi ? mi->name : "", sym->name); | 
| Bruce Beare | 6cc4923 | 2010-10-13 16:11:15 -0700 | [diff] [blame] | 65 | } else { | 
| Vladimir Chtchetkine | 714d9de | 2011-06-07 09:24:03 -0700 | [diff] [blame] | 66 | _LOG(tfd, !at_fault, "    #%02d  %08x  %08x  %s\n", | 
|  | 67 | stack_level, stack_ptr, stack_content, mi ? mi->name : ""); | 
| Bruce Beare | 6cc4923 | 2010-10-13 16:11:15 -0700 | [diff] [blame] | 68 | } | 
|  | 69 |  | 
|  | 70 | stack_ptr = stack_ptr + 4; | 
|  | 71 | //the stack frame may be very deep. | 
|  | 72 | if((int)(stack_ptr - cur_sp) >= STACK_FRAME_DEPTH) { | 
|  | 73 | _LOG(tfd, !at_fault, "    ......  ......  \n"); | 
|  | 74 | break; | 
|  | 75 | } | 
|  | 76 | } | 
|  | 77 | cur_sp = ebp + 4; | 
|  | 78 | stack_level++; | 
|  | 79 | if (stack_level >= STACK_DEPTH || stack_level >= stack_depth) | 
|  | 80 | break; | 
|  | 81 | ebp = ptrace(PTRACE_PEEKTEXT, pid, (void*)ebp, NULL); | 
|  | 82 | } | 
|  | 83 |  | 
|  | 84 | return stack_depth; | 
|  | 85 | } | 
|  | 86 |  |