从内核调用跟踪中获取行号

时间:2010-04-15 20:41:27

标签: debugging linux-kernel kernel debug-symbols backtrace

我正在尝试调试看似是完成队列的问题:

Apr 14 18:39:15 ST2035 kernel: Call Trace:
Apr 14 18:39:15 ST2035 kernel:  [<ffffffff8049b295>] schedule_timeout+0x1e/0xad
Apr 14 18:39:15 ST2035 kernel:  [<ffffffff8049a81c>] wait_for_common+0xd5/0x13c
Apr 14 18:39:15 ST2035 kernel:  [<ffffffffa01ca32b>]
ib_unregister_mad_agent+0x376/0x4c9 [ib_mad]
Apr 14 18:39:16 ST2035 kernel:  [<ffffffffa03058f4>] ib_umad_close+0xbd/0xfd

是否可以将这些十六进制数转换为接近行号的东西?

1 个答案:

答案 0 :(得分:4)

不完全如果你有一个带有调试信息的的vmlinux镜像,(例如,在RHEL中,你应该能够安装kernel-debug或kernel-dbg或类似的东西)你可以靠近所以假设你有vmlinux文件可用。执行以下操作:

objdump -S vmlinux

这将尝试将目标代码与各个源代码行匹配起来最困难。

e.g。对于以下C代码:

#include <stdio.h>
main() {
  int a = 1;
  int b = 2;

  // This is a comment

  printf("This is the print line %d\n", b);
} 

编译:cc -g test.c

然后在生成的可执行文件上运行objdump -S,我得到一个大输出,描述了可执行文件的各个部分,包括以下部分:

00000000004004cc <main>:
#include <stdio.h>
main() {
  4004cc:   55                      push   %rbp
  4004cd:   48 89 e5                mov    %rsp,%rbp
  4004d0:   48 83 ec 20             sub    $0x20,%rsp
  int a = 1;
  4004d4:   c7 45 f8 01 00 00 00    movl   $0x1,-0x8(%rbp)
  int b = 2;
  4004db:   c7 45 fc 02 00 00 00    movl   $0x2,-0x4(%rbp)

  // This is a comment

  printf("This is the print line %d\n", b);
  4004e2:   8b 75 fc                mov    -0x4(%rbp),%esi
  4004e5:   bf ec 05 40 00          mov    $0x4005ec,%edi
  4004ea:   b8 00 00 00 00          mov    $0x0,%eax
  4004ef:   e8 cc fe ff ff          callq  4003c0 <printf@plt>
} 

您可以将第一列中对象代码的地址与堆栈跟踪中的地址进行匹配。将它与汇编输出中交错的行号信息相结合......你就在那里。

现在请记住,这并不总是100%成功,因为kenrel通常在-O2优化级别编译,并且编译器会完成大量代码重新排序等。但是如果你熟悉代码那么你正在尝试进行调试,并且通过破译正在处理的平台组件而感到安慰......你应该能够确定大部分崩溃等。

相关问题