2012-03-02 17 views
4

我有一個應用程序,我正在使用NetCDF C++庫,NetCDF正在拉HDF-4庫。但是,它正在拉動錯誤的 HDF-4庫。爲什麼我的Linux應用程序拉錯了.so庫?

這裏是我的應用程序是如何鏈接:

/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輸出的摘錄:

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是告訴我它快死在老HDF-4庫(這可能是爲什麼它的段錯誤),而不是我試圖對鏈接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*, 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) 

我的應用程序在動態拉入其他庫時獲取路徑信息還有哪些地方?

回答

4

我不知道到底要如何-rpath和LD_LIBRARY_PATH工作的所有細節,以及它們的優先級,但是我確實發現一些有用的環境變量:

  • LD_DEBUG=all - 這個環境變量打開詳細動態鏈接器調試。現在在您的應用程序上執行ldd將輸出關於所有依賴關係如何找到其依賴關係的詳細信息。
  • LD_DEBUG_OUTPUT=<filename_prefix> - 與LD_DEBUG一起使用來指定輸出文件以記錄調試信息。

LD_DEBUG環境變量幫我追查這/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庫是如何被編譯將rpath似乎讓我周圍的LD_LIBRAR_PATH結束運行。直到我可以讓我的實驗室團隊,以正確地重建libgdal,我發現這的環境變量,這讓我加載我想要的「正確」的庫版本:

  • LD_PRELOAD=<path/to/libName.so> - 點這一個庫的位置(或一個空格分隔的庫列表)應該在所有其他列表之前加載。請參閱ld.so man page
+0

這是我見過的對這類問題最有幫助的解決方案,而且我最終遇到了一個與'RPATH'問題​​非常類似的問題。在你的二進制文件上嘗試'readelf',看看是否有定義的'RPATH',以及它是否不正確。如果不正確,請確保您的'.profile' /'.bashrc'不會將您的'PATH'或'LD_LIBRARY_PATH'設置爲您不期望的內容。 – patrickvacek 2016-02-09 19:00:01

相關問題