2009-09-28 15 views
29

A causa dell'utilizzo di Gentoo, accade spesso che dopo un aggiornamento i programmi siano collegati a vecchie versioni di librerie. Normalmente, revdep-rebuild aiuta a risolverlo, ma questa volta è una dipendenza da una libreria python, e python-updater non lo raccoglierà.Hierarchical ldd (1)

Esiste una variante "gerarchica" di ldd che mi mostra quale libreria condivisa dipende da quale altra libreria condivisa? La maggior parte delle volte le librerie e gli eseguibili sono collegati solo con una manciata di altre librerie condivise, che a loro volta erano collegate a una manciata, trasformando la dipendenza della biblioteca in una grande lista. Voglio sapere quale dipendenza devo ricostruire con la nuova versione di un'altra libreria che ho aggiornato.

risposta

15

Se si esegue Portage ≥ 2.2 con FEATURES=preserve-libs, si dovrebbe raramente mai bisogno revdep-rebuild più come vecchi .so. vers saranno conservati come necessario (anche se è ancora necessario ricostruire con attenzione, come roba va ancora Kaboom quando libA.so.0 vuole libC.so.0 e libB.so.0 vuole libC.so.1 e alcuni file binari vogliono sia libA.so.0 sia libB.so.0).


Detto questo, ciò che ldd fa è quello di ottenere il linker dinamico per fare caricare il file eseguibile o una libreria come si farebbe normalmente, ma stampare alcune informazioni lungo la strada. Questa è una "libreria di esigenze binarie ricorsive ha bisogno di un'altra ricerca & hellip", perché è quello che fa il linker dinamico.

Attualmente sono in esecuzione Linux/ppc32; su Linux/x86, il linker dinamico è in genere /lib/ld-linux.so.2 e su Linux/x86_64, il linker dinamico è in genere /lib/ld-linux-x86-64.so.2. Qui, lo chiamo direttamente solo per martellare nel punto che tutto lo ldd non è altro che uno script di shell che invoca il linker dinamico per eseguire la sua magia.

 
$ /lib/ld.so.1 /sbin/badblocks 
Usage: /sbin/badblocks [-b block_size] [-i input_file] [-o output_file] [-svwnf] 
     [-c blocks_at_once] [-d delay_factor_between_reads] [-e max_bad_blocks] 
     [-p num_passes] [-t test_pattern [-t test_pattern [...]]] 
     device [last_block [first_block]] 
$ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /sbin/badblocks 
     linux-vdso32.so.1 => (0x00100000) 
     libext2fs.so.2 => /lib/libext2fs.so.2 (0x0ffa8000) 
     libcom_err.so.2 => /lib/libcom_err.so.2 (0x0ff84000) 
     libc.so.6 => /lib/libc.so.6 (0x0fdfa000) 
     libpthread.so.0 => /lib/libpthread.so.0 (0x0fdc0000) 
     /lib/ld.so.1 (0x48000000) 
$ LD_TRACE_LOADED_OBJECTS=1 /lib/ld.so.1 /lib/libcom_err.so.2 
     linux-vdso32.so.1 => (0x00100000) 
     libpthread.so.0 => /lib/libpthread.so.0 (0x6ffa2000) 
     libc.so.6 => /lib/libc.so.6 (0x6fe18000) 
     /lib/ld.so.1 (0x203ba000) 
$ grep -l pthread /sbin/badblocks /lib/libcom_err.so.2 
/lib/libcom_err.so.2 

/sbin/badblocks non elenca libpthread.so.0 come dipendenza biblioteca, ma viene tirato in da libcom_err.so.2.

Il problema è che ldd non restituisce un albero delle dipendenze dall'aspetto piacevole? Utilizzare ldd -v.

 
$ LD_TRACE_LOADED_OBJECTS=1 LD_VERBOSE=1 /lib/ld.so.1 /sbin/badblocks 
     linux-vdso32.so.1 => (0x00100000) 
     libext2fs.so.2 => /lib/libext2fs.so.2 (0x0ffa8000) 
     libcom_err.so.2 => /lib/libcom_err.so.2 (0x0ff84000) 
     libc.so.6 => /lib/libc.so.6 (0x0fdfa000) 
     libpthread.so.0 => /lib/libpthread.so.0 (0x0fdc0000) 
     /lib/ld.so.1 (0x201f9000) 

     Version information: 
     /sbin/badblocks: 
       libc.so.6 (GLIBC_2.2) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6 
     /lib/libext2fs.so.2: 
       libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.3) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.2) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 
     /lib/libcom_err.so.2: 
       ld.so.1 (GLIBC_2.3) => /lib/ld.so.1 
       libpthread.so.0 (GLIBC_2.1) => /lib/libpthread.so.0 
       libpthread.so.0 (GLIBC_2.0) => /lib/libpthread.so.0 
       libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 
     /lib/libc.so.6: 
       ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1 
       ld.so.1 (GLIBC_2.3) => /lib/ld.so.1 
     /lib/libpthread.so.0: 
       ld.so.1 (GLIBC_2.3) => /lib/ld.so.1 
       ld.so.1 (GLIBC_2.1) => /lib/ld.so.1 
       ld.so.1 (GLIBC_PRIVATE) => /lib/ld.so.1 
       libc.so.6 (GLIBC_2.1.3) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.3.4) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.4) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.1) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.3.2) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.2) => /lib/libc.so.6 
       libc.so.6 (GLIBC_PRIVATE) => /lib/libc.so.6 
       libc.so.6 (GLIBC_2.0) => /lib/libc.so.6 

Se si desidera, è possibile leggere le intestazioni ELF direttamente anziché a seconda del linker dinamico.

 
$ readelf -d /sbin/badblocks | grep NEEDED 
0x00000001 (NEEDED)      Shared library: [libext2fs.so.2] 
0x00000001 (NEEDED)      Shared library: [libcom_err.so.2] 
0x00000001 (NEEDED)      Shared library: [libc.so.6] 
$ readelf -d /lib/libcom_err.so.2 | grep NEEDED 
0x00000001 (NEEDED)      Shared library: [libpthread.so.0] 
0x00000001 (NEEDED)      Shared library: [libc.so.6] 
0x00000001 (NEEDED)      Shared library: [ld.so.1] 

È inoltre possibile man ld.so per altri trucchi cute si può giocare con linker dinamico glibc s'.

+0

Wow, grazie mille! – Astro

+0

la sezione ad albero dell'output 'ldd -v' mostra solo le librerie con i simboli versioned – marcin

0

Avevo anche intenzione di suggerire "read -d", ma assicurarmi anche di creare con LDFLAGS = "- Wl, - come necessario" se non lo hai già fatto. Questo ti farà colpire questo problema meno spesso. Le librerie di riserva di Portage 2.2 sono belle, ma ritengo che sia stata mascherata principalmente a causa di esso - ha dei difetti.

+0

Al giorno d'oggi i difetti sono minori. Mentre lo facevo, penso che dovevo dare un'occhiata più da vicino a loro, come un mese fa o qualcosa del genere: P. –

60

Vedo molti dettagli interessanti ma nessuna risposta diretta alla domanda posta.

La versione 'gerarchico' di ldd è lddtree (da app-misc/pax-utils):

$ lddtree /usr/bin/xmllint 
xmllint => /usr/bin/xmllint (interpreter => /lib64/ld-linux-x86-64.so.2) 
    libreadline.so.6 => /lib64/libreadline.so.6 
     libncurses.so.5 => /lib64/libncurses.so.5 
      libdl.so.2 => /lib64/libdl.so.2 
    libxml2.so.2 => /usr/lib64/libxml2.so.2 
     libicui18n.so.49 => /usr/lib64/libicui18n.so.49 
      libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/32/libstdc++.so.6 
       ld-linux.so.2 => /lib64/ld-linux.so.2 
      libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/32/libgcc_s.so.1 
     libicuuc.so.49 => /usr/lib64/libicuuc.so.49 
     libicudata.so.49 => /usr/lib64/libicudata.so.49 
     libz.so.1 => /lib64/libz.so.1 
     liblzma.so.5 => /usr/lib64/liblzma.so.5 
     libm.so.6 => /lib64/libm.so.6 
    libpthread.so.0 => /lib64/libpthread.so.0 
    libc.so.6 => /lib64/libc.so.6 
+2

Tu, signore, sei il mio eroe. Grazie per aver menzionato 'lddtree', ho cercato uno strumento come questo per un po 'di tempo. – ack

6

avevo bisogno di qualcosa di simile, così ho scritto tldd, qui si sta mostrando le proprie dipendenze di libreria:

 
$ ./tldd ./tldd 
./tldd 
└─libstdc++.so.6 => /lib64/libstdc++.so.6 (0x0000003687c00000) 
    ├─libm.so.6 => /lib64/libm.so.6 (0x0000003685000000) 
    │ └─libc.so.6 => /lib64/libc.so.6 (0x0000003684c00000) 
    │ └─ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x0000003684400000) 
    └─libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003686c00000) 
Problemi correlati