2009-09-28 6 views
29

Aufgrund der Verwendung von Gentoo passiert es oft, dass nach einem Update Programme gegen alte Versionen von Bibliotheken gelinkt werden. Normalerweise hilft revdep-rebuild das zu lösen, aber diesmal ist es eine Abhängigkeit von einer Python-Bibliothek, und python-updater wird es nicht aufnehmen.Hierarchische ldd (1)

Gibt es eine "hierarchische" Variante von ldd, die mir zeigt, welche Shared Library von welcher anderen Shared Library abhängig ist? Meistens sind Bibliotheken und ausführbare Dateien nur mit einer Handvoll anderer gemeinsam genutzter Bibliotheken verbunden, die wiederum mit einer Handvoll verbunden sind, wodurch die Bibliotheksabhängigkeit in eine große Liste umgewandelt wird. Ich möchte wissen, welche Abhängigkeit ich mit der neuen Version einer anderen von mir aktualisierten Bibliothek wiederherstellen muss.

Antwort

15

Wenn Sie mit Portage ≥ 2.2 mit FEATURES=preserve-libs, sollten Sie nur selten brauchen immer revdep-rebuild mehr so ​​alt .so. vers wird je nach Bedarf erhalten werden (obwohl Sie müssen noch vorsichtig wieder aufzubauen, wie Sachen noch kaboom geht, wenn libA.so.0 will libC.so.0 und libB.so.0 will libC.so.1 und einige binäre will sowohl libA.so.0 und libB.so.0).


aber sagt, dass was ldd tut, ist die dynamischen Linker zu bekommen, um die ausführbare Datei oder Bibliothek nicht geladen werden, da es würde in der Regel, aber auf dem Weg ein paar Informationen ausdrucken. Dies ist eine rekursive "Binär benötigt Bibliothek benötigt andere Bibliothek & hellip" Suche, denn das ist, was der dynamische Linker tut.

Ich bin derzeit Linux/ppc32; Unter Linux/x86 ist der dynamische Linker normalerweise /lib/ld-linux.so.2 und unter Linux/x86_64 ist der dynamische Linker normalerweise /lib/ld-linux-x86-64.so.2. Hier nenne ich es direkt, nur um den Punkt einzuhaken, dass alles ldd nichts anderes als ein Shell-Skript ist, das den dynamischen Linker dazu auffordert, seine Magie auszuführen.

 
$ /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 nicht libpthread.so.0 als Bibliothek Abhängigkeitsliste, aber es wird von libcom_err.so.2 eingezogen.

Ist Ihr Problem, dass ldd keinen gut aussehenden Abhängigkeitsbaum ausgibt? Verwenden Sie 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 

Wenn Sie möchten, können Sie die ELF-Header direkt statt in Abhängigkeit von den dynamischen Linker lesen.

 
$ 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] 

Sie können auch man ld.so für andere nette Tricks können Sie mit glibc ‚s dynamischen Linker spielen.

+0

Wow, vielen Dank! – Astro

+0

der Baumabschnitt von 'ldd -v' Ausgabe zeigt nur Bibliotheken mit versionierten Symbolen – marcin

0

Ich schlug auch vor "readelf -d", aber auch sicherstellen, dass Sie mit LDFLAGS = "- Wl, - wie benötigt" bauen, wenn Sie nicht bereits. Dadurch werden Sie dieses Problem seltener bekommen. Portage 2.2's preserve-libs ist nett, aber ich nehme an, dass es hauptsächlich deswegen maskiert wurde - es hat Fehler.

+0

Die Fehler sind heutzutage geringfügig. Während ich dabei war, sollte ich sie mir genau ansehen, wie vor einem Monat oder so: P. –

60

Ich sehe viele interessante Details, aber keine direkte Antwort auf die gestellte Frage.

Die 'hierarchische' -Version von ldd ist lddtree (von 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

Sie, mein Herr, sind mein Held. Danke für die Erwähnung von 'lddtree', ich suche schon seit längerem nach einem Tool wie diesem. – ack

6

ich so etwas wie dies erforderlich ist, also schrieb ich tldd, hier wird es eine eigene Bibliothek Abhängigkeiten zeigt:

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