可执行文件找不到动态链接的mkl库,但是ldd可以

时间:2013-07-23 21:39:03

标签: linker intel-mkl ldd

我有一个与mkl库动态链接的代码。在运行代码时,它报告找不到mkl。

./bmdl
/g/software/EMTO/5.7/intel_12.1/ser/bin/bmdl: error while loading shared libraries: libmkl_intel_lp64.so: cannot open shared object file: No such file or directory

但是当我使用ldd检查可执行文件中的动态链接库时,它显示找到了mkl库

ldd bmdl
libmkl_intel_lp64.so => /g/software/intelXE/composer_xe_2011_sp1/mkl/lib/intel64/libmkl_intel_lp64.so (0x00002b975d76d000)
libmkl_sequential.so => /g/software/intelXE/composer_xe_2011_sp1/mkl/lib/intel64/libmkl_sequential.so (0x00002b975df53000)
libmkl_core.so => /g/software/intelXE/composer_xe_2011_sp1/mkl/lib/intel64/libmkl_core.so (0x00002b975e631000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003785600000)
libm.so.6 => /lib64/libm.so.6 (0x0000003784e00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003784a00000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000378a600000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003785200000)
/lib64/ld-linux-x86-64.so.2 (0x0000003784600000)

知道可能出现什么问题吗?

readelf -l ./bmdl

的输出
Elf file type is EXEC (Executable file)
Entry point 0x4034b0
There are 8 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000001c0 0x00000000000001c0  R E    8
  INTERP         0x0000000000000200 0x0000000000400200 0x0000000000400200
                 0x000000000000001c 0x000000000000001c  R      1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000e4eb4 0x00000000000e4eb4  R E    200000
  ....

更多调试

$ export LD_DEBUG=libs,files
$ ./bmdl
./bmdl: error while loading shared libraries: libmkl_intel_lp64.so: cannot open shared object file: No such file or directory
$ ldd ./bmdl
     15133: 
     15133: file=libtermcap.so.2 [0];  needed by /bin/sh [0]
     15133: find library=libtermcap.so.2 [0]; searching
     15133:  search path=/g/software/intelXE/composer_xe_2011_sp1/mkl/lib/intel64/tls/x86_64:/g/software/intelXE/composer_xe_2011_sp1/mkl/lib/intel64/tls:/g/software/intelXE/composer_xe_2011_sp1/mkl/lib/intel64/x86_64:/g/software/intelXE/composer_xe_2011_sp1/mkl/lib/intel64:/g/software/intelXE/composer_xe_2011_sp1/lib/intel64/tls/x86_64:/g/software/intelXE/composer_xe_2011_sp1/lib/intel64/tls:/g/software/intelXE/composer_xe_2011_sp1/lib/intel64/x86_64:/g/software/intelXE/composer_xe_2011_sp1/lib/intel64        (LD_LIBRARY_PATH)
     ....      

似乎LD_DEBUG对单独运行./bmdl没有影响。

我刚刚意识到旧的bmdl有一个'setgid'标志,我的新建没有它。也许这就是原因?

-rwxr-sr-x 1 root gants 1123992 Jul 23 16:14 /scratch/helpdesk/bmdl

我从旧版setgid中删除了bmdl位,并且运行./bmdl并未抱怨未找到库。现在的问题是为什么setgid会干扰动态链接库?

具有动态链接的可执行文件的setgid可能会导致安全问题,并且受到GNU glibc的极大限制。例如,LD_LIBRARY_PATH将被忽略。也许旧的建筑从来没有工作过??

3 个答案:

答案 0 :(得分:7)

使用MKL需要env变量,包括正确设置INCLUDE,MKLROOT,LD_LIBRARY_PATH,LIBRARY_PATH,CPATH,FPATH和NLSPATH。

这可以通过英特尔提供的单个脚本来完成。

如果您使用intel编译器,

  $ source ${intel_dir}/bin/compilervars.sh intel64

如果仅将MKL用于gcc编译器,

  $ source ${intel_dir}/mkl/bin/mklvars.sh intel64

您可以将此cmd行添加到.bashrc,这样您就不必每次都运行它。

答案 1 :(得分:3)

代码是动态链接的,并具有setgid属性。带有动态链接的可执行文件的setgid可能会导致安全问题,并且受到GNU glibc的极大限制。例如,LD_LIBRARY_PATH将被忽略。这就是为什么代码继续抱怨找不到一些共享库的原因。

答案 2 :(得分:0)

  

但是当我使用ldd检查可执行文件中的动态链接库时,它显示找到了mkl库

你告诉我们整个故事是非常不可能的,因为ldd(在Linux上)只是ld-linux.so周围的一个小shell脚本。如果ld-linux.soldd调用时可以找到共享库,ld-linux.so 可以在直接调用可执行文件时执行此操作({{1}运行ld-linux.so)时,实际映射共享库是什么。

我能想到的唯一可信的解释:

  • 您在与a.out执行的环境不同的环境中执行bmdl,或
  • 您的ldd修改了ldd,可能会在运行“真实”PATH之前修改环境。
  

我如何知道使用了哪个链接器?

ldd

并寻找“请求程序解释器”。

  

readelf -l bmdl

很奇怪。

下一个调试建议:设置[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2].并查看LD_DEBUG=libs,files正在搜索的位置。您可以为ld-linuxldd执行此操作,并查看差异的来源。