有没有一种简单而有效的办法知道一个给定的动态链接ELF
是缺少必要的.所以它的运行,所有从内一个C/C++程序的?
我需要一个具有某些类似功能的程序ldd
,而不是试图执行ELF
以找出系统中的(met/unmet)依赖项.也许通过一些库询问ld-linux.so实用程序?(我是这部分linux的新手=)
注意:阅读源代码
ldd
对我的意图不是很有帮助:它似乎ldd
实际上是在分支另一个进程并执行程序.
如果在不执行程序的情况下无法知道程序是否存在未满足的依赖项,是否有某种方法可以至少快速地ELF
从我的程序中列出所有的.so所需的内容?
在此先感谢=)
首先,请记住我是linux的新手.我在编译项目时遇到问题.我一直收到以下错误:
/ usr/bin/ld:CMakeFiles/Robot.dir/source/ModuleHandler.cpp.o:对符号'dlsym @@ GLIBC_2.4'的未定义引用//lib/arm-linux-gnueabihf/libdl.so.2:error添加符号:命令行collect2中缺少DSO:ld返回1退出状态
首先关闭正确的目录是:/usr/lib/arm-linux-gnueabihf/libdl.so
而不是://lib/arm-linux-gnueabihf/libdl.so
我已经尝试更新我的ldconfig.conf文件,设置LD_LIBRARY_PATH
,使用ldd -r
无济于事.
CMAKE用于创建make文件.
我以前没有编译问题.它是在我进行apt-get升级或从VS尝试交叉编译之后开始的.
任何建议将不胜感激!
//弥敦道
我试图找出Qt Assistant
需要部署的库.我ldd
在Linux上用过这个.
我发现它ldd
提供了-u
"打印未使用的依赖项" 的选项.这听起来像是某种依赖(部署)不需要(总是).所以我再运行了两个ldd
命令:
~$ ldd -u ~/Qt/5.10.0/gcc_64/bin/assistant
Unused direct dependencies:
/lib/x86_64-linux-gnu/libQt5Network.so.5
/lib/x86_64-linux-gnu/libQt5Sql.so.5
/lib/x86_64-linux-gnu/mesa/libGL.so.1
/lib/x86_64-linux-gnu/libpthread.so.0
/lib/x86_64-linux-gnu/libm.so.6
/lib/x86_64-linux-gnu/libgcc_s.so.1
~$ ldd -r -u ~/Qt/5.10.0/gcc_64/bin/assistant
Unused direct dependencies:
/lib/x86_64-linux-gnu/libQt5Network.so.5
/lib/x86_64-linux-gnu/mesa/libGL.so.1
/lib/x86_64-linux-gnu/libpthread.so.0
/lib/x86_64-linux-gnu/libm.so.6
/lib/x86_64-linux-gnu/libgcc_s.so.1
Run Code Online (Sandbox Code Playgroud)
我试图找出发生了什么,但我并没有完全理解它.
我的问题是:
Qt Assistant
实际上是否需要一个未使用的直接依赖(除了启动它并等待错误)?libQt5Sql
却没有第二个列表?我有一个应用程序,我正在构建使用NetCDF C++库,NetCDF正在拉入HDF-4库.然而,它正在吸引错误的 HDF-4库.
这是我的应用程序的链接方式:
/apps1/intel/bin/icpc -gxx-name=/apps1/gcc-4.5.0/bin/g++ -shared -o lib/libMyCustom.so
-Llib -L/apps1/boost-1.48.0/lib -Wl,-rpath=/apps1/boost-1.48.0/lib
-L/apps1/gdal-1.8.0-jasper/lib -Wl,-rpath=/apps1/gdal-1.8.0-jasper/lib
-L/new_apps1/hdf4/lib -Wl,-rpath=/new_apps1/hdf4/lib -L/new_apps1/netcdf/lib
-Wl,-rpath=/new_apps1/netcdf/lib -lboost_system -lboost_serialization
-lboost_date_time -lboost_thread -lgdal -ldf -lmfhdf -lnetcdf_c++
MyProj/obj/ProjUtility.o MyProj/obj/ProjMetadataException.o
MyProj/obj/ProjTimestampUtil.o
Run Code Online (Sandbox Code Playgroud)
我设置了LD_LIBRARY_PATH非常短:
LD_LIBRARY_PATH=/new_apps1/hdf4/lib:/new_apps1/hdf5/lib:
/apps1/intel/composerxe/lib/intel64:/apps1/gcc-4.5.0/lib64:/apps1/gcc-4.5.0/lib
Run Code Online (Sandbox Code Playgroud)
这里是ldd -v输出的摘录:
libdf.so.0 => /new_apps1/hdf4/lib/libdf.so.0 (0x00002af5baabc000)
libmfhdf.so.0 => /new_apps1/hdf4/lib/libmfhdf.so.0 (0x00002af5bad61000)
libnetcdf_c++.so.5 => /new_apps1/netcdf/lib/libnetcdf_c++.so.5 (0x00002af5baf85000)
libhdf5.so.6 => /new_apps1/hdf5/lib/libhdf5.so.6 (0x00002af5bd1e7000)
libgif.so.4 => /usr/lib64/libgif.so.4 (0x0000003a6bc00000)
libpng12.so.0 => /usr/lib64/libpng12.so.0 (0x0000003a71000000)
libnetcdf.so.6 => /new_apps1/netcdf/lib/libnetcdf.so.6 (0x00002af5bd682000)
libhdf5_hl.so.6 => /new_apps1/hdf5/lib/libhdf5_hl.so.6 (0x00002af5be272000)
/new_apps1/hdf4/lib/libdf.so.0:
libc.so.6 (GLIBC_2.3) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
/new_apps1/hdf4/lib/libmfhdf.so.0:
libc.so.6 (GLIBC_2.2.5) => …
Run Code Online (Sandbox Code Playgroud) 在Linux上,我有一个使用dlopen()来加载一些共享库的C++应用程序,但我怀疑正在加载的共享库的版本不是我期望的版本,因为我的调试跟踪代码似乎不是执行.
有没有办法检查正在运行的进程来查询它当前打开的所有共享库以及每个库的路径?换句话说,类似于ldd
但可以在正在运行的可执行文件上运行的东西,并列出运行时加载的库.
我有一个较旧的二进制可执行文件(utserver,闭源),我试图在运行 Fedora 22 的系统上运行它。
utserver 需要 openssl_1.0.0 - F22 提供 openssl_1.0.1k
我做了两个符号链接:
$ sudo ln -s /usr/lib64/libssl.so.1.0.1k /usr/lib64/libssl.so.1.0.0
$ sudo ln -s /usr/lib64/libcrypto.so.1.0.1k /usr/lib64/libcrypto.so.1.0.0
Run Code Online (Sandbox Code Playgroud)
但是尝试运行 utserver 会抱怨库版本:
$ ./utserver
./utserver: /lib64/libcrypto.so.1.0.0: version `OPENSSL_1.0.0' not found (required by ./utserver)
./utserver: /lib64/libssl.so.1.0.0: version `OPENSSL_1.0.0' not found (required by ./utserver)
Run Code Online (Sandbox Code Playgroud)
好的,所以它正在寻找一个版本字符串。我编辑了 utserver ELF 以将字符串 OPENSSL_1.0.0 更改为 OPENSSL_1.0.1,但出现相同的错误(未找到“OPENSSL_1.0.1”)
objdump 和 readelf 都显示 OPENSSL_1.0.1 存在于 libssl.so.1.0.1 的版本区域中:
$ objdump -p /lib64/libssl.so.1.0.1 | grep OPENSSL
3 0x00 0x066a2b21 OPENSSL_1.0.1
4 0x00 0x02b21533 OPENSSL_1.0.1_EC
0x02b21533 0x00 07 …
Run Code Online (Sandbox Code Playgroud) 我的Python代码给出了这个错误:
from cv_bridge import CvBridge, CvBridgeError
导入错误:libcv_bridge.so:无法打开共享对象文件:没有这样的文件或目录。
但是,如果我做 ldd,一切似乎都很好。怎么了?(ROS indigo、ubuntu 14.04 LTS、PyCharm)
user@user-VirtualBox:/opt/ros/indigo/lib$ ldd libcv_bridge.so
linux-vdso.so.1 => (0x00007ffc9439d000)
libopencv_imgproc.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_imgproc.so.2.4 (0x00007fcac6b34000)
libopencv_highgui.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4 (0x00007fcac68e9000)
libopencv_core.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_core.so.2.4 (0x00007fcac64b1000)
libopencv_contrib.so.2.4 => /usr/lib/x86_64-linux-gnu/libopencv_contrib.so.2.4 (0x00007fcac61ce000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fcac5eca000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fcac5cb3000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcac58ee000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fcac56d0000)
libtbb.so.2 => /usr/lib/libtbb.so.2 (0x00007fcac549b000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fcac5195000)
libGL.so.1 => /var/lib/VBoxGuestAdditions/lib/libGL.so.1 (0x00007fcac4f5d000)
libjpeg.so.8 => /usr/lib/x86_64-linux-gnu/libjpeg.so.8 (0x00007fcac4d07000)
libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007fcac4ae1000)
libtiff.so.5 => /usr/lib/x86_64-linux-gnu/libtiff.so.5 (0x00007fcac486f000)
libjasper.so.1 => /usr/lib/x86_64-linux-gnu/libjasper.so.1 (0x00007fcac4617000)
libIlmImf.so.6 => …
Run Code Online (Sandbox Code Playgroud) 什么是最便携,最健壮的方法来获取路径列表,/etc/ld.so.conf
由它们配置和包含的文件?手动解析文件似乎不是一个好主意 - 格式可能会在将来的版本中发生变化.
为了更好地理解这个问题,我将在下面给出具体细节.请注意,尽管有这些细节,但这是一个通用编程问题,适用于其他情况.
有一个名为LuaRocks的程序.它是Lua编程语言的包管理器(有点像Ruby gems或Python eggs).LuaRocks包被称为"岩石".
作为一个便利功能,LuaRocks允许摇滚作者为摇滚指定外部依赖项列表,并将其表达为C头文件和/或动态库文件的列表.(.so在Linux上.)如果指定的文件不存在,则无法安装摇滚.
目前,在Linux上,默认检查LuaRocks通过搜索两个文件.so文件所有脑干硬编码路径,/usr/lib
和/usr/local/lib
.
我认为这是不正确的行为,并且最近Ubuntu和其他Debian发行版的更改打破了它.
更新:路径本身不是硬编码的,但在配置文件中是用户可配置的.仍然,IMO,不是最好的解决方案.
相反(据我所知),LuaRocks应该在路径中查找文件,由/etc/ld.so.conf
它指定的文件和文件.
(现在请重新阅读上面的问题;-))
我正在编译一些代码,出于各种原因,我正在静态地进行。在我的 Ubuntu 12.04 / gcc 4.6.3 机器上,它编译执行得很好,并且是完全静态的:
> ldd mycode
not a dynamic executable
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好。但我还需要在另一台机器上运行它,Scientific Linux 5 系统,运行 gcc 4.5.3。出于某种原因, ldd 还剩下一些动态库:
> ldd mycode
linux-vdso.so.1 => (0x00007fffd75fd000)
libstdc++.so.6 => /usr/local/swift/gcc-4.5.3/lib64/libstdc++.so.6 (0x00002b4bafab2000)
libm.so.6 => /lib64/libm.so.6 (0x000000398ca00000)
libc.so.6 => /lib64/libc.so.6 (0x000000398c600000)
/lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x000000398c200000)
libgcc_s.so.1 => /usr/local/swift/gcc-4.5.3/lib64/libgcc_s.so.1 (0x00002b4bafdb8000)
Run Code Online (Sandbox Code Playgroud)
这本身就很好。代码编译链接OK,从ldd可以看到,所有的依赖都解决了。但是,当我尝试在 SL 机器上执行它时,它失败了:
> ./mycode
/lib/ld64.so.1: bad ELF interpreter: No such file or directory
Run Code Online (Sandbox Code Playgroud)
因此,据我所知,在执行时由于某种原因/lib/ld64.so.1 => /lib64/ld-linux-x86-64.so.2
链接没有被解析,即使 ldd 做到了。当然,在我有 root 访问权限的机器上,我可以通过从 ld-linux-x84..blah 到 /lib/ld64.so.1 建立符号链接来解决这个问题,但这是一个相当糟糕的解决方案,我不能申请它到我们的集群。如果我动态编译整个东西,它工作正常,但这意味着在一堆我想避免的机器上安装我正在编译的所有 3rd 方库。最后,我编译的所有依赖项也被另一个项目使用,也是用cmake编译的,在这种情况下我没有问题,而且ldd实际上列出了/lib64/ld-linux...blah直接,而不是调用到/lib/ld64.so。
那么 - 为什么会发生这种情况?为什么我可以编译和链接代码OK,ldd它OK,但不执行它?任何想法将不胜感激!
我创建了一个新项目,用stack
它创建了一个项目resolver: lts-16.12
。当使用 运行示例.hs
文件时stack runghc src/MyExample.hs
,它工作正常,但我在运行之前也得到了这些:
/home/lpied/.stack/programs/x86_64-linux/ghc-8.8.4/lib/ghc-8.8.4/bin/ghc: /lib64/libtinfo.so.5: no version information available (required by /home/lpied/.stack/programs/x86_64-linux/ghc-8.8.4/lib/ghc-8.8.4/bin/../haskeline-0.7.5.0/libHShaskeline-0.7.5.0-ghc8.8.4.so)
/home/lpied/.stack/programs/x86_64-linux/ghc-8.8.4/lib/ghc-8.8.4/bin/ghc: /lib64/libtinfo.so.5: no version information available (required by /home/lpied/.stack/programs/x86_64-linux/ghc-8.8.4/lib/ghc-8.8.4/bin/../ghc-8.8.4/libHSghc-8.8.4-ghc8.8.4.so)
/home/lpied/.stack/programs/x86_64-linux/ghc-8.8.4/lib/ghc-8.8.4/bin/ghc: /lib64/libtinfo.so.5: no version information available (required by /home/lpied/.stack/programs/x86_64-linux/ghc-8.8.4/lib/ghc-8.8.4/bin/../terminfo-0.4.1.4/libHSterminfo-0.4.1.4-ghc8.8.4.so)
Run Code Online (Sandbox Code Playgroud)
我已经阅读过诸如此类的内容,并且可以确认有问题的库:
$ ll /lib64/libtinfo.so.5
lrwxrwxrwx. 1 root root 15 Aug 08 19:47 /lib64/libtinfo.so.5 -> libtinfo.so.5.9
Run Code Online (Sandbox Code Playgroud)
不具有VERDEF
/ .gnu.version_d
:
$ readelf -V /lib64/libtinfo.so.5|grep gnu
Version symbols section '.gnu.version' contains 245 entries:
Version needs section '.gnu.version_r' contains 1 …
Run Code Online (Sandbox Code Playgroud)