2011-03-11 79 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