如何充分利用堆栈跟踪(来自内核或核心转储)?

Sha*_*baz 18 c gcc stack-trace

如果你的内核模块崩溃,你很幸运,你会得到一个带有大量信息的日志,例如寄存器中的值等.一个这样的信息是堆栈跟踪(核心转储也是如此,但我最初问这个内核模块).举个例子:

[<f97ade02>] ? skink_free_devices+0x32/0xb0 [skin_kernel]
[<f97aba45>] ? cleanup_module+0x1e5/0x550 [skin_kernel]
[<c017d0e7>] ? __stop_machine+0x57/0x70
[<c016dec0>] ? __try_stop_module+0x0/0x30
[<c016f069>] ? sys_delete_module+0x149/0x210
[<c0102f24>] ? sysenter_do_call+0x12/0x16
Run Code Online (Sandbox Code Playgroud)

我的猜测是,+<number1>/<number2>它与发生错误的函数的偏移量有关.也就是说,通过检查这个数字,或许可以查看汇编输出,我应该能够找到发生此错误的行(更好的是,指令).那是对的吗?

我的问题是,这两个数字究竟是什么?你如何利用它们?

Pav*_*ath 19

skink_free_devices+0x32/0xb0
Run Code Online (Sandbox Code Playgroud)

这意味着违规指令是0x32从函数开始的字节,总共skink_free_devices()0xB0字节长.

如果您使用-genabled 编译内核,那么您可以使用该工具addr2line或我们的旧版本获取控件跳转的函数内的行号gdb

像这样的东西

$ addr2line -e ./vmlinux 0xc01cf0d1
/mnt/linux-2.5.26/include/asm/bitops.h:244
or
$ gdb ./vmlinux
...
(gdb) l *0xc01cf0d1
0xc01cf0d1 is in read_chan (include/asm/bitops.h:244).
(...)
244     return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
(...)
Run Code Online (Sandbox Code Playgroud)

因此,只需提供您要检查的地址,addr2line或者gdb他们将告诉您源文件中存在违规功能的行号.有关详细信息,请参阅文章

编辑: vmlinux是用于调试的内核的未压缩版本,通常可以找到@,/lib/modules/$(uname -r)/build/vmlinux前提是您已经从源代码构建了内核.vmlinuz您找到的/boot是压缩内核,在调试时可能没那么有用