LD_AUDIT 是动态链接器提供的插桩接口,能监控 SO 加载/卸载/符号解析等底层动作,但仅对动态链接生效,不涉及 C++ 语义;需用 extern "C" 导出函数,禁用异常与 RTTI,并以绝对路径设置 LD_AUDIT。

什么是 LD_AUDIT,它真能监控 C++ 程序的 SO 加载?
能,但只对动态链接过程生效,且不关心 C++ 语义(比如类构造、模板实例化),只管 dlopen、DT_NEEDED、符号解析这些底层动作。它不是调试器,也不是 profiler,而是一个由动态链接器 ld-linux.so 提供的“插桩接口”——你写一个 audit 库,链接时用 LD_AUDIT 指向它,后续所有被审计进程的共享库加载/卸载/符号查找都会回调你的函数。
注意:它对静态链接的代码、RTLD_LOCAL 下未导出符号的 dlopen、以及被 LD_PRELOAD 覆盖掉的符号解析行为,监控效果会打折扣。
la_objopen 和 la_objclose 怎么抓到真正加载的 SO?
这两个是 audit 接口里最常用的入口点:la_objopen 在每个对象(主程序、依赖 SO、dlopen 打开的 SO)被映射进内存后立即调用;la_objclose 在其卸载前触发。但它们不保证“首次加载”——同一个 SO 多次 dlopen 可能只触发一次 la_objopen(因为已驻留),而 la_objclose 也只在引用计数归零时才来。
- 用
cookie参数区分不同加载实例(它由链接器分配,同一 SO 多次dlopen会得不同 cookie) -
name字符串可能为空(如主可执行文件)或为绝对路径(如/lib/x86_64-linux-gnu/libc.so.6),别直接strcmp判空,先检查指针是否非 NULL - 不要在
la_objopen里调用printf或malloc—— 此时 libc 可能尚未完全初始化,应使用write(2)+ 栈缓冲区
C++ 编译 audit 库要注意哪些 ABI 和符号问题?
audit 库必须是共享库(.so),且必须用 C 风格符号导出(extern "C"),否则链接器找不到 la_version、la_objopen 等入口。C++ 编译器默认 name mangling,不加修饰就会链接失败。
常见错误现象:ld-linux.so: audit function la_objopen not found 或程序直接 abort。
- 所有 audit 函数声明必须包在
extern "C"块里 - 编译时禁用 C++ 异常和 RTTI:
-fno-exceptions -fno-rtti,避免引入不可控的 libcxxabi 依赖 - 链接时不能带
-lstdc++,audit 库运行在 libc 初始化之前,std::string / iostream 会崩溃 - 示例最小骨架:
extern "C" { unsigned int la_version(unsigned int v) { return LAV_VERSION; } uint32_t la_objopen(uintptr_t *cookie, const char *file, uintptr_t *loadaddr, uint32_t *type) { write(2, "loaded: ", 8); if (file) write(2, file, strlen(file)); write(2, "\n", 1); return LA_FLG_BINDTO | LA_FLG_BINDFROM; } }为什么设置了
LD_AUDIT却没看到输出?最常见原因是权限或路径问题:audit 库必须有可执行权限,且不能依赖其他未预加载的 SO;另外,
LD_AUDIT不继承给子进程,system()或fork+exec启动的程序不会自动带上它。- 确保 audit 库是
chmod +x的,并用绝对路径指定:LD_AUDIT=/abs/path/to/audit.so ./a.out - 目标程序不能是 setuid/setgid,否则
LD_AUDIT被内核忽略(安全限制) - 用
readelf -d ./a.out | grep NEEDED确认它确实依赖动态链接器(即不是静态链接的musl或staticx打包产物) - 若用 GDB 调试,
LD_AUDIT会被绕过——GDB 自己接管了加载流程,得用set exec-wrapper /path/to/ld-linux.so --audit /path/to/audit.so
audit 的时机非常早,早于 main,也早于大多数日志框架初始化。想确认它是否跑起来,最靠谱的方式是用
strace -e trace=openat,open,write看有没有你的 write 系统调用出现。 - 确保 audit 库是
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











