• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <cutils/logd.h>
2 #include <sys/ptrace.h>
3 #include "../utility.h"
4 #include "x86_utility.h"
5 
6 
unwind_backtrace_with_ptrace_x86(int tfd,pid_t pid,mapinfo * map,bool at_fault)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) {
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) {
34             _LOG(tfd, !at_fault, "    #%02d  eip: %08x  %s (%s)\n",
35                  stack_level, eip, mi ? mi->name : "", sym->name);
36         } else {
37             _LOG(tfd, !at_fault, "    #%02d  eip: %08x  %s\n",
38                  stack_level, eip, mi ? mi->name : "");
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) {
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) {
63                 _LOG(tfd, !at_fault, "    #%02d  %08x  %08x  %s (%s)\n",
64                      stack_level, stack_ptr, stack_content, mi ? mi->name : "", sym->name);
65             } else {
66                 _LOG(tfd, !at_fault, "    #%02d  %08x  %08x  %s\n",
67                      stack_level, stack_ptr, stack_content, mi ? mi->name : "");
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 
87