Linux动态链接C程序:动态库是启动加载还是按需加载?
Linux动态链接库的加载逻辑解析
加载时机:启动时就加载所有依赖库
对于编译阶段通过-l参数指定链接的共享库(也就是你说的"必要共享库"),Linux的动态链接器ld-linux.so是在程序启动时就把所有依赖的.so文件全部加载到进程地址空间,不是等调用库中函数的时候才加载。
举个实际例子:你用gcc main.c -lm编译程序链接数学库libm.so,哪怕你的代码里压根没调用sin()、sqrt()这些数学函数,启动程序时动态链接器也会先找到libm.so并完成加载。
唯一的例外是用dlopen()、dlsym()这类API手动加载的共享库——这种是你代码里调用dlopen()时才会加载,属于运行时按需加载,但这不属于编译时固定指定的依赖范畴。
如何识别函数所属的库?靠这两个关键信息
动态链接器能精准匹配函数和对应库,核心依赖两个部分的信息:
- 可执行文件的动态段:编译生成的可执行文件里,有个叫
.dynamic的段,其中DT_NEEDED条目会列出所有需要依赖的共享库名单;同时还会记录可执行文件里哪些符号(函数、变量)需要从外部库中解析。 - 共享库的符号表:每个
.so文件自身都带符号表,里面清晰记录了库对外导出的所有函数、变量名称,以及它们在库内部的地址偏移。
启动程序时,动态链接器的工作流程是:
- 先读取可执行文件的
DT_NEEDED列表,找到所有要加载的共享库; - 把每个库加载到进程内存后,将库的符号表和可执行文件里未解析的符号一一匹配;
- 最后把可执行文件中调用外部函数的位置,替换成对应库中函数的实际内存地址。
你可以用readelf -d <你的可执行文件>命令查看DT_NEEDED的依赖库列表,用nm -D <目标.so文件>查看库导出的所有符号。
内容的提问来源于stack exchange,提问作者Engineer999
相关产品推荐
相关产品推荐

