程序换到新服务器上跑不起来,报error while loading shared libraries,第一个想到的就是ldd,敲一下就能知道它到底在找哪些库。
ldd就是列依赖,用法很简单
ldd ./myapp输出每行左边是库名,右边是它找到的路径。看到not found,说明这个库在本机没有,或者路径不在搜索范围内,程序自然起不来。
libmysqlclient.so.21 => not foundlibc.so.6 => /lib64/libc.so.6第一行就是问题所在,第二行是正常的。定位到缺哪个,装对应的包或者把库拷到搜索路径下就行。
库找不到,按这个顺序查
- 看有没有装:用rpm或dpkg反查库属于哪个包
- 看搜索路径:ldconfig -p 列出系统缓存里的库,缓存没更新也会找不到
- 看环境变量:LD_LIBRARY_PATH有没有包含你自己编译的库目录
ldconfig -p | grep libmysqlexport LD_LIBRARY_PATH=/opt/app/lib几个容易忽略的点
一是ldd会实际加载程序,对不可信来源的二进制文件别随便ldd,有被利用执行代码的风险,这是圈里公认的坑。看不可信文件用objdump或者readelf -d更安全。
二是它显示的是当前用户环境下的结果,换了用户、换了容器,结果可能不一样。容器里排查,要进到容器内部去跑,别只看宿主机。
三是环境变量只在当前会话生效,要长期生效得写进启动脚本或者放进ld.so.conf.d目录再执行ldconfig刷新缓存。
一句话取舍:排查启动报错,ldd先用来看依赖,确认可疑文件来源时,换readelf更稳妥。