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