如何阅读、理解、分析和调试 Linux 内核恐慌?

新手上路,请多包涵

考虑以下 Linux 内核转储堆栈跟踪;例如,您可以通过调用 panic("debugging a Linux kernel panic"); 从内核源代码触发恐慌:

 [<001360ac>] (unwind_backtrace+0x0/0xf8) from [<00147b7c>] (warn_slowpath_common+0x50/0x60)
[<00147b7c>] (warn_slowpath_common+0x50/0x60) from [<00147c40>] (warn_slowpath_null+0x1c/0x24)
[<00147c40>] (warn_slowpath_null+0x1c/0x24) from [<0014de44>] (local_bh_enable_ip+0xa0/0xac)
[<0014de44>] (local_bh_enable_ip+0xa0/0xac) from [<0019594c>] (bdi_register+0xec/0x150)

  • unwind_backtrace+0x0/0xf8+0x0/0xf8 代表什么?
  • 如何查看 unwind_backtrace+0x0/0xf8 的 C 代码?
  • 如何解读恐慌的内容?

原文由 0x90 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

这只是一个普通的回溯,这些函数以相反的顺序调用(第一个调用被前一个调用,依此类推):

 unwind_backtrace+0x0/0xf8
warn_slowpath_common+0x50/0x60
warn_slowpath_null+0x1c/0x24
ocal_bh_enable_ip+0xa0/0xac
bdi_register+0xec/0x150

bdi_register+0xec/0x150 是符号 + 偏移量/长度,在 Understanding a Kernel Oops 以及如何调试内核oops 中有更多信息。还有这个关于 调试内核 的优秀教程

注意:正如 Eugene 下面的建议,您可能想先尝试 addr2line ,但它仍然需要带有调试符号的图像,例如

addr2line -e vmlinux_with_debug_info 0019594c(+offset)

原文由 iabdalkader 发布,翻译遵循 CC BY-SA 4.0 许可协议

这是 addr2line 的两种替代方案。假设您拥有正确的目标工具链,您可以执行以下操作之一:

使用 objdump

  1. 在内核根目录下找到您的 vmlinux.ko 文件,然后反汇编目标文件:
    objdump -dS vmlinux > /tmp/kernel.s

  1. 打开生成的程序集文件 /tmp/kernel.s 。使用文本编辑器,例如 vim 。转到 unwind_backtrace+0x0/0xf8 ,即搜索 unwind_backtrace 的地址+ offset 的地址。最后,您在源代码中找到了有问题的部分。

使用 gdb

IMO,一个更优雅的选择是使用唯一的 gdb 。假设您的主机上有合适的工具链:

  1. 运行 gdb <path-to-vmlinux>
  2. 在 gdb 的提示符下执行: list *(unwind_backtrace+0x10)

有关更多信息,您可以查看以下资源:

  1. 内核调试技巧
  2. 使用 Gdb 调试 Linux 内核

原文由 0x90 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题