xv6, line by line
lab 2
Lab 22 A kernel backtrace on panic

Lab 2 · reveal · 16 steps · 8 commits

A kernel backtrace on panic: the reference solution

When this kernel panics it prints one line, such as panic: sched locks, and stops. The line names the check that failed, not the path that led to it. In this lab you add backtrace(), which prints the return address of every function on the current kernel call chain, and make panic call it. On the host, addr2line turns the addresses into file names and line numbers.

The walk itself is a five-line loop over the frame pointers the compiler already maintains. The interesting part is where the loop must stop, and that depends on which stack it is walking. A process’s kernel stack is one page, so its top is a page boundary. A hart’s scheduler stack is a 4096-byte slice of stack0, which is only 16-byte aligned, so its top is in the middle of a page, and its top 32 bytes hold two frames left over from boot. And when an interrupt arrives in the middle of a call chain, kernelvec pushes a 256-byte kernelvec frame that the walk has to step across. You will see all three, in real output from three harts, and you will see what goes wrong, in recorded runs, when the walk does not stop where it should.

Each step shows one change on the branch ext/02-backtrace, the code around it, and the state of the machine when that code runs.

The route
  1. 1One instruction to read s0 kernel/riscv.h
  2. 2The record every prologue writes Makefile
  3. 3Walking the chain kernel/printk.c
  4. 4The outermost record belongs to uservec kernel/trampoline.S
  5. 5A system call to try it kernel/sysproc.c
  6. 6Reading the lines back with addr2line kernel/syscall.c
  7. 7Asking the timer for a backtrace kernel/sysproc.c
  8. 8kernelvec pushes a frame, but no record kernel/kernelvec.S
  9. 9kerneltrap takes the request kernel/trap.c
  10. 10stack0, sixteen-byte aligned kernel/entry.S
  11. 11stacktop knows both kinds kernel/printk.c
  12. 12Exactly one idle hart prints kernel/trap.c
  13. 13The requester sleeps until the print is done kernel/sysproc.c
  14. 14A fossil at the top of every scheduler stack kernel/start.c
  15. 15panic prints the chain kernel/printk.c
  16. 16bttest user/bttest.c

Keys: ← → step · Home start