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

0x9*_*x90 41 c linux debugging linux-kernel panic

Consider the following linux kernel dump stack trace, you can trigger a panic from the kernel source code by calling 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)
Run Code Online (Sandbox Code Playgroud)
  • In unwind_backtrace+0x0/0xf8 what the +0x0/0xf8 stands for?
  • How can I see the C code of unwind_backtrace+0x0/0xf8?
  • How to interpret the panic's content?

iab*_*der 44

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

unwind_backtrace+0x0/0xf8
warn_slowpath_common+0x50/0x60
warn_slowpath_null+0x1c/0x24
ocal_bh_enable_ip+0xa0/0xac
bdi_register+0xec/0x150
Run Code Online (Sandbox Code Playgroud)

bdi_register+0xec/0x150是符号+偏移/长度那里是关于更多信息,了解内核哎呀,你如何调试内核oops中.还有关于调试内核的优秀教程

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

addr2line -e vmlinux_with_debug_info 0019594c(+offset)

  • 有时`addr2line`可以解析地址并确定合适的源代码行.当然,并不总是可以将指令映射到源代码中的位置,但仍然比没有好.当然,需要内核的调试符号.如果幸运的话,可以在`vmlinux`本身(用于定制内核)或单独的包中找到它们.一些发行版提供这样的包,名称可能会有所不同.`addr2line -e vmlinux_with_debug_info 0019594c`可能有助于找到与`bdi_register + 0xec`对应的源代码行. (5认同)

0x9*_*x90 21

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

用途objdump:

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

    objdump -dS vmlinux > /tmp/kernel.s
    
    Run Code Online (Sandbox Code Playgroud)
  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内核


mga*_*lgs 13

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

第一个数字(+0x0)是从函数开头偏移量(unwind_backtrace在本例中).第二个数字(0xf8)是函数总长度.鉴于这两条信息,如果你已经预先确定了故障发生的位置,这可能足以证实你的怀疑(你可以(大致)告诉你你的功能有多远).

要获得相应指令的确切源代码行(通常优于预测),请使用addr2line其他答案中的其他方法.