Por que o mesmo executável em diferentes locais carregou diferentes libc.so

1

Eu compilei um arquivo C simples (continha apenas uma função principal vazia) em a.out, e executei em loaction diferente:

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)

Por que carregou libc.so diferente?

Aqui estão mais informações, obrigado por @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
    
por da_miao_zi 17.10.2018 / 10:26

1 resposta

1

Seu compilador foi configurado para definir DT_RPATH com $ORIGIN por padrão usando suas especificações internas.

A finalidade de $ORIGIN é criar executáveis que possam ser movidos para outro local com as bibliotecas compartilhadas das quais eles dependem: se um binário for movido para /alt/opt/bin e tiver $ORIGIN/../lib em seu caminho de execução, o vinculador dinâmico primeiro procure por suas bibliotecas em /alt/opt/lib . Mais detalhes na% man_de% manpage.

O problema com seu compilador é que ele está usando o ld.so(8) (em vez de DT_RPATH ) reprovado, que é sempre pesquisado primeiro e não pode ser substituído via DT_RUNPATH . Para evitar isso, tente usar LD_LIBRARY_PATH to -Wl,--enable-new-dtags :

gcc -Wl,--enable-new-dtags file.c

Isso direcionará o vinculador a usar gcc em vez de DT_RUNPATH para a opção DT_RPATH , seja na linha de comando ou via especificações. Isso não deveria ser suportado em sistemas mais antigos, mas pelo que me lembro, isso foi há um bom tempo.

    
por 22.10.2018 / 10:50