我的理解是,当您使用
我的目标是将编译后的二进制文件复制到另一台计算机上,并仍然能够检索此调试信息。但目前,当我这样做时,所有的调试信息都会丢失。我不介意也将源文件一并复制过去,但第二台计算机正在运行不同的操作系统,因此文件结构不同,我无法将源文件放在完全相同的绝对位置,这导致objdump无法找到源代码。我查看了该二进制文件,并发现它包含以下部分,与大量二进制文件交错:
我还研究了gcc标记,希望其中之一允许指定源代码的相对路径而不是绝对路径,但我没有找到类似的内容。
供参考,这是我希望从
注意:虽然我以objdump作为使用源文件信息的程序示例,但实际上我感兴趣的不是objdump的输出。我正在运行一个需要访问相同信息的不同程序。问题是如何修复二进制文件,而不是如何使用objdump。
gcc -g
编译C代码时,gcc会插入包含对原始源代码的引用(例如行号)的调试信息。然后,其他程序如gdb和objdump可以稍后恢复这些引用。举个例子,我们将使用objdump -S
,它会打印与相应源代码交错的汇编代码。我的目标是将编译后的二进制文件复制到另一台计算机上,并仍然能够检索此调试信息。但目前,当我这样做时,所有的调试信息都会丢失。我不介意也将源文件一并复制过去,但第二台计算机正在运行不同的操作系统,因此文件结构不同,我无法将源文件放在完全相同的绝对位置,这导致objdump无法找到源代码。我查看了该二进制文件,并发现它包含以下部分,与大量二进制文件交错:
/home/path/to/source/code
我尝试编辑以匹配到源的新路径,但那只会使二进制文件无效。我还研究了gcc标记,希望其中之一允许指定源代码的相对路径而不是绝对路径,但我没有找到类似的内容。
供参考,这是我希望从
objdump - S
中获得的输出类型:0804840b <main>:
#include <stdio.h>
int main(){
804840b: 8d 4c 24 04 lea 0x4(%esp),%ecx
804840f: 83 e4 f0 and $0xfffffff0,%esp
8048412: ff 71 fc pushl -0x4(%ecx)
8048415: 55 push %ebp
8048416: 89 e5 mov %esp,%ebp
8048418: 51 push %ecx
8048419: 83 ec 14 sub $0x14,%esp
for(int varName = 0; varName < 100; varName++){
804841c: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp)
8048423: eb 32 jmp 8048457 <main+0x4c>
for(int innerLoop = 0; innerLoop < 30; innerLoop++){
8048425: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp)
804842c: eb 1f jmp 804844d <main+0x42>
if(innerLoop == varName){
804842e: 8b 45 f4 mov -0xc(%ebp),%eax
8048431: 3b 45 f0 cmp -0x10(%ebp),%eax
8048434: 75 13 jne 8048449 <main+0x3e>
printf("%d\n", innerLoop);
8048436: 83 ec 08 sub $0x8,%esp
8048439: ff 75 f4 pushl -0xc(%ebp)
804843c: 68 f0 84 04 08 push $0x80484f0
8048441: e8 9a fe ff ff call 80482e0 <printf@plt>
8048446: 83 c4 10 add $0x10,%esp
#include <stdio.h>
int main(){
for(int varName = 0; varName < 100; varName++){
for(int innerLoop = 0; innerLoop < 30; innerLoop++){
8048449: 83 45 f4 01 addl $0x1,-0xc(%ebp)
804844d: 83 7d f4 1d cmpl $0x1d,-0xc(%ebp)
8048451: 7e db jle 804842e <main+0x23>
#include <stdio.h>
int main(){
for(int varName = 0; varName < 100; varName++){
8048453: 83 45 f0 01 addl $0x1,-0x10(%ebp)
8048457: 83 7d f0 63 cmpl $0x63,-0x10(%ebp)
804845b: 7e c8 jle 8048425 <main+0x1a>
804845d: b8 00 00 00 00 mov $0x0,%eax
if(innerLoop == varName){
printf("%d\n", innerLoop);
}
}
}
}
注意:虽然我以objdump作为使用源文件信息的程序示例,但实际上我感兴趣的不是objdump的输出。我正在运行一个需要访问相同信息的不同程序。问题是如何修复二进制文件,而不是如何使用objdump。
objcopy
(修改目标文件的常用方法)似乎不支持更改此选项。但是gcc的-fdebug-prefix-map
选项应该可以在编译时做到您想要的效果。cc foo.c -g -fdebug-prefix-map = $(pwd)=。
应该会在DW_AT_comp_dir属性中输出.
而不是当前目录的路径名(这通常是您看到的)。运行objdump -Wi foo
进行检查。 - Mark Plotnickgcc -S -fverbose-asm
(可能还要加上-g
和/或-O
)来获取汇编代码。 - Basile Starynkevitch