간단한 C(빈 기본 함수만 포함) 파일을 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
답변1
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
이는 명령줄에서 설정하든 사양을 통해 설정하든 상관없이 링커에게 options DT_RUNPATH
대신 사용하도록 지시합니다. 이전 시스템은 이것을 지원해서는 안 되지만, 제가 기억하는 한 그것은 오래 전 일이었습니다.DT_RPATH
-rpath