ldd能查C++程序依赖,因g++生成的仍是标准ELF文件,动态链接由链接器决定而非语言;只要未-static链接,必依赖libstdc++.so.6和libc.so.6等,ldd通过解析ELF的DT_NEEDED段获取这些动态库信息。

直接用 ldd 查 C++ 可执行文件,和查 C 的完全一样——C++ 本身不改变 ELF 依赖机制,关键看链接方式。
为什么 ldd 能查 C++ 程序的依赖
C++ 编译器(如 g++)生成的可执行文件仍是标准 ELF 格式,动态链接行为由链接器(ld)决定,不是语言决定的。只要没加 -static,它就依赖 libstdc++.so、libc.so.6 等动态库。
-
ldd不关心源码是 C 还是 C++,只解析 ELF 的DT_NEEDED段 - 典型输出里一定有
libstdc++.so.6和libc.so.6,这是 C++ 程序的“标配”依赖 - 如果你用了 Boost、Qt 或自定义
.so,它们也会列在ldd输出中
ldd 输出里看到 libstdc++.so.6 => not found 怎么办
这说明系统缺少 GCC 的 C++ 标准库运行时,不是你代码写错了,而是环境没配好。
- Debian/Ubuntu:运行
sudo apt install libstdc++6 - CentOS/RHEL:运行
sudo yum install libstdc++或dnf install libstdc++ - 别手动复制
libstdc++.so.6文件——版本错位会导致undefined symbol错误 - 检查是否混用了不同 GCC 版本构建的库:用
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX看支持的 ABI 版本
为什么 ldd ./myapp 显示正常,但运行时报 cannot open shared object file
因为 ldd 默认受当前 shell 环境影响,而真实运行环境可能没有那些变量。
立即学习“C++免费学习笔记(深入)”;
- 运行前清掉干扰:
LD_LIBRARY_PATH= ldd ./myapp—— 这才接近生产环境行为 - 如果此时出现
not found,说明程序依赖的路径没进系统缓存,得用ldconfig或-rpath - 检查
RPATH是否被硬编码:readelf -d ./myapp | grep RPATH,它优先级高于LD_LIBRARY_PATH - 注意:C++ 模板实例化、异常处理、RTTI 都依赖
libstdc++.so.6,缺它连main()都进不去
安全起见,对第三方 C++ 二进制该用什么替代 ldd
不要对不可信的 C++ 可执行文件跑 ldd,它可能触发恶意代码片段(尤其含构造函数的全局对象)。
- 用
readelf -d ./untrusted_binary | grep NEEDED—— 只读 ELF 头,零风险 - 输出的是
soname,比如[libboost_filesystem.so.1.74.0],不是路径,但能确认它要什么 - 搭配
objdump -p ./binary | grep NEEDED做交叉验证,结果一致才可信 - 若需确认是否真静态链接:
file ./myapp输出含statically linked才算数,ldd显示not a dynamic executable是 fallback 提示,不一定准
真正容易被忽略的是:C++ 程序的依赖链往往比 C 更深——libstdc++.so.6 自己又依赖 libgcc_s.so.1,而后者可能再依赖 libc.so.6。用 ldd -v 看完整树形依赖时,得一层层核对 soname 和实际文件名是否匹配,尤其是带版本号的 .so.x.y.z 文件。


















