在两个以上的共享库之间切换 (LD_PRELOAD)

Switching Between More than Two Shared Libraries (LD_PRELOAD)

假设存在三个共享库A.soB.soC.so,每个共享库都有一个函数f()。我想在某些情况下在运行时确定的每个功能 f() 之间切换。使用 LD_PRELOAD 技巧,我将按如下方式执行程序 p(即这些库的用户):

LD_PRELOAD=A.so:B.so:C.so ./p

f() in A.so 将是默认值。在那个 f() 实例中,我可以使用 dlsym() 访问 B.sof(),如下所示:

void f() // in A.so
{
...
    void *f_in_B = dlsym(RTLD_NEXT, "f");
...
}

如何访问 C.so 中的 f() 实例?


更新:

虽然 简单的 情况下有效,但在 一般情况下 有问题 条件。我将通过提供更多 详细信息 当前 情况来阐明问题:

我需要两个不同的动态内存分配器并且想要处理内部 glibc malloc(),... 的实现细节。简而言之,我有两个 独立的 内存区域,每个内存区域都有自己的 glibc。我根据某些 runtime 条件在分配器之间使用 LD_PRELOADswitch。我使用 加载和访问 secondary 库。

首先,我在副库中调用了ptmalloc_init()初始化malloc()数据结构。我还在 managed brk() 系统调用级别调用 each 库有其 拥有brk()范围,这避免了进一步的冲突。

问题是该解决方案 仅在 application/glibc 边界 有效。比如我在secondary库中使用malloc()时,它会调用primary库中的__default_morecore()等函数,内部,并且这些调用不会LD_PRELOAD技巧捕获。

为什么会发生这种情况?我以为库的内部符号是在库编译时内部设置的,但是,这里,似乎他们使用 LD_PRELOADprimary 库中的符号。如果解析是由 linker 完成的,为什么这些看似内部的符号 而不是 LD_PRELOAD 技巧捕获?

我怎样才能解决这个问题?我是否应该重命名 exported secondary 库中的所有函数?或者 唯一 可行的方法是使用 单个 库并 深入研究 实现的东西?

您可以 dlopen 三个库中的每一个在启动时获取它们的句柄,并使用它们调用 dlsym(h, "f") 以获得 f 的特定实现。如果您事先不知道库名称,您可以使用 dl_iterate_phdr 来获取它们(例如参见 [​​=14=])。