如何从链接器错误转到源代码行?

Ste*_*ini 3 c++ linux linker gcc g++

链接器产生这种输出

/var/tmp/ccITB4j2.o: In function `main':
/var/tmp/ccITB4j2.o(.text+0x4): undefined reference to `myFunction(void)'
Run Code Online (Sandbox Code Playgroud)

如何查找与实际调用该函数的.text + 0x4指令对应的源代码行?

Emp*_*ian 6

首先,您的问题的另一个答案是错误的:在Linux上,您确实从链接器获取文件和行号:

$ cat foo.cc
extern int myFunction(void);

int main()
{
  return myFunction();
}
$ g++ -g foo.cc
/tmp/cc3twlhL.o: In function `main':
/tmp/foo.cc:5: undefined reference to `myFunction()'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

以上输出来自gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3和链接器GNU ld (GNU Binutils for Ubuntu) 2.22,但对于许多旧版本的GCC和ld也是如此.

你没有得到文件/行的原因必须是那个

  • 你没有使用-g旗帜,或
  • 真的老了ld,或者
  • 您已经配置了ld不支持调试(我不确定这是否可行).

但是,即使您ld拒绝告诉您文件和行,也不会丢失所有内容.您可以将源代码编译为object,然后使用它objdump -rdS foo.o来获取相同的信息:

g++ -g -c foo.cc
objdump -rdS foo.o

Disassembly of section .text:

0000000000000000 <main>:
extern int myFunction(void);

int main()
{
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
  return myFunction();
   4:   e8 00 00 00 00          callq  9 <main+0x9>
            5: R_X86_64_PC32    _Z10myFunctionv-0x4
}
   9:   5d                      pop    %rbp
   a:   c3                      retq
Run Code Online (Sandbox Code Playgroud)

在上面的输出中,您可以清楚地看到哪个源行导致在目标文件中发出引用_Z10myFunctionv(这是被C++破坏的名称myFunction(void)).