2010-01-05 60 views
12

我正在嘗試爲相當大的項目的一小部分編寫一些小測試。試圖鏈接這個野獸是不幸的,如果沒有將整個項目鏈接在一起,這是我不想做的事情(這是一個非常複雜的系統,可以找到所有的依賴關係和東西,而且我不會干涉它)。現在我可以將未解析的引用鏈接到中止嗎?

,我確切知道所引用的功能將不會在我的測試中被調用的函數,則恰好是與東西,我做的測試文件共享功能的一部分。

有沒有辦法簡單地鏈接到這些未解決的參考,讓我們說,中止,還是什麼?或者是否有一種工具創建了適當的存根目標文件,其中所有調用都會導致中止,給定了我擁有的一組目標文件?

我使用用於編譯/鏈接,版本3.4.4的gcc(克++)。平臺是unix(solaris/sparc如果這很重要)。

我能想到的

回答

15

你可以告訴鏈接器忽略未解決的符號。我找不到將其鏈接到abort或類似的選項。

忽略目標文件未解決的符號政策不僅是最自然的,我想:

gcc -Wl,--unresolved-symbols=ignore-in-object-files obj.o another.o etc.o 

其他選項包括(報價man ld):

--unresolved-symbols=method 
     Determine how to handle unresolved symbols. There are four possi- 
     ble values for method: 

     ignore-all 
      Do not report any unresolved symbols. 

     report-all 
      Report all unresolved symbols. This is the default. 

     ignore-in-object-files 
      Report unresolved symbols that are contained in shared 
      libraries, but ignore them if they come from regular object 
      files. 

     ignore-in-shared-libs 
      Report unresolved symbols that come from regular object files, 
      but ignore them if they come from shared libraries. This can 
      be useful when creating a dynamic binary and it is known that 
      all the shared libraries that it should be referencing are 
      included on the linker's command line. 

     The behaviour for shared libraries on their own can also be con- 
     trolled by the --[no-]allow-shlib-undefined option. 

     Normally the linker will generate an error message for each 
     reported unresolved symbol but the option --warn-unresolved-sym- 
     bols can change this to a warning. 

在我的Linux系統嘗試將未解析的函數調用結果稱爲「分段錯誤」。

+0

segmantation故障會做我想... :)謝謝,我會嘗試--warn-unresolved-符號以及 – falstro 2010-01-05 15:39:14

+0

酷。這是很好的信息。 – 2010-01-05 15:42:16

+2

--warn-unresolved-symbols對我來說是完美的,那樣我會(希望)也會注意到有什麼東西不應該被解決。 – falstro 2010-01-05 15:44:00

1

那麼一種方法是首先編譯.o文件,爲你的資料庫。

然後用像nm工具(在* nix系統中很常見),讓所有的符號,在nm,所有的「外部」(未在此的.o發現又名者)是型ü(它可能不同於非GNU版本的nm請參閱您的文檔)。

如果庫是一個所有的源文件,那麼很簡單,幾乎U型的所有符號將是要麼在另一個庫中發現了一個功能或將在鏈接時沒有解決。如果你的圖書館要多於一個源文件,這會稍微複雜一點,因爲你將會有源文件間的依賴關係。

所以,現在你有AA手段創造無法解析外部的潛在名單,那麼你就可以創建具有爲每一個,你可以用這樣的填充存根符號「test_stub.c」:

void some_func() { abort(); } 

其中some_func是將無法解析的外部。編譯並鏈接到您的庫,所有調用都會導致中止。

+0

很棒的技巧,這是從一個單一的.o文件遺憾的是遠,所以它需要一些工作......但我想沒有任何一個位腳本不會解決。 – falstro 2010-01-05 15:27:58

+0

是啊,我有點小小的困惑應該可以走很長的路。如果你所有的庫函數都有一些通用的命名約定來讓你分離出libc引用,那將是非常容易的。 – 2010-01-05 15:29:04

+0

它的C++不幸(name-mangling ftw!):(你知道是否有辦法將對象鏈接到單個對象中?(有點像我想的ar,但我猜nm不會在.a文件上工作?) – falstro 2010-01-05 15:32:06

1

試圖編譯下面的程序

#include <iostream> 

extern int bar(); 

int foo() 
{ 
    return bar() + 3; 
} 

int main() 
{ 
    std::cout << "Hello, world!" << std::endl; 
    // std::cout << foo() << std::endl; 

    return 0; 
} 

結果

$ g++ -o main main.cc 
/tmp/ccyvuYPK.o: In function `foo()': 
main.cc:(.text+0x5): undefined reference to `bar()' 
collect2: ld returned 1 exit status

但是我們可以告訴鏈接忽略未解決的符號,並運行它只是罰款:

$ g++ -Wl,--unresolved-symbols=ignore-all -o main main.cc 
$ ./main 
Hello, world!

說一些未解決的功能通過您的測試工具(通過取消對foo的調用來模擬此工具),它將編譯並鏈接正常,但在執行程序時會出現段錯誤。請務必ulimit -c unlimited,以便獲得core

0

嘗試GCC alias屬性:

/* cannot directly alias to yet undefined symbols, 
* so need an intermediate function. 
*/ 
static void do_abort() { abort(); } 

void func0() __attribute__ ((weak, alias ("do_abort"))); 
void func1() __attribute__ ((weak, alias ("do_abort"))); 
... 
相關問題