2016-05-10 45 views
2

我正在重寫Linux項目上的C++全局新/刪除操作符。它在我自己的代碼中很好地工作,直到我發現系統庫中的新/刪除符號也被我的代碼取代!這是一個非常糟糕的問題,因爲它遠遠超出了我想要的「惡劣程度」。C++自定義全局新/刪除覆蓋系統庫

所以問題是如何防止鏈接器/編譯器從其他(系統)共享庫中取代新/刪除syms?或者更確切地說,我如何控制共享庫從我的庫中鏈接syms? 我希望系統庫仍然會使用它們的默認新建/刪除實現。尤其是當可執行文件稍後將其他可選的動態庫加載到不受我控制的dlopen()中時。

自定義全局新建/刪除操作符實現構建到共享庫中。

我在互聯網上搜索瞭如何控制動態鏈接,但沒有成功。我首先嚐試在測試可執行文件上更改庫鏈接順序,但這並沒有改變任何內容。

+2

您正在使用錯誤的自定義點。如果您真的想在任何地方進行此項更改,則更換全球運營商很有用。如果您只想在本地化庫中自定義分配,則應該使用其他一些機制(例如分配器)來提供自定義點。 –

+2

考慮僅在您的類上重載新的和刪除操作符。如果你有大部分對象的基類,就在那裏做。這應該覆蓋您正在使用的大部分內存。然後,您可以在需要管理STL容器內的對象的情況下創建自定義STL分配器。 –

+0

只有在普通的「root」類中重載新的/刪除,在分配原始內存的情況下無法幫助我。重構大量的代碼來使用自定義的基礎新/刪除將是乏味的。我正在尋找LD_PRELOAD分配器在其他C++程序上測試它的可能性。 – JATothrim

回答

2

我發現系統庫中的新/刪除符號也被替換爲我的代碼!

你可以閱讀爲什麼發生這種情況的解釋here

所以問題是如何防止鏈接器/編譯器從其他(系統)共享庫中取代新/刪除syms?

你可以讓你::operator new::operator delete私人到庫與-fvisibility=hidden建設,並明確標示您想與__attribute__((visibility("default")))導出功能。或者,您可以使用linker version script獲得相同的結果。

+0

我知道linux.so庫與win.dll很不相同。但我不知道在可執行文件中解析的動態syms會鏈接到需要跨所有鏈接代碼具有單一定義的存檔文件。所以在* nix中這似乎是不可能的。太糟糕了。還是謝謝! 我已經在使用-fvisibility = hidden來編譯二進制文件並在代碼中標記導出的funcs。 – JATothrim

+1

太糟糕了,它不適用於這個超市操作系統。我使用-fvisibility = hidden標記了項目,用__attribute __((visibility(「hidden」)))標記了新的操作符。仍然我的系統庫被我的操作員覆蓋 –