2012-12-24 104 views
2

作爲從HP到AIX的應用程序遷移的一部分,我面臨着一個獨特的問題。 以下模擬代碼在HP和AIX中產生不同的結果。在AIX中啓動C++可執行文件時出錯

LIBRARY.C **

#include <stdio.h> 
    #include "mylib.h" 

    int libimgclientFNXXX() 
    { 
     int check = 100; 
     check = FileNetDeleteDoc(check); 
     return check; 
    } 

    int libimgclientFN() 
    { 
     int check = 1; 
     printf("In lib "); 
     return check; 
    } 

* main_func.C *

#include <stdio.h> 

    int libimgclientFN(); 
    int libimgclientFNXXX(); 

    int main() 
    { 
     int one = 0; 
     if (1 == 1) 
     { 
      one = libimgclientFN(); 
     } 
     printf("\n The status is %d \n", one); 
    } 

* mylib.h **

extern int FileNetDeleteDoc (int); 

注意函數libimgclientFNXXX()不會被調用。 我make文件是如下:

xlC -c -g library.C -o library.o -I./ 
xlC -G -qmkshrobj -o libImgClient.so library.o 
xlC -c -g -qpic=small main_func.C -o main_func.o 
xlC -brtl main_func.o -L. -lImgClient -o TST 

當我運行TST,我得到以下加載錯誤

$ TST 
exec(): 0509-036 Cannot load program TST because of the following errors: 
rtld: 0712-001 Symbol FileNetDeleteDoc__Fi was referenced 
     from module ./libImgClient.so(), but a runtime definition 
     of the symbol was not found. 

即使功能libimgclientFNXXX()不會被調用,還有未解決的錯誤。

與惠普內置的完全相同的代碼工作正常,沒有錯誤。

任何輸入表示讚賞。

感謝,

+0

歡迎來到SO。正如您所看到的,人們已經編輯了您的問題,以便於閱讀和搜索。 –

回答

2

是啊,「不使用」的庫函數仍可能是一個錯誤,即使你不打算調用的代碼。它可能會延遲一些組件的加載,直到以後,所以它可能不會導致錯誤。最好不要引用不存在的東西(或手動加載庫並獲取地址,如果該函數不存在,則會從「查找函數」調用中收到錯誤,並且您可以執行某些操作在代碼中是明智的)。

加載器(加載二進制可執行文件的代碼)不是很聰明,所以它不能確切地知道被調用的是什麼,什麼不是。也有可能不同的編譯器對「死代碼清除」有不同程度的聰明,所以一個編譯器完全刪除了「never called」函數,但另一個編譯器不會刪除它[因爲它沒有100%的認證你永遠不會調用函數 - 例如,在gcc中,如果你使得libimgclientFNXXX成爲一個靜態函數,它就會知道這一點 - 因爲它知道靜態函數不會在這個模塊之外被調用,並且這個模塊沒有使用它。

+0

謝謝大家。使用-blazy會涉及很多變化。我們有100個用於不同模塊的makefile。有沒有任何方法來識別這些「死代碼」,以便我可以從源文件中刪除它們?我可以使用nm或任何其他工具來執行此操作嗎? nm的問題在於有很多動態鏈接的「未定義」函數。我怎樣才能將它與真正的「未定義」區分開來? – SreeniH

+0

我不確定是否有一種簡單的方法來確定哪些模塊具有「真正」未定義的符號,哪些不符合。我想你可以寫一個腳本來收集你所有的模塊和交叉引用,並打印任何未定義的東西的名字。 –

2

AIX要求所有符號在加載時解析,因此即使它構建成功,因爲符號被引用,應用程序也不會運行。

對於.so(-blazy鏈接選項),您需要使用lazy linking,這應該會導致僅在首次使用時鏈接缺少的函數。

你真的不應該在庫中留下未定義的符號,但是 - 如果它需要來自另一個庫的符號,則應該鏈接到它們(除非它是插件,符號在應用程序本身中公開) 。

相關問題