2011-03-11 81 views
10

我只是想知道是否有一种有效的技术来解决gcc中未定义的符号问题。有时我的一个项目无法链接,我通常会花费大量时间来查找原因。通常这是一个深藏在makefile中的错字,错误的环境变量或类似的东西。如果你的构建突然与“未定义的符号”一起死亡,你使用了什么方法,这是不明显的原因?未定义符号的一般故障排除技术 - gcc

+0

我在词典中查找单词“符号”......(对不起,它已经晚了......) – dappawit 2011-03-11 06:57:30

回答

23

说这是我开始的配置:

/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/crt1.o: In function `_start': 
(.text+0x18): undefined reference to `main' 
bar.o: In function `baz()': 
bar.cpp:(.text+0xd): undefined reference to `Foo::bar()' 
collect2: ld returned 1 exit status 

我开始使用grep缺少的符号查找到所有的.o和.lib文件。

$ grep 'Foo.*bar' *.o *.lib *.so 
Binary file bar.o matches 
Binary file foo.o matches 

然后我用个nm工具来检查每个对象文件,如果符号存在缺失或执行。

$ nm foo.o 
00000000 T _ZN3Foo3barEv 

$ nm bar.o 
00000000 T _Z3bazv 
     U _ZN3Foo3barEv 
     U __gxx_personality_v0 

现在我知道Foo :: bar()是在foo.o中实现的,并且可以将该文件链接到可执行文件中。因此下一部分是检查为什么foo.o不包含在链接命令中。

有时您找不到任何实施符号。通常情况下,执行单元未生成或者不包含符号(#ifdef,符号可见性)。在这种情况下,我搜索定义符号的.cpp文件,运行make $file.o以生成文件,然后检查文件。当smbol在那里时,我会继续构建放置该文件的库或可执行文件。

+0

感谢您的信息。添加-Wl-t选项以转储链接器已知的库也是有用的。你知道一些真正困难的案件吗?例如两个依赖的静态库包含错误的顺序? – danatel 2011-03-13 10:00:19

+0

@danatel对不起,但我没有通用的技术来调试错误的库依赖关系,因为每种情况都是不同的。 – Rudi 2011-03-14 19:06:49

+0

这是一个很好的答案。想知道为什么它没有被接受。 – 2011-05-21 17:40:13