我有一个与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将被忽略。也许旧的建筑从来没有工作过??
答案 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.so
在ldd
调用时可以找到共享库,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-linux
和ldd
执行此操作,并查看差异的来源。