dump_stack调用:
void dump_stack(void)
{ dump_backtrace(NULL, NULL);}继续看:
static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{ unsigned int fp, mode; int ok = 1; printk("Backtrace: "); if (!tsk) tsk = current; if (regs) { fp = regs->ARM_fp; mode = processor_mode(regs); } else if (tsk != current) { fp = thread_saved_fp(tsk); mode = 0x10; } else { asm("mov %0, fp" : "=r" (fp) : : "cc"); mode = 0x10; } if (!fp) { printk("no frame pointer"); ok = 0; } else if (verify_stack(fp)) { printk("invalid frame pointer 0x%08x", fp); ok = 0; } else if (fp < (unsigned long)end_of_stack(tsk)) printk("frame pointer underflow"); printk("\n"); if (ok) c_backtrace(fp, mode);}#endif我们搜索这个 c_backtrace 函数
在arch\arm\lib中 backtrace.S中
#include <linux/linkage.h>
#include <asm/assembler.h> .text@ fp is 0 or stack frame#define frame r4#define sv_fp r5#define sv_pc r6#define mask r7#define offset r8ENTRY(c_backtrace)。。。。
1003: ldr r2, [sv_pc, #-4] @ if stmfd sp!, {args} exists,
ldr r3, .Ldsi+4 @ adjust saved 'pc' back one teq r3, r2, lsr #10 @ instruction subne r0, sv_pc, #4 @ allow for mov subeq r0, sv_pc, #8 @ allow for mov + stmia ldr r1, [frame, #-4] @ get saved lr mov r2, frame bic r1, r1, mask @ mask PC/LR for the mode bl dump_backtrace_entry ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists, ldr r3, .Ldsi+4 teq r3, r1, lsr #10 ldreq r0, [frame, #-8] @ get sp subeq r0, r0, #4 @ point at the last arg bleq .Ldumpstm @ dump saved registers1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc}
再看这个函数 dump_backtrace_entry
void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
{ #ifdef CONFIG_KALLSYMS printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);#else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);#endif if (in_exception_text(where)) dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));}