You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LD_PRELOAD加载的共享库中,调用dlsym查找符号的最早可行时机

关于LD_PRELOAD库中dlsym查找依赖库符号的时机问题

最早成功的时间点

当通过LD_PRELOAD=buzz.so ./foo启动程序时,动态链接器会先完成所有必要共享库的加载与符号重定位——包括主程序foo直接链接的bar.so,以及bar.so的间接依赖库,之后才会执行任何构造函数。因此,buzz.so中能成功调用dlsym查找bar.so符号的最早时间点,就是buzz.so的构造函数执行阶段——哪怕是优先级最高的构造函数,此时bar.so已经被加载到进程地址空间,符号也已完成解析,dlsym调用必然成功。

如何在该时机执行函数

GCC/Clang的__constructor__属性可以指定构造函数的执行优先级,结合这个特性可以精准控制执行时机:

  • 优先级数值范围为0到100,数值越小,构造函数执行越早;未指定优先级的构造函数默认使用100。
  • 若无需等待其他库的构造函数,直接使用默认优先级即可:
    #include <dlfcn.h>
    
    __attribute__((constructor))
    void buzz_init() {
        // 查找bar.so中的目标符号,RTLD_DEFAULT搜索全局符号表
        void (*bar_func)() = dlsym(RTLD_DEFAULT, "bar_target_function");
        if (bar_func) {
            bar_func();
        }
    }
    
  • 若需要确保在主程序或bar.so的构造函数之后执行(避免干扰其他初始化逻辑),可以将优先级设为大于100的数值(比如101):
    __attribute__((constructor(101)))
    void buzz_late_init() {
        // 此处执行的逻辑会在默认优先级的构造函数之后运行
        void *sym = dlsym(RTLD_DEFAULT, "bar_another_function");
        // ...
    }
    

关键注意事项

  • 编译buzz.so时必须链接dl库:添加-ldl编译选项,否则dlsym、dlopen等函数会出现未定义引用错误。
  • 若要更精准指定查找bar.so的符号,可以先用dlopen("bar.so", RTLD_NOLOAD)获取bar.so的句柄(该选项不会重复加载库),再用此句柄调用dlsym,避免全局符号表的歧义。
  • 即使bar.so使用延迟加载(-z lazy),dlsym调用也会触发符号解析,不会影响查找结果。

内容的提问来源于stack exchange,提问作者Joseph Garvin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 06:55:00