我想攔截在dlopen()中發生的所有文件系統訪問。起初,這看起來就LD_PRELOAD
或-Wl,-wrap,
將是可行的解決方案,但我有麻煩做他們的工作,由於一些技術原因:如何攔截dlopen()內的文件系統訪問?
ld.so已經由時間LD_PRELOAD映射自己的符號是處理。攔截初始加載對我來說並不重要,但此時解決了工作人員功能,以便將來的呼叫通過它們。我認爲
LD_PRELOAD
爲時已晚。不知何故
malloc
避開了這個問題,因爲上面的ld.so內malloc()
不具有的功能free()
,它只是調用memset()
。文件系統工作者功能,例如,
__libc_read()
,包含在ld.so
中是靜態的,所以我不能用-Wl,-wrap,__libc_read
來攔截它們。
這可能都意味着我需要建立直接從源我自己ld.so
而不是鏈接成一個包裝。存在的挑戰是,libc
和rtld-libc
都是從相同的來源構建的。我知道在構建rtld-libc
時定義了宏IS_IN_rtld
,但是如何確保在仍然導出公共接口函數的同時只有一個靜態數據結構副本? (這是一個glibc構建系統的問題,但我還沒有找到這些細節的文檔。)
有沒有更好的方法進入dlopen()
?
注意:我不能使用特定於Linux的解決方案,如FUSE
,因爲這適用於不支持此類操作的最小「計算節點」內核。
這不是你的問題的答案,所以我沒有把它作爲一個發佈,但總的來說你不能做到這一點可靠:它可以通過直接調用系統調用而不通過動態庫接口。如果您沒有完全控制您要加載的庫的編譯方式,那麼您可能會失敗。像fakeroot這樣的程序在大多數情況下都能正常工作,並且在某些情況下會出現可怕的情況。 –
也就是說,你可以通過在自己的進程中運行動態庫代碼並使用'ptrace'來截獲系統調用本身來完成這項工作。我已經取得了巨大的成功,它完全避免了所有的共享庫廢話。但它確實需要你完全重新設計你的邏輯,以便擁有一個完成ptrace內容的主進程和一個執行動態庫內容的從進程。 –
嗯,我需要'dlopen' /'dlsym'才能正常工作,但要以不同的方式訪問文件系統。特別是在諸如Blue Gene等HPC環境中,涉及內核文件描述符的所有操作都是從計算節點IO節點提供的。這會導致高節點併發嚴重的爭用問題。例如,加載引用大量編譯共享庫的Python應用程序在65k內核上需要大約4個小時。毋庸置疑,人們對於耗費25萬個核心小時來加載他們的節目並不感到興奮。 – Jed