我想拦截在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