1

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

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

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

4

1 回答 1

5

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

objdump -S vmlinux

这将尝试将目标代码与源代码的各个行进行匹配是最困难的。

例如对于以下 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 优化级别编译,并且编译器会进行大量代码重新排序等。但是如果您熟悉您的代码尝试调试并在破译您正在使用的平台的组装时感到舒适......您应该能够确定大多数崩溃等。

于 2010-04-15T21:02:07.383 回答