addr2line 和 gdb 定位内核模块 Oops 源码行

发布时间:2026/7/12 2:40:46

addr2line 和 gdb 定位内核模块 Oops 源码行 内核模块崩溃后dmesg 里经常看到类似这样的回溯[ 123.456] EIP: [f8a01234] xxx_main0x1a2a/0x2000 [xxx]拿到符号加偏移xxx_main0x1a2a就能直接映射到 C 源码行。前提是模块编译时带了调试信息-g或内核开了CONFIG_DEBUG_INFO且.ko文件没有被strip。1. addr2line最快addr2line-e./xxx.ko xxx_main0x1a2a输出/path/to/source.c:123如果模块代码移动了位置加-f可同时打印函数名addr2line-f-e./xxx.ko xxx_main0x1a2a2. gdb直接看上下文gdb ./xxx.ko(gdb)list *xxx_main0x1a2agdb 会列出崩溃行附近的源代码。如果源码路径不对用directory命令指向正确目录。也可以只精确显示一行(gdb) info line *xxx_main0x1a2a3. 用 objdump 做源码级反汇编备用这个方法要手动计算绝对地址一般不优先用但适合想看清到底哪条指令炸了。先找函数在.ko中的段内偏移objdump-txxx.ko|grep xxx_main$00000500 g F .text 00001000 xxx_main# 示例计算目标地址 0x500 0x1a2a 0x1f2a然后反汇编并穿插源码objdump-d-S--start-address0x1f2a xxx.ko注意事项如果崩溃日志只给了绝对地址如0xf8a01234而没给符号偏移先拿到模块加载基址再算偏移偏移 绝对地址 - 模块基址。然后用addr2line -e xxx.ko 偏移不可行因为.ko是重定位文件地址从 0 起算。此时仍建议用 gdbgdb ./xxx.ko后info symbol 偏移能还原出函数和偏移再用上面的方法定位行。务必保留编译时的.ko文件且不能strip。如果用modpost等工具处理过调试信息可能已丢失。对vmlinux同样适用文件替换即可。

相关新闻