什么时候才可以使用 dlsym 在另一个共享库中查找函数?

问题描述 投票:0回答:1

假设我有一个与

foo
链接的应用程序
bar.so
。我有另一个库
buzz.so
,应用程序不直接链接,但当我使用
LD_PRELOAD
运行应用程序时使用它,如下所示:
LD_PRELOAD=buzz.so ./foo
。现在我希望
buzz.so
能够使用
dlsym
来查找
bar.so
内的符号。我的问题是:dlsym 调用最早可以成功的时间点是什么?当时如何运行函数?

GCC/Clang 支持使用

__constructor__((priority))
属性注释函数,使它们在
main
之前运行,但据我所知,没有任何优先级数字与确保所有共享库都已加载相对应。

linux dynamic-linking ld-preload dlsym
1个回答
0
投票

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
    
© www.soinside.com 2019 - 2024. All rights reserved.