调试小技巧记录

查看panic的调用栈

// kernel/printf.c
void backtrace() {
  uint64 fp = r_fp(); // 读取帧指针寄存器
  uint64 top = PGROUNDUP(fp);
  uint64 bottom = PGROUNDDOWN(fp);
  
  printf("backtrace:\n");
  while(fp < top && fp > bottom) {
    uint64 ra = *(uint64*)(fp - 8);  // 返回地址
    printf("  %p\n", ra);
    fp = *(uint64*)(fp - 16);       // 上一帧指针
  }
}

void
panic(char *s)
{
  pr.locking = 0;
  printf("panic: ");
  printf(s);
  printf("\n");
  //新增
  printf("\nStack trace:\n");
  backtrace();
  //新增结束
  panicked = 1; // freeze uart output from other CPUs
  for(;;)
    ;
}
// kernel/riscv.h
static inline uint64 r_fp() {
  uint64 x;
  asm volatile("mv %0, s0" : "=r" (x));
  return x;
}

当发生panic时,就会打印出调用栈函数的地址

backtrace:
  0x000000008000059e
  0x0000000080001234
  0x0000000080001a48
  0x0000000080002082
  0x0000000080002eac
  0x0000000080002e20
  0x0000000080002b0a

然后结束qemu,通过命令:
riscv64-unknown-elf-addr2line -e kernel/kernel 0x0000000080002b0a
就会打印出函数名和对应的行数

posted @ 2025-07-07 15:17  名字好难想zzz  阅读(9)  评论(0)    收藏  举报