示例 · xv6 中断后栈错乱
这是一条按模板写好的真实风格示例。你的每条踩坑记录都长这样。
现象
跑 xv6 的 lab 时,开启时钟中断后偶发 panic,栈回溯(backtrace)显示返回地址是一串明显非法的值。
环境 / 触发条件
- xv6-riscv,QEMU 7.x
- 只在开启多核(
CPUS=2以上)时出现,单核复现不了 - 大约每 20 次启动触发 1 次,非必现
走过的弯路
- 一开始怀疑是自己改的调度器逻辑,回滚后仍复现 —— 排除。
- 以为是 QEMU 版本问题,换版本无效 —— 排除。
- 这些弯路本身值得记,免得下次又走一遍。
根因
中断处理入口没有正确切换到内核栈,在用户栈上继续压栈,遇到特定时序就踩到非法区域。本质是保存上下文的时机问题。
解法
在 trap 入口最早处先完成栈切换再做其它保存。关键改动:
sscratch里事先放好了内核栈指针,csrrw一条指令完成交换,避免在用户栈上多做任何动作。
一句话教训
中断/异常入口,换栈要趁早——任何在切换前发生的压栈都可能踩到不该碰的地方。