87 lines
2.9 KiB
C
87 lines
2.9 KiB
C
#include <cutils/logd.h>
|
|
#include <sys/ptrace.h>
|
|
#include "../utility.h"
|
|
#include "x86_utility.h"
|
|
|
|
|
|
int unwind_backtrace_with_ptrace_x86(int tfd, pid_t pid, mapinfo *map,
|
|
bool at_fault)
|
|
{
|
|
struct pt_regs_x86 r;
|
|
unsigned int stack_level = 0;
|
|
unsigned int stack_depth = 0;
|
|
unsigned int rel_pc;
|
|
unsigned int stack_ptr;
|
|
unsigned int stack_content;
|
|
|
|
if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return 0;
|
|
unsigned int eip = (unsigned int)r.eip;
|
|
unsigned int ebp = (unsigned int)r.ebp;
|
|
unsigned int cur_sp = (unsigned int)r.esp;
|
|
const mapinfo *mi;
|
|
const struct symbol* sym = 0;
|
|
|
|
|
|
//ebp==0, it indicates that the stack is poped to the bottom or there is no stack at all.
|
|
while (ebp) {
|
|
mi = pc_to_mapinfo(map, eip, &rel_pc);
|
|
|
|
/* See if we can determine what symbol this stack frame resides in */
|
|
if (mi != 0 && mi->symbols != 0) {
|
|
sym = symbol_table_lookup(mi->symbols, rel_pc);
|
|
}
|
|
if (sym) {
|
|
_LOG(tfd, !at_fault, " #%02d eip: %08x %s (%s)\n",
|
|
stack_level, eip, mi ? mi->name : "", sym->name);
|
|
} else {
|
|
_LOG(tfd, !at_fault, " #%02d eip: %08x %s\n",
|
|
stack_level, eip, mi ? mi->name : "");
|
|
}
|
|
|
|
stack_level++;
|
|
if (stack_level >= STACK_DEPTH || eip == 0)
|
|
break;
|
|
eip = ptrace(PTRACE_PEEKTEXT, pid, (void*)(ebp + 4), NULL);
|
|
ebp = ptrace(PTRACE_PEEKTEXT, pid, (void*)ebp, NULL);
|
|
}
|
|
ebp = (unsigned int)r.ebp;
|
|
stack_depth = stack_level;
|
|
stack_level = 0;
|
|
if (ebp)
|
|
_LOG(tfd, !at_fault, "stack: \n");
|
|
while (ebp) {
|
|
stack_ptr = cur_sp;
|
|
while((int)(ebp - stack_ptr) >= 0) {
|
|
stack_content = ptrace(PTRACE_PEEKTEXT, pid, (void*)stack_ptr, NULL);
|
|
mi = pc_to_mapinfo(map, stack_content, &rel_pc);
|
|
|
|
/* See if we can determine what symbol this stack frame resides in */
|
|
if (mi != 0 && mi->symbols != 0) {
|
|
sym = symbol_table_lookup(mi->symbols, rel_pc);
|
|
}
|
|
if (sym) {
|
|
_LOG(tfd, !at_fault, " #%02d %08x %08x %s (%s)\n",
|
|
stack_level, stack_ptr, stack_content, mi ? mi->name : "", sym->name);
|
|
} else {
|
|
_LOG(tfd, !at_fault, " #%02d %08x %08x %s\n",
|
|
stack_level, stack_ptr, stack_content, mi ? mi->name : "");
|
|
}
|
|
|
|
stack_ptr = stack_ptr + 4;
|
|
//the stack frame may be very deep.
|
|
if((int)(stack_ptr - cur_sp) >= STACK_FRAME_DEPTH) {
|
|
_LOG(tfd, !at_fault, " ...... ...... \n");
|
|
break;
|
|
}
|
|
}
|
|
cur_sp = ebp + 4;
|
|
stack_level++;
|
|
if (stack_level >= STACK_DEPTH || stack_level >= stack_depth)
|
|
break;
|
|
ebp = ptrace(PTRACE_PEEKTEXT, pid, (void*)ebp, NULL);
|
|
}
|
|
|
|
return stack_depth;
|
|
}
|
|
|