在零售构建中分析核心转储通常需要将objdump
任何特定模块与源相关联。如果功能非常复杂,通常将程序集转储与源相关联会变得很痛苦。今天,我尝试创建assembly listing
一个特定模块(使用 compile 选项-S
),期望我会看到一个带有汇编或某些相关性的交错源。不幸的是,列表不够友好,无法关联,所以我想知道
- 给定一个核心转储,我可以从中确定崩溃位置
objdump
通过重新编译失败的模块组装清单- 带
-S
选项的模块。
是否可以与来源进行一一对应?
例如,我将程序集列表视为
.LBE7923:
.loc 2 4863 0
movq %rdi, %r14
movl %esi, %r12d
movl 696(%rsp), %r15d
movq 704(%rsp), %rbp
.LBB7924:
.loc 2 4880 0
testq %rdx, %rdx
je .L2680
.LVL2123:
testl %ecx, %ecx
jle .L2680
movslq %ecx,%rax
.loc 2 4882 0
testl %r15d, %r15d
.loc 2 4880 0
leaq (%rax,%rax,4), %rax
leaq -40(%rdx,%rax,8), %rdx
movq %rdx, 64(%rsp)
但不明白如何解释标签.LVL2123
和指令.loc 2 4863 0
注意
正如所描述的答案,阅读汇编源代码并根据符号(如函数调用、分支、返回语句)直观地确定模式是我通常所做的。我不否认它不起作用,但是当一个函数非常复杂时,阅读汇编列表页面是一种痛苦,并且通常你最终会得到很少匹配的列表,因为函数被内联或优化器只是简单地扔了代码随心所欲。我有一种感觉,看看效率如何Valgrind
处理优化的二进制文件以及在 Windows WinDBG 中如何处理优化的二进制文件,我缺少一些东西。所以我虽然我会从编译器输出开始并使用它来关联。如果我的编译器负责修改二进制文件,那将是说明如何与源代码关联的最佳人选,但不幸的是,这几乎没有帮助,而且.loc
确实具有误导性。不幸的是,我经常不得不通读各种平台上无法重现的转储,而我花最少的时间是通过 WinDBG 调试 Windows Mini-dumps,而在调试 Linux Coredumps 上花费了相当多的时间。我虽然这可能是我做事不正确,所以我想出了这个问题。