修改 glibc 动态链接器以检查共享库是否已在另一个进程中加载

Modify glibc dynamic linker to check if a shared library has been loaded in another process

我想修改 glibc 动态 linker/loader 以便在将共享库映射到进程之前,linker/loader 检查库是否已被 loaded/in-use 中的任何其他进程系统与否。 linker/loader 仅当库未被任何其他进程 used/loaded 时,才会对共享库代码执行特定操作。我了解目前 linker/loader 仅线性映射共享库并等待需求分页以物理加载库。

我尝试使用动态 linker/loader 代码中的 shell 命令 lsof /path/library.so 来完成此操作。要从动态链接器代码中调用 lsof 命令,我尝试了

  1. system("lsof /path/library.so")
  2. File* fp=popen("lsof /path/library.so", "r")

构建动态链接器,但是,当我试图包含 stdio.h(对于 popen())或stdlib.h(对于 system())头文件。您能否建议如何解决 glibc 构建错误或任何其他更好的方法来解决我原来的问题?

补充 1:感谢@EmployedRussian。我还研究了您提到的选项。

One possible answer is: store them in a file or a database. If that is your answer, then the solution becomes obvious: check if the file or a database entry exists. If it does, you don't need to do the computation again.

基于 lsof 或 file/databased 的解决方案的主要问题是:当我添加一个新的 .c 文件并在该文件中 include <stdio.h> 进行文件操作时(例如 FILE* fp = fopen()), glibc build 给了我这样的几个函数错误:
'-Wl,-(' /path/glibc-2.30_build/elf/dl-allobjs.os /path/glibc-2.30_build/libc_pic.a -lgcc '-Wl,-)' -Wl,-Map,/path/glibc-2.30_build/elf/librtld.mapT /usr/bin/ld: /path/glibc-2.30_build/libc_pic.a(dl-error.os): in function `__GI__dl_signal_exception': /path/glibc_2.30_shared_library/elf/dl-error-skeleton.c:91: multiple definition of `_dl_signal_exception'; /path/glibc-2.30_build/elf/dl-allobjs.os:/path/glibc_2.30_shared_library/elf/dl-error-skeleton.c:91: first defined here

Building dynamic linker, however, gives me "multiple definitions of x symbols" error

这是因为动态链接器非常特殊,您在动态链接器中可以做的事情非常有限。

它很特殊,因为它必须是一个独立的程序——它不能使用任何其他库(包括libc.so.6)——它负责加载 所有其他库,因此它自然不能使用尚未加载的任何内容。

I just want to compute them once when the library is being physically loaded the first time.

这是还是一个XY Problem。您打算使用此计算结果做什么?

一个可能的答案是:将它们存储在文件或数据库中。

如果这是您的答案,那么解决方案就很明显了:检查文件或数据库条目是否存在。如果是,则无需重新计算。

更新:

The main problem for both lsof or file/databased based solution is: when I add a new .c file and include <stdio.h> in that file to do file operations (such as FILE* fp = fopen()), the glibc build gives me errors

这是完全相同的问题:您正在尝试使用无法在动态链接器中使用的 libc.so 部分。

如果您想将计算结果存储在文件中,则需要使用 可用的低级部分。使用 open()write() 而不是 fopen()fprintf().

或者,从您的库或程序中执行此操作——因为您将不再关心有多少进程加载了该库,因此没有理由尝试执行这个计算在加载器中。 (可能是一个原因,但你没有解释它;所以我们回到 XY 问题。)