麒麟系统排查软件异常需分三步:先用ldd查静态依赖是否缺失;再用strace捕获运行时真实加载的.so路径;最后用pstack或/proc/PID/maps查看已驻留内存的动态库。

在麒麟系统中排查特定软件启动失败或运行异常时,需精准定位它实际加载了哪些动态库、是否缺失或版本错配,而不是仅看编译时的依赖声明。
用 ldd 查看程序静态链接的动态库列表
ldd 命令解析可执行文件的 ELF 头和 .dynamic 段,列出所有声明依赖的共享库路径及是否能找到。它不反映运行时实际加载行为,但能快速暴露“not found”类硬性缺失。
执行:ldd /opt/myapp/bin/myserver | grep "not found"
若输出为空,说明所有声明依赖的 .so 文件在当前环境都能被 ld.so 找到;若有行显示“xxx.so => not found”,则该库未被识别,需检查是否在 /usr/local/lib、/opt/myapp/lib 等路径下,或是否漏加到 ldconfig 配置中。
【注意:ldd 本质是通过伪造 _dl_main 调用 libc 的 loader,对 setuid 程序会拒绝执行,此时应改用 readelf -d】
用 strace 实时捕获进程运行时真实加载的动态库
当程序能启动但中途崩溃,或 ldd 显示全绿却仍报“symbol lookup error”,说明问题出在运行时动态加载(如 dlopen)、或库版本冲突,必须用 strace 抓取真实系统调用链。
第一步:准备一个干净终端,确保目标程序未在运行;
第二步:执行 strace -e trace=openat,open,openat2,stat -f -o myapp_trace.log -- ./myapp > /dev/null 2>&1 &
第三步:等待程序完成初始化(例如打印出“listening on port 8080”后),立即按 Ctrl+C 终止 strace;
第四步:用 grep -E '\.so|\.dll' myapp_trace.log | grep -v 'ENOENT' 提取所有成功打开的动态库绝对路径——这些才是进程真正加载进内存的文件。
这一步绕过了 ldconfig 缓存和环境变量干扰,直接看到内核返回的 openat() 成功结果,比 ldd 更可信。
用 pstack + cat /proc/PID/maps 定位正在运行进程的已加载库
适用于程序已卡死、假死或后台常驻场景,你想知道此刻它内存里到底驻留了哪些 .so。
方法一:先查 PID,再读映射
执行:pgrep -f "myapp" → 得到 PID(如 12345);
然后执行:cat /proc/12345/maps | awk '$6 ~ /\.so$/ {print $6}' | sort -u
方法二:一步到位(需安装 pstack)
执行:pstack 12345 2>/dev/null | grep '\.so' | sed 's/.*\(\/.*\.so[^ ]*\).*/\1/' | sort -u
【关键点:/proc/PID/maps 中的 .so 行必须第6列以“.so”结尾,且不能含空格;过滤掉 /lib/x86_64-linux-gnu/ld-2.31.so 这类解释器自身】

















