2013-07-23 56 views
2

我有一個與mkl庫動態鏈接的代碼。運行代碼時,它會報告未找到mkl。可執行文件找不到動態鏈接的mkl庫,但ldd確實有

./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 

我從舊bmdl取出setgid位和運行./bmdl不會抱怨沒有找到庫。現在的問題是爲什麼setgid會干擾動態鏈接庫?

碰巧setgid與一個動態鏈接的可執行文件可能會導致安全問題,並受到GNU glibc的極大限制。例如,LD_LIBRARY_PATH將被忽略。也許舊的建築從來沒有工作過?!

+0

你能提供cmd行來顯示你如何編譯和鏈接你的'bmdl'嗎? – kangshiyin

+0

鏈接MKL的命令行爲'-L $(MKLPATH)-lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread'。我在這裏省略了一些細節。 'bmdl'是由其他人首先構建的,它工作。幾個月後,我們發現它抱怨找不到mkl庫。所以我用它的原始makefile重建它。新的建設工程。但是我只是覺得這很奇怪爲什麼原始版本不能工作,特別是'ldd'可以解析所有動態鏈接的庫。 – user2196452

+0

這很奇怪。你使用哪個編譯器/鏈接器?在你的orignal文章中提供整個complie/link cmd行可能會有所幫助。你也可以嘗試靜態鏈接。 – kangshiyin

回答

3

該代碼是動態鏈接的並具有setgid屬性。 setgid與動態鏈接的可執行文件可能會導致安全問題,並受到GNU glibc的極大限制。例如,LD_LIBRARY_PATH將被忽略。這就是爲什麼代碼不斷抱怨找不到一些共享庫。

6

使用MKL reqires env變量,包括正確設置的INCLUDE,MKLROOT,LD_LIBRARY_PATH,LIBRARY_PATH,CPATH,FPATH和NLSPATH。

這可以通過英特爾提供的單個腳本完成。

如果使用英特爾編譯器,

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

如果使用MKL只與gcc編譯器,

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

您可以將此CMD行添加到您的.bashrc,這樣你就不需要運行它每一次。

+0

Eric,謝謝你的回覆。在運行可執行文件之前,所有環境變量都已正確設置。 – user2196452

0

但是當我使用LDD檢查動態鏈接庫中的可執行文件,它顯示的MKL庫中找到

這是極不可能的,你已經告訴我們整個故事,因爲ldd (在Linux上)只是一個圍繞ld-linux.so的小型shell腳本。如果當ldd調用ld-linux.so可以找到共享庫,ld-linux.so應該能夠做到的是,當可執行直接調用(ld-linux.so是什麼實際上映射共享庫當您運行a.out)。

唯一的合理解釋我能想到的:

  • 你從你在執行ldd的一個不同的環境中執行bmdl,或
  • 你一個對你PATH,這或許修改修改ldd運行之前的環境「真實」ldd

我怎麼知道使用哪個鏈接器?

readelf -l bmdl 

,並查找 「請求程序解釋器」。

[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2].

很奇怪。

下一個調試建議:設置LD_DEBUG=libs,files並查看ld-linux正在搜索的位置。您可以對lddbmdl這樣做,並查看差異來自哪裏。

+0

當我使用'/ lib64/ld-linux-x86-64.so.2'啓動'bmdl'時,代碼實際上已經完成。這讓我在那裏徘徊,可能是我們集羣上的操作系統有問題。任何想法如何進行調試。非常感謝。 – user2196452

+0

我閱讀了ld的聯機幫助頁。所以說,動態鏈接器可以間接運行\t到\t,運行一些動態鏈接的程序或庫(在這種情況下,可以傳遞動態鏈接器的命令行選項,並且在ELF情況下,動態鏈接器被存儲在程序的.interp部分執行)''我檢查過'bmdl'的'.interp'部分,它如下:'0 .interp 0000001c 0000000000400200 0000000000400200 00000200 2 ** 0 CONTENTS,ALLOC,LOAD,READONLY ,DATA '我如何知道使用哪個鏈接器? – user2196452

+0

@ user2196452我更新了答案。 –

相關問題