在两个以上的共享库之间切换 (LD_PRELOAD)
Switching Between More than Two Shared Libraries (LD_PRELOAD)
假设存在三个共享库A.so
、B.so
和C.so
,每个共享库都有一个函数f()
。我想在某些情况下在运行时确定的每个功能 f()
之间切换。使用 LD_PRELOAD
技巧,我将按如下方式执行程序 p
(即这些库的用户):
LD_PRELOAD=A.so:B.so:C.so ./p
f()
in A.so
将是默认值。在那个 f()
实例中,我可以使用 dlsym()
访问 B.so
的 f()
,如下所示:
void f() // in A.so
{
...
void *f_in_B = dlsym(RTLD_NEXT, "f");
...
}
如何访问 C.so
中的 f()
实例?
更新:
虽然 在 简单的 情况下有效,但在 一般情况下 有问题 条件。我将通过提供更多 详细信息 当前 情况来阐明问题:
我需要两个不同的动态内存分配器并且不想要处理内部 glibc
malloc(),...
的实现细节。简而言之,我有两个 独立的 内存区域,每个内存区域都有自己的 glibc
。我根据某些 runtime 条件在分配器之间使用 LD_PRELOAD
到 switch。我使用 加载和访问 secondary 库。
首先,我在副库中调用了ptmalloc_init()
初始化malloc()
数据结构。我还在 managed brk()
系统调用级别调用 each 库有其 拥有大brk()
范围,这避免了进一步的冲突。
问题是该解决方案 仅在 application/glibc
边界 有效。比如我在secondary库中使用malloc()
时,它会调用primary库中的__default_morecore()
等函数,内部,并且这些调用不会被LD_PRELOAD
技巧捕获。
为什么会发生这种情况?我以为库的内部符号是在库编译时内部设置的,但是,这里,似乎他们使用 LD_PRELOAD
的primary 库中的符号。如果解析是由 linker 完成的,为什么这些看似内部的符号 而不是 被 LD_PRELOAD
技巧捕获?
我怎样才能解决这个问题?我是否应该重命名 exported secondary 库中的所有函数?或者 唯一 可行的方法是使用 单个 库并 深入研究 实现的东西?
您可以 dlopen
三个库中的每一个在启动时获取它们的句柄,并使用它们调用 dlsym(h, "f")
以获得 f
的特定实现。如果您事先不知道库名称,您可以使用 dl_iterate_phdr
来获取它们(例如参见 [=14=])。
假设存在三个共享库A.so
、B.so
和C.so
,每个共享库都有一个函数f()
。我想在某些情况下在运行时确定的每个功能 f()
之间切换。使用 LD_PRELOAD
技巧,我将按如下方式执行程序 p
(即这些库的用户):
LD_PRELOAD=A.so:B.so:C.so ./p
f()
in A.so
将是默认值。在那个 f()
实例中,我可以使用 dlsym()
访问 B.so
的 f()
,如下所示:
void f() // in A.so
{
...
void *f_in_B = dlsym(RTLD_NEXT, "f");
...
}
如何访问 C.so
中的 f()
实例?
更新:
虽然
我需要两个不同的动态内存分配器并且不想要处理内部 glibc
malloc(),...
的实现细节。简而言之,我有两个 独立的 内存区域,每个内存区域都有自己的 glibc
。我根据某些 runtime 条件在分配器之间使用 LD_PRELOAD
到 switch。我使用
首先,我在副库中调用了ptmalloc_init()
初始化malloc()
数据结构。我还在 managed brk()
系统调用级别调用 each 库有其 拥有大brk()
范围,这避免了进一步的冲突。
问题是该解决方案 仅在 application/glibc
边界 有效。比如我在secondary库中使用malloc()
时,它会调用primary库中的__default_morecore()
等函数,内部,并且这些调用不会被LD_PRELOAD
技巧捕获。
为什么会发生这种情况?我以为库的内部符号是在库编译时内部设置的,但是,这里,似乎他们使用 LD_PRELOAD
的primary 库中的符号。如果解析是由 linker 完成的,为什么这些看似内部的符号 而不是 被 LD_PRELOAD
技巧捕获?
我怎样才能解决这个问题?我是否应该重命名 exported secondary 库中的所有函数?或者 唯一 可行的方法是使用 单个 库并 深入研究 实现的东西?
您可以 dlopen
三个库中的每一个在启动时获取它们的句柄,并使用它们调用 dlsym(h, "f")
以获得 f
的特定实现。如果您事先不知道库名称,您可以使用 dl_iterate_phdr
来获取它们(例如参见 [=14=])。