未定义符号的通用故障排除技术 - gcc

16

我想知道是否有一种有效的技术来解决gcc中的未定义符号问题。有时我的项目链接失败,通常我会花费很多时间来查找原因。通常是深藏在makefile中的拼写错误、不正确的环境变量或类似的问题。如果您的构建突然出现“未定义符号”,而且原因不明显,那么您会使用什么方法?


我在字典里查找单词“symbol”……(抱歉,现在有点晚了……) - dappawit
1个回答

30

这是我的起始配置:

/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生成文件,并检查文件。当符号存在时,我继续构建包含此文件的库或可执行文件。

谢谢您提供的信息。添加-Wl-t选项以转储链接器已知的库也很有用。您是否了解一些针对真正困难的情况的方法?例如,两个依赖静态库按错误顺序包含在内的情况? - danatel
@danatel,很抱歉,我没有一般性的技巧来调试错误的库依赖,因为每个情况都是不同的。 - Rudi
这是一个很好的答案。不知道为什么它还没有被接受。 - Jon Mills

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接