Linux内核驱动调试经常遇到定位困难的问题,除了在代码之间添加log(printk/dev_info等)以外,还可以借助栈(stack)信息定位到代码。
dump_stack
现象
原因
内核打印栈信息的常见原因有:
- oops崩溃:常见问题有空指针、内存访问越界等
- dump_stack函数:需要头文件linux/kprobes.h和asm/traps.h
分析
oops信息
<1>[ 12.043486] Unable to handle kernel read from unreadable memory at virtual address 000003b8
显示内存访问越界
寄存器信息
<4>[ 12.043568] PC is at gpiochip_remove_pin_ranges+0x24/0xa0
<4>[ 12.043572] LR is at gpiochip_remove+0xc8/0x1b8
<4>[ 12.043596] pc : [<ffffff800864357c>] lr : [<ffffff8008646528>] pstate: 80400045
PC:程序计数器,指向要执行的下一条指令,异常返回oops。
LR:连接寄存器,子程序返回地址(有说法划分LR为过程连接寄存器PLR和异常连接寄存器ELR)
<4>[ 12.043605] sp : ffffffc0f126bb60
SP:栈指针寄存器,指向栈顶。
<4>[ 12.043626] x29: ffffffc0f126bb60 x28: ffffff8009abc910
<4>[ 12.043645] x27: ffffff80098fa1a8 x26: ffffff80098820e8
<4>[ 12.043656] x25: ffffff800a3f0000 x24: 0000000000000002
<4>[ 12.043666] x23: ffffff800a43f2c8 x22: 00000000000003b8
<4>[ 12.043682] x21: ffffffc0e9734