blob: 0a7f04c88e102cf1d8fbe7f7f142746b0bee32a6 [file] [log] [blame]
Bruce Beare6cc49232010-10-13 16:11:15 -07001#include <cutils/logd.h>
2#include <sys/ptrace.h>
3#include "../utility.h"
4#include "x86_utility.h"
5
6
7int 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 Beare6cc49232010-10-13 16:11:15 -070027 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 Chtchetkine714d9de2011-06-07 09:24:03 -070034 _LOG(tfd, !at_fault, " #%02d eip: %08x %s (%s)\n",
35 stack_level, eip, mi ? mi->name : "", sym->name);
Bruce Beare6cc49232010-10-13 16:11:15 -070036 } else {
Vladimir Chtchetkine714d9de2011-06-07 09:24:03 -070037 _LOG(tfd, !at_fault, " #%02d eip: %08x %s\n",
38 stack_level, eip, mi ? mi->name : "");
Bruce Beare6cc49232010-10-13 16:11:15 -070039 }
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 Beare6cc49232010-10-13 16:11:15 -070053 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 Chtchetkine714d9de2011-06-07 09:24:03 -070063 _LOG(tfd, !at_fault, " #%02d %08x %08x %s (%s)\n",
64 stack_level, stack_ptr, stack_content, mi ? mi->name : "", sym->name);
Bruce Beare6cc49232010-10-13 16:11:15 -070065 } else {
Vladimir Chtchetkine714d9de2011-06-07 09:24:03 -070066 _LOG(tfd, !at_fault, " #%02d %08x %08x %s\n",
67 stack_level, stack_ptr, stack_content, mi ? mi->name : "");
Bruce Beare6cc49232010-10-13 16:11:15 -070068 }
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