linux下通过解析/proc/self/maps过滤出绝对路径且存在的.so文件,windows下用enumprocessmodules配合getmodulefilenameexa获取dll路径,跨平台需统一处理伪路径和权限问题。

Linux下用/proc/self/maps解析已加载的共享库路径
Linux没有标准API直接列出所有已加载的.so路径,但/proc/self/maps是可靠来源——它记录了当前进程所有内存映射段,其中包含可执行文件、堆、栈和动态库的映射信息。关键是要过滤出类型为shared library且路径以.so结尾(或含/lib、/usr/lib等典型路径)的行。
常见错误是只匹配.so字符串,结果会误抓到带.so的普通文件(比如libfoo.so.debug或临时文件)。更稳妥的做法是:先按空格分割每行,取第6字段(即路径),再检查该路径是否为绝对路径、是否存在、且stat()确认是常规文件而非设备节点或符号链接(除非你明确需要符号链接目标)。
- 用
std::ifstream逐行读/proc/self/maps,避免一次性加载大文件 - 跳过无路径字段的行(如
[heap]、[stack]) - 对提取出的路径调用
access(path.c_str(), R_OK)验证可读性,防止因权限或卸载导致的失效路径 - 注意同一库可能被多次映射(如不同权限段),用
std::set<:string></:string>去重
Windows下用EnumProcessModules配合GetModuleFileNameExA
Windows需启用SE_DEBUG_NAME权限才能枚举其他进程模块,但当前进程不需要——直接调用EnumProcessModules即可获取模块句柄列表,再对每个句柄调用GetModuleFileNameExA得到全路径。
容易踩的坑是忽略GetModuleFileNameExA返回值:它返回实际写入字符数,若缓冲区不够会截断且不报错;更糟的是某些系统DLL(如ntdll.dll)在低权限下可能返回空字符串。必须检查返回值是否为0或等于MAX_PATH-1(暗示截断)。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 缓冲区至少申请
MAX_PATH字节,推荐用std::vector<char>(MAX_PATH)</char>避免栈溢出 - 对每个
HMODULE调用GetModuleFileNameExA前,先用GetModuleBaseNameA快速筛掉明显不是DLL的模块名(如kernel32不含路径,可跳过) -
EnumProcessModules可能因模块正在卸载而失败,建议加try/catch或检查GetLastError()是否为ERROR_PARTIAL_COPY
C++跨平台封装时别硬编码路径分隔符或扩展名
写个统一接口时,.so和.dll只是表象,真正要识别的是“被dlopen/dll加载且仍在内存中的共享模块”。不能简单按扩展名过滤——比如Windows上有些驱动用.sys,Linux上也有.ko内核模块(虽然用户态进程通常不加载),甚至存在无扩展名的库(如/lib64/ld-linux-x86-64.so.2)。
更健壮的策略是:Linux侧优先信任/proc/self/maps中路径字段;Windows侧信任GetModuleFileNameExA返回值;两者都应跳过路径为空、含[括号(如[vdso])、或明显不属于文件系统的伪路径。
- 用
#ifdef _WIN32区分平台逻辑,避免运行时探测OS类型 - 路径拼接一律用
std::filesystem::path(C++17)或手动判断PATH_SEPARATOR,别写死/或\ - 返回结果用
std::vector<:string></:string>,不保证顺序——/proc/self/maps按地址升序,Windows枚举顺序不确定
调试时发现路径缺失?先查LD_DEBUG=libs或Process Explorer
如果代码跑出来缺某些库(比如libstdc++.so.6没列出来),不是代码漏了,而是这些库可能被标记为PT_INTERP(解释器)或通过RTLD_NODELETE加载但未出现在maps里——它们属于加载器自身依赖,不在用户模块列表中。
此时别改代码,先用外部工具交叉验证:LD_DEBUG=libs ./your_program 2>&1 | grep "calling init"能打印所有dlopen路径;Windows下用Process Explorer的“Lower Pane → DLLs”视图比API更全,尤其对注入的DLL。
-
LD_DEBUG输出极多,建议重定向到文件后grep -E '\.so|\.dll' - Process Explorer需以管理员运行才显示完整DLL列表,否则可能缺系统级模块
- 某些嵌入式环境(如musl libc)不支持
/proc/self/maps,得回退到dl_iterate_phdr(但仅限ELF,且不返回路径)
/proc/self/maps和EnumProcessModules覆盖95%场景,剩下那些边界情况——比如被LD_PRELOAD劫持的库、或dlopen后dlclose前的瞬态模块——根本没法靠一次快照捕获全。真要追踪动态加载行为,得上ptrace或ETW。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










