【问题标题】:How to make good use of stack trace (from kernel or core dump)?如何充分利用堆栈跟踪(来自内核或核心转储)?
【发布时间】:2012-04-16 09:54:14
【问题描述】:

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

[<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

我的猜测是 +&lt;number1&gt;/&lt;number2&gt; 与发生错误的函数的偏移量有关。也就是说,通过检查这个数字,也许查看汇编输出,我应该能够找出发生此错误的行(更好的是指令)。对吗?

我的问题是,这两个数字到底是什么?您如何使用它们?

【问题讨论】:

    标签: c gcc stack-trace


    【解决方案1】:
    skink_free_devices+0x32/0xb0
    

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

    如果您在启用-g 的情况下编译内核,那么您可以使用工具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;
    (...)
    

    因此,只需将您要检查的地址提供给addr2linegdb,他们就会告诉您源文件中存在违规函数的行号 详情见this文章

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

    【讨论】:

    • 我不知道你可以 gdb linux 本身!这太棒了!
    • vmlinux 在哪里?我认为那将是 linux 内核本身(在 /boot 中),但那是 vmlinuz ... 和 addr2line 说“文件格式无法识别”不过没什么大不了的,因为我对自己的模块更感兴趣。
    • @Shahbaz vmlinuz 只是 vmlinux 的压缩和/或剥离版本。两者通常都在/boot 文件夹中。我现在没有带我的 linux 盒子来检查。谷歌周围的两个 :) 这里有一些首发。 OneTwo
    • @Shahbaz 在这里检查vmlinux 文件/lib/modules/$(uname -r)/build/vmlinux,前提是您已经从同一台机器上的源代码构建了内核。其他请参阅this 帖子,了解如何在 Ubuntu 上获取未压缩的内核
    • 太棒了!我编辑了我的答案以添加此信息,以便将来对其他人有所帮助
    【解决方案2】:

    对于 Emacs 用户,here's 是一种主要模式,可以在堆栈跟踪中轻松跳转(内部使用 addr2line)。

    免责声明:我写的:)

    【讨论】:

    【解决方案3】:

    反刍this answer你需要使用faddr2line

    就我而言,我有以下截断的呼叫跟踪:

    [  246.790938][   T35] Call trace:
    [  246.794075][   T35]  __switch_to+0x10c/0x180
    [  246.798348][   T35]  __schedule+0x278/0x6e0
    [  246.802531][   T35]  schedule+0x44/0xd0
    [  246.806368][   T35]  rpm_resume+0xf4/0x628
    [  246.810463][   T35]  __pm_runtime_resume+0x94/0xc0
    [  246.815257][   T35]  macb_open+0x30/0x2b8
    [  246.819265][   T35]  __dev_open+0x10c/0x188
    

    并在mainline linux kernel 中运行以下内容:

    ./scripts/faddr2line vmlinux macb_open+0x30/0x2b8
    

    给出输出

    macb_open+0x30/0x2b8:
    pm_runtime_get_sync at include/linux/pm_runtime.h:386
    (inlined by) macb_open at drivers/net/ethernet/cadence/macb_main.c:2726
    

    【讨论】:

      猜你喜欢
      • 2017-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-27
      相关资源
      最近更新 更多