2012-06-12 94 views
7

我有一個靜態鏈接到libssl.a &另一個靜態鏈接libssl.a的共享對象B.so的共享對象A.so。靜態庫加載兩次

A.so & B.so在GLOBAL範圍內具有來自libssl.a的符號。我通過readelf -s A.so檢查了這個。我有一個可執行文件a.out,它加載A.so和B.so.當a.out終止時,我在A.so.的libssl.a中的一個符號中得到一個 雙免費錯誤。

即使libssl.a靜態鏈接到每個共享對象,因爲它們在全局範圍內公開顯示爲 有可能共享相同的符號而不是選擇它的本地副本。

這是什麼解決方法?如何使符號在本地?

請幫忙

+0

我會推薦使用調試器來確認你的理論。 – jdigital

+0

能否詳細說明一下? – KodeWarrior

+0

只是一件小事,因爲我不知道如何將它應用到你的情況:'dlopen'有一個RTLD_LOCAL標誌,在某些情況下,這種標誌可以幫助確切地處理這種情況。所以如果你用'dlopen'打開這些庫,他們可能不應該干涉。 – liori

回答

5

這確實是預期的。 libssl.a的一個實例會介入另一個實例(可能是其中的一個子集),結果並不美觀。您可以使用版本腳本(--version-script至ld,cc爲-Wl,)來控制從A.soB.so導出的內容。如果有東西沒有輸出,它也不能插入。

或者,您可以編譯libssl.a,並顯示可見性標誌,如-fvisibility=hidden。這些標誌隻影響動態鏈接器而不影響靜態鏈接。您可能需要自己編譯它,因爲運輸.a文件傾向於包含位置相關的代碼,意味着鏈接到可執行文件。只有一些平臺(如32位x86)才能讓您將此類代碼鏈接到共享對象,並且僅以文本重定位爲代價。

dlopenRTLD_LOCAL正如評論中所建議的也應該工作,但它似乎hackish使用dlopen爲此目的。

另一種選擇是在兩個庫中使用相同的共享libssl.so