2011-04-28 82 views
6

我寫了一個自定義庫,它使用標準的C原型實現了malloc/calloc/realloc/free,並且我想出瞭如何將它編譯爲so。我想通過鏈接一個標準的應用程序來測試這個庫嗎?什麼是這樣做的好方法?一旦我有一個工作庫,我假設我可以用LD_PRELOAD加載它,但是如何讓我的函數與系統庫共存,但優先於系統庫?我的函數需要調用malloc以獲得內存運行,所以我不能完全拋棄stdlib ...幫助?編譯一個自定義的malloc

+1

我相當肯定我的答案在於使用動態鏈接器。 – conartist6 2011-04-28 17:43:06

回答

4

您試圖替換的函數是標準的C函數,而不是宏,而不是系統調用。所以你必須簡單地給你的函數使用相同的名字並將它們編譯到共享庫中。

然後,使用LD_PRELOAD在二進制啓動之前預先加載您的庫。由於所有地址都解析了一次,鏈接器會找出你函數的地址並記住它們的名字,以後不會在標準庫中查找它們。

如果您的程序與標準運行時間靜態鏈接,則此方法可能不起作用。此外,它不適用於Mac OS X,因爲還有另一個插值API。

在Linux中,例如,爲了讓您的功能並存的(也就是說,如果你想在自己實現malloc使用的系統malloc),你必須打開使用dlopen手動標準庫,查找功能你需要在那裏使用dlsym,然後通過地址給他們打電話。

+0

我以爲我會碰到更多的問題,但我刪除了包含標準庫和加載malloc後退出與dlsym一切編譯好。謝謝! – conartist6 2011-04-28 18:03:09

+0

@ conartist6:不客氣:) – 2011-04-28 18:04:25

1

如果你有使用這個庫的源代碼的控制權,這裏有一種可能性。使用不同的函數名稱:例如,而不是malloc,將其稱爲newCoolMalloc。此方法有時更簡單,不依賴於特殊的鏈接器選項。

然後在您的代碼中,使用#define使代碼調用所需的一組函數。你可以#定義malloc是不同的。例如:

#define malloc newCoolMalloc 
#define free newCoolFree 

如果你這樣做,但你必須非常小心地包括這一貫。否則,你會冒着在一個地方使用stdlib malloc的風險,然後在另一個地方使用自由空間,這導致了一些麻煩的bug。一種有助於緩解這種情況的方法是(如果可能)在您自己的代碼中使用分配和自由函數的自定義名稱。然後更容易確保正確的被調用。您可以爲各自的malloc函數或甚至原始的stdlib malloc函數定義各種自定義名稱。

例如,您可能會在代碼中使用mallocPlaceHolder的實際名稱:

someThing = mallocPlaceHolder(nbytes); 

然後你定義一下會更是這樣的:

#define mallocPlaceHolder myCoolMalloc 

如果沒有形式mallocPlaceHolder的功能(和相關的免費)實際存在,它避免了混合不同的庫。

+0

不幸的是,這並不適合我。我想通過使用這個庫運行別人的應用程序來測試我的分配器。我可以在理論上重新編譯這些內容,但時間和精力將通過LD_PRELOAD保存。 – conartist6 2011-04-28 18:04:39

2

不要根據malloc()編寫malloc() - 使用sbrk編寫它,它可以直接從操作系統獲取內存。

+0

有趣的建議。我會研究它。 – conartist6 2011-04-28 18:03:20

+0

在某些系統上,'sbrk()'不再可用。例如,在我目前的Mac OS X上,該名男子說:「brk和sbrk函數是虛擬內存管理出現之前早期遺留下來的歷史好奇。」如果你看看函數的全部來源,它甚至可以有趣的:'errno = ENOMEM; return((void *) - 1);' – achedeuzot 2015-01-20 18:02:26