show_stack
和 dump_stack
是内核调试的重要工具。
1,show_stack
函数分析
show_stack
函数用于打印当前进程或指定进程的内核态堆栈信息。其核心功能是回溯函数调用栈,并打印出每个函数的地址。
void show_stack(struct task_struct *task, unsigned long *sp, unsigned long pc)
{
unsigned long fp;
unsigned long *stack;
if (sp == NULL) {
if (task == NULL)
sp = (unsigned long *)current_thread_info();
else
sp = (unsigned long *)task->thread.sp;
}
fp = *sp;
stack = (unsigned long *)TASK_STACK;
while (fp >= (unsigned long)stack && fp < (unsigned long)stack + THREAD_SIZE) {
unsigned long lr = fp[1];
unsigned long ra = fp[2];
printk("fp: %08lx lr: %08lx ra: %08lx\n", fp, lr, ra);
fp = (unsigned long *)fp[0];
}
}
2,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;
printk("Backtrace: ");
if (!tsk) tsk = current;
if (regs) {
fp = regs->ARM_fp;
mode = processor_mode(regs);
} else {
asm("mov %0, fp" : "=r" (fp));
mode = 0x10;
}
if (fp) {
c_backtrace(fp, mode); // 调用汇编函数回溯栈
}
}