2013-07-25 30 views
4

我的問題涉及Python,Qt,PyQt和其他東西,但問題實際上是關於Linux的ld.so實際如何工作。定義相同函數名稱的兩個linux共享對象之間的衝突

問題

如果程序加載兩個不同的共享庫都具有相同的入口點名稱(即它們都定義具有相同名稱和簽名的功能),它如何知道哪個版本是它打電話?

我的問題

我有一個第三方的,專有的Linux應用程序,它是用C++編寫(雖然原來的語言是不相關的),它的動態鏈接到Qt3.3。該應用程序嵌入了一個可用於爲其編寫腳本的Python解釋器。

可以使用的命令,例如即使使用應用程序的嵌入式Python,而不是原來的:

/path/to/the/program/python 

它顯示以下內容:

Python 2.7.1 (r271:86832, Sep 16 2011, 18:16:32) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> 

使用GCC 4.1.2我有從源代碼構建並安裝PyQt4,與系統也具有的Qt4庫。我認爲,構建成功,因爲我可以通過運行一個小的PyQt4的應用:

/path/to/the/program/python mypyqtapp.py 

但是,如果我與它的GUI加載程序並加載相同的腳本,它崩潰在第一PyQt4調用,這是一個實例化QApplication類。

由於python環境相同,我懷疑它可能是Qt3和Qt4之間的某種共享庫衝突。但是,命令strace -e trace=file顯示python在兩種情況下都定位並加載了正確的Qt4庫。

所以,我的問題是,如果一個程序加載兩個共享不同的庫,定義相同的功能,它是如何知道它調用正確的? linux加載程序ld.so以某種方式限定入口點的文件名或其他?我懷疑我的問題可能存在,該應用程序最終加載了兩個不同的QApplication實例,它調用了錯誤的實例,但實際上ld.so實際上是如何工作的。

也可能是我的問題是由完全不同的東西造成的。

謝謝。

+0

你試過像gdb/ddd這樣的調試器嗎? – Frodon

回答

1

僅在鏈接(ld)階段檢測到衝突符號,loader(ld-linux.so)不檢查衝突符號。

當多個庫提供重複符號時,使用第一個加載的符號。

其實有人可以利用這個功能。通過提供LD_PRELOAD = overwrite.so,overwrite.so可以覆蓋程序所需的任何函數。

+0

引發這個問題的真正問題已經過時了,現在已經消失了。我猜如果我嘗試使用LD_PRELOAD解決方案,那麼應用程序只會在不同的地方崩潰。我接受這個答案是因爲它確實提供了關於ld.so如何工作的具體問題的直接答案。謝謝。 – deStrangis