コード例 #1
0
static void print_backtrace(const intptr_t *bt, unsigned int depth)
{
    const mapinfo *mi;
    unsigned int cnt;
    unsigned int rel_pc;
    intptr_t self_bt[MAX_BACKTRACE_DEPTH];

    if (!bt) {
        depth = get_backtrace(self_bt, MAX_BACKTRACE_DEPTH);
        bt = self_bt;
    }

    log_message("*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
    for (cnt = 0; cnt < depth && cnt < MAX_BACKTRACE_DEPTH; cnt++) {
        mi = pc_to_mapinfo(milist, bt[cnt], &rel_pc);
        log_message("\t#%02d  pc %08x  %s\n", cnt,
                   mi ? (intptr_t)rel_pc : bt[cnt],
                   mi ? mi->name : "(unknown)");
    }
}
コード例 #2
0
/* routine to determine if a word value represents a return address
 * This routine checks to see if the word value points to an address that
 * immediately follows a branch instruction.
 */
int is_ARM_return_address(int pid, mapinfo *milist, unsigned int value)
{
	unsigned int addr;
	unsigned int data;
	unsigned int rel_addr;
	const mapinfo *mi;

	/* check 4 bytes before the address */
	addr = value-4;

	/* FIXTHIS - check map to see if this is in text segment */
	rel_addr = addr;
	mi = pc_to_mapinfo(milist, addr, &rel_addr);
	if (mi == NULL) {
		/* address is not in the executable memory map */
		/* note that the [stack] map is not executable,
 		 * and has already been filtered from the map list
 		*/
		return 0;
	}

	DLOG("checking addr=0x%08lx for instruction\n", addr);

	data = ptrace(PTRACE_PEEKTEXT, pid, (void*)addr, NULL);

	/* detect failure to read data from process memory */
	if (data==0xffffffff) {
		return 0;
	}

	DLOG("instruction at %08lx is %08lx\n", addr, data);

	if (is_ARM_bl(data)) {	
		DLOG("this instruction is a branch and link, with offset %d and target 0x%08x\n",
			branch_offset(data), branch_target(addr, data));
		return 1;
	} else {
		return 0;
	}
}
コード例 #3
0
ファイル: unwind.c プロジェクト: 28vicky/android_system_core
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;
}