微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的Linux应用程序拉错了.so库?

我有一个使用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

我已经设置了我的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

这里是从ldd -v输出摘录:

在Windows 7上从Java启动CYGWIN构build的可执行文件失败,“加载共享库时出错:?:没有这样的文件或目录”

依赖于相同静态链接库的可执行文件和共享库

一些关于GCC链接器search顺序的问题

如何控制Windows DLL从应用程序导入哪些符号?

如何使分析器(valgrind,perf,pprof)在使用mpirun时选取/使用具有debugging符号的库的本地版本?

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) => /lib64/libc.so.6 /new_apps1/netcdf/lib/libnetcdf_c++.so.5: libgcc_s.so.1 (GCC_3.0) => /apps1/gcc-4.5.0/lib64/libgcc_s.so.1 libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6 libstdc++.so.6 (CXXABI_1.3) => /apps1/gcc-4.5.0/lib64/libstdc++.so.6 libstdc++.so.6 (GLIBCXX_3.4) => /apps1/gcc-4.5.0/lib64/libstdc++.so.6 /new_apps1/hdf5/lib/libhdf5.so.6: libm.so.6 (GLIBC_2.2.5) => /lib64/libm.so.6 libc.so.6 (GLIBC_2.3) => /lib64/libc.so.6 libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6 /new_apps1/netcdf/lib/libnetcdf.so.6: libm.so.6 (GLIBC_2.2.5) => /lib64/libm.so.6 libc.so.6 (GLIBC_2.3) => /lib64/libc.so.6 libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6 /new_apps1/hdf5/lib/libhdf5_hl.so.6: libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6

到目前为止,LD_LIBRARY_PATH,rpath和ldd中的所有内容都表明它指向了我想引用的HDF(/new_apps1/hdf4/lib/libmfhdf.so.0)。 但是当我运行的时候,Valgrind告诉我在HDD-4库(这可能是为什么它是segfaulting)中死掉了,而不是我试图链接的HDF-4库:

Invalid read of size 4 at 0x67CF765: NC_var_shape (in /apps1/hdf-4.2.6/lib/libmfhdf.so.0.0.0) by 0x91327CA: nc_get_NC (v1hpg.c:1113) by 0x91303C0: l3nc__open_mp (nc.c:1096) by 0x915B279: nc3d__open_mp (dapdispatch3.c:336) by 0x914A752: nc3d_open (ncdap3.c:94) by 0x911F8A2: l4nc_open_file (nc4file.c:2338) by 0x916A290: nc4d_open_file (ncdap4.c:122) by 0x911CDDF: nc__open (nc4file.c:2407) by 0x69E85F8: NcFile::NcFile(char const*,NcFile::FileMode,unsigned long*,unsigned long,NcFile::FileFormat) (netcdf.cpp:384) by 0x710F0B8: getData(std::string const&) (ProjTimestamputil.cc:593) by 0x70E9BEA: (anonymous namespace)::parSEOptions(int,char**) (ProjUtility.cc:190) by 0x70EAAFB: main(int,char**) (ProjUtility.cc:243) Address 0x1051 is not stack'd,malloc'd or (recently) free'd Process terminating with default action of signal 11 (SIGSEGV) Access not within mapped region at address 0x1051 at 0x67CF765: NC_var_shape (in /apps1/hdf-4.2.6/lib/libmfhdf.so.0.0.0) by 0x91327CA: nc_get_NC (v1hpg.c:1113) by 0x91303C0: l3nc__open_mp (nc.c:1096) by 0x915B279: nc3d__open_mp (dapdispatch3.c:336) by 0x914A752: nc3d_open (ncdap3.c:94) by 0x911F8A2: l4nc_open_file (nc4file.c:2338) by 0x916A290: nc4d_open_file (ncdap4.c:122) by 0x911CDDF: nc__open (nc4file.c:2407) by 0x69E85F8: NcFile::NcFile(char const*,char**) (ProjUtility.cc:243)

我的应用程序在dynamic拉入其他库时获取path信息还有哪些地方?

为什么linux的多主机使用x86_64-linux-gnu而不是lib64?

使用J的接口在Linux上的C共享库(DLL的)

将dlopen产生相同的文件处理两个电话相同的处理?

libSDL2-2.0.so.0:无法打开共享对象文件

加载共享库时出错:libncurses.so.5:

我不完全确定-rpath和LD_LIBRARY_PATH的工作方式以及它们的优先级,但是我找到了一些有用的环境变量:

LD_DEBUG=all – 这个env变量打开详细的动态链接器调试。 现在在您的应用上执行ldd将会输出关于所有依赖关系如何找到其依赖关系的详细信息。

LD_DEBUG_OUTPUT=<filename_prefix> – 与LD_DEBUG一起使用来指定输出文件来记录调试信息。

LD_DEBUG env变量帮助我追踪到/apps1/gdal-1.8.0-jasper/lib/libgdal.so.1是用一个-rpath选项编译的,这个选项是我的库的旧版本(错误的)。 它给了这个有用的调试输出

search path=/pathXYZ/lib/tls/x86_64:/pathXYZ/lib/tls:/pathXYZ/lib/x86_64: /pathABC/jasper/lib:/pathABC/hdf5/lib/tls/x86_64:/pathABC/hdf5/lib/tls: /pathABC/hdf5/lib/x86_64:/pathABC/hdf5/lib:/pathABC/netcdf/lib/tls/x86_64: /pathABC/netcdf/lib/tls:/pathABC/netcdf/lib/x86_64:/pathABC/netcdf/lib (RPATH from file /apps1/gdal-1.8.0-jasper/lib/libgdal.so.1)

所以GDAL库编译的路径似乎是在我的LD_LIBRAR_PATH周围运行。 在我能让我的实验室团队正确地重建libgdal之前,我发现了这个env var,它帮助我加载了我想要的“正确”的库版本:

LD_PRELOAD=<path/to/libName.so> – 将这个指向一个库的位置(或者一个空格分隔的库列表),它应该在所有其他库之前加载。 请参阅ld.so手册页 。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐