我将一个简单的C(仅包含一个空的main函数)文件编译到a.out中,并在不同的位置运行它:
user@host:~$ md5sum /home/work/a.out /tmp/a.out
dcbdb836569b99a7dc83366ba9bb3588 /home/work/a.out
dcbdb836569b99a7dc83366ba9bb3588 /tmp/a.out
user@host:~$
user@host:~$
user@host:~$ ldd /home/work/a.out
linux-vdso.so.1 (0x00007fffe11fa000)
libc.so.6 => /opt/compiler/gcc-4.8.2/lib/libc.so.6 (0x00007f42b8bca000) <--
/opt/compiler/gcc-4.8.2/lib64/ld-linux-x86-64.so.2 (0x00007f42b8f77000)
user@host:~$
user@host:~$ ldd /tmp/a.out
linux-vdso.so.1 (0x00007fff6ba41000)
libc.so.6 => /tmp/../lib64/tls/libc.so.6 (0x0000003f0b000000) <--
/opt/compiler/gcc-4.8.2/lib64/ld-linux-x86-64.so.2 (0x00007f12f537a000)
为什么要加载不同的libc.so?
这是更多信息,感谢@qubert
$ readelf -a ./a.out | fgrep ORIGIN
0x000000000000000f (RPATH) Library rpath: [$ORIGIN:$ORIGIN/lib:$ORIGIN/lib64:$ORIGIN/../lib:$ORIGIN/../lib64:/opt/compiler/gcc-4.8.2/lib:/opt/compiler/gcc-4.8.2/lib64]
$ gcc -v -g 1.c 2>&1 | fgrep collect
/home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../libexec/gcc/x86_64-xxx-linux-gnu/4.8.2/collect2 -rpath $ORIGIN:$ORIGIN/lib:$ORIGIN/lib64:$ORIGIN/../lib:$ORIGIN/../lib64:/opt/compiler/gcc-4.8.2/lib:/opt/compiler/gcc-4.8.2/lib64 --sysroot=/home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../x86_64-xxx-linux-gnu/sys-root --eh-frame-hdr -m elf_x86_64 -dynamic-linker /opt/compiler/gcc-4.8.2/lib64/ld-linux-x86-64.so.2 /home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../lib/gcc/x86_64-xxx-linux-gnu/4.8.2/../../../../lib64/crt1.o /home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../lib/gcc/x86_64-xxx-linux-gnu/4.8.2/../../../../lib64/crti.o /home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../lib/gcc/x86_64-xxx-linux-gnu/4.8.2/crtbegin.o -L/home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../lib/gcc/x86_64-xxx-linux-gnu/4.8.2 -L/home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../lib/gcc -L/home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../lib/gcc/x86_64-xxx-linux-gnu/4.8.2/../../../../lib64 -L/home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../x86_64-xxx-linux-gnu/sys-root/lib/../lib64 -L/home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../x86_64-xxx-linux-gnu/sys-root/usr/lib/../lib64 -L/home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../lib/gcc/x86_64-xxx-linux-gnu/4.8.2/../../../../x86_64-xxx-linux-gnu/lib -L/home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../lib/gcc/x86_64-xxx-linux-gnu/4.8.2/../../.. -L/home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../x86_64-xxx-linux-gnu/sys-root/lib -L/home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../x86_64-xxx-linux-gnu/sys-root/usr/lib /tmp/ccbKeW7k.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../lib/gcc/x86_64-xxx-linux-gnu/4.8.2/crtend.o /home/opt/gcc-4.8.2.xxx-r4/gcc-4.8.2.xxx-r4/sbin/../lib/gcc/x86_64-xxx-linux-gnu/4.8.2/../../../../lib64/crtn.o
你的编译器,用于设置DT_RPATH
与$ORIGIN
默认情况下使用其内置的规格。
的目的$ORIGIN
是创建可执行文件,这些可执行文件可以与它们所依赖的共享库一起移动到其他地方:如果二进制文件被移动到运行路径中/alt/opt/bin
并包含$ORIGIN/../lib
在其运行路径中,则动态链接程序将首先在中查找其库/alt/opt/lib
。ld.so(8)
联机帮助页中的更多详细信息。
您的编译器的问题在于,它使用的是已弃用的DT_RPATH
(而不是DT_RUNPATH
),始终会首先搜索它,并且无法通过进行覆盖LD_LIBRARY_PATH
。为了避免这种情况,请尝试使用以下-Wl,--enable-new-dtags
方法gcc
:
gcc -Wl,--enable-new-dtags file.c
这将指示链接器使用DT_RUNPATH
而不是使用DT_RPATH
该-rpath
选项,无论是在命令行上还是通过规范进行设置。较早的系统应该不支持此功能,但是据我所记得,那是很久以前的事了。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句