繁体   English   中英

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

[英]How to read, understand, analyze, and debug a Linux kernel panic?

考虑以下 Linux 内核转储堆栈跟踪,您可以通过调用panic("debugging a Linux kernel panic");从内核源代码中触发一个恐慌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 代码?
  • 如何解读恐慌的内容?

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

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是符号 + 偏移量/长度,在了解内核 Oops以及如何调试内核 oops 中有更多信息。 还有这个关于调试内核的优秀教程

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

addr2line -e vmlinux_with_debug_info 0019594c(+offset)

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

使用objdump

  1. 在内核根目录下找到您的vmlinux.ko文件,然后反汇编目标文件:

     objdump -dS vmlinux > /tmp/kernel.s
  2. 打开生成的程序集文件/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 内核

unwind_backtrace+0x0/0xf8+0x0/0xf8代表什么?

第一个数字 ( +0x0 ) 是距函数开头偏移量(在本例中为unwind_backtrace )。 第二个数字 ( 0xf8 ) 是函数总长度 鉴于这两条信息,如果您已经对故障发生的位置有预感,这可能足以证实您的怀疑(您可以(大致)知道您的功能有多远)。

要获得相应指令的确切源代码行(通常比addr2line更好),请使用addr2line或其他答案中的其他方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM