假设我有一个与
foo
链接的应用程序 bar.so
。我有另一个库 buzz.so
,应用程序不直接链接,但当我使用 LD_PRELOAD
运行应用程序时使用它,如下所示:LD_PRELOAD=buzz.so ./foo
。现在我希望 buzz.so
能够使用 dlsym
来查找 bar.so
内的符号。我的问题是:dlsym 调用最早可以成功的时间点是什么?当时如何运行函数?
GCC/Clang 支持使用
__constructor__((priority))
属性注释函数,使它们在 main
之前运行,但据我所知,没有任何优先级数字与确保所有共享库都已加载相对应。
dlsym 调用最早可以成功的时间点是什么?那时如何运行函数?
当
buzz.so
初始化时,没有什么可以阻止它使用 dlopen()
来加载 bar.so
,一旦 dlopen()
完成,您就可以使用 dlsym()
。
事实上
bar.so
也是 main
的依赖项(因此
bar.so
将在稍后作为加载
main
的一部分进行加载)是无关紧要的。示例:
// main.c
extern int bar();
int main() { return bar(); }
// bar.c
int bar() { return 42; }
// buzz.c
#include <dlfcn.h>
#include <stdio.h>
__attribute__((constructor)) void init_buzz()
{
printf("loading bar.so\n");
void *handle = dlopen("./bar.so", RTLD_LAZY|RTLD_GLOBAL);
if (handle == NULL) {
fprintf(stderr, "dlopen: %s\n", dlerror());
return;
}
int (*pbar)() = (int (*)()) dlsym(handle, "bar");
if (pbar == NULL) {
fprintf(stderr, "dlsym: %s\n", dlerror());
return;
}
printf("bar.so bar() = %d\n", (*pbar)());
}
把它们放在一起:
gcc -fPIC -shared -o bar.so bar.c &&
gcc main.c ./bar.so &&
gcc -fPIC -shared -o buzz.so buzz.c -ldl
./a.out ; echo $?
42
LD_PRELOAD=./buzz.so ./a.out
loading bar.so
bar.so bar() = 42