oops 概念
Linux内核在发生kernel panic时会打印出Oops信息,把目前的寄存器状态、堆栈内容、以及完整的Call trace都show给我们看,这样就可以帮助我们定位错误
Oops如何产生的解释如下:由于处理器使用的地址几乎都是虚拟地址,这些地址通过一个被称为“页表”的结构被映射为物理地址。当引入一个非法指针的时候,分页机制无法将该地址映射到物理地址,此时处理器就会向操作系统发出一个“页面失效(page fault)”的信号。如果地址非法“换入(page in)”缺失页面;这时,如果处理器恰好处于超级用户模式,系统就会产生一个Oops。
oops示例图
oops源码路径为
源码路径: \kernel\panic.c
oops分析
开始为Unable to handle kernel paging request at virtual address ffffffdffffffceo
CPU:0 代表 发生错误时为CPU0
PID: 447 代表447进程发生了错误
Comm: 代表发生错误的进程名,为top
Modules linked in 内核中加载的模块名称
5.10.4-tag- #4为内核版本
这段为riscv的寄存器,arm版本请参考其他图片
从epc开始为发生错误时候dump出来的寄存器
epc为发生错误时候的PC值,对应为ffffffe0002cf05e 查询vmlinux以及其他程序可知,该段为linux内核elf档案加载地址,反汇编可以查到对应为refcount_inc函数
排查时候可以将对应的a0,a1,a2代入汇编中对应代码
栈信息
栈回溯信息,可以从中看出函数调用关系
要看函数发生错误的具体位置 需要用
objdump反汇编查找fffffe0002cf05e 对应的位置上
或者用addr2line也可以排查
没有打开KALLSYMS下怎么调试
首先cat /proc/modules 查看模块的加载地址位置
从而判断其在哪个模块上,再将对应的ko或者vmlinux进行反汇编 使用addr2line排查