2009-09-28 16 views
29

Debido al uso de Gentoo, a menudo ocurre que después de una actualización, los programas se vinculan con versiones anteriores de las bibliotecas. Normalmente, revdep-rebuild ayuda a resolver eso, pero esta vez es una dependencia de una biblioteca de Python, y python-updater no lo recogerá.Hdd jerárquico (1)

¿Existe una variante "jerárquica" de ldd que me muestra qué biblioteca compartida depende de qué otra biblioteca compartida? La mayoría de las veces, las bibliotecas y los archivos ejecutables están vinculados solo con un puñado de otras bibliotecas compartidas, que a su vez estaban vinculadas con un puñado, convirtiendo la dependencia de la biblioteca en una gran lista. Quiero saber qué dependencia tengo que reconstruir con la nueva versión de otra biblioteca que actualicé.

Respuesta

15

Si está ejecutando Portage ≥ 2.2 con FEATURES=preserve-libs, debe rara vez necesita revdep-rebuild más como viejos .so. vers se conservarán según sea necesario (aunque todavía se necesita reconstruir cuidadosamente, ya que las cosas todavía va kaboom cuando libA.so.0 quiere libC.so.0 y libB.so.0 quiere libC.so.1 y algunos binarios quieren tanto libA.so.0 como libB.so.0).


Dicho esto, lo que hace es ldd para obtener el enlazador dinámico de hacer cargar el ejecutable o una biblioteca, ya que normalmente lo haría, pero imprimir algo de información a lo largo del camino. Esta es una "biblioteca de necesidades binarias recursiva necesita otra biblioteca & hellip", porque eso es lo que hace el enlazador dinámico.

Actualmente estoy ejecutando Linux/ppc32; en Linux/x86, el enlazador dinámico suele ser /lib/ld-linux.so.2, y en Linux/x86_64, el enlazador dinámico suele ser /lib/ld-linux-x86-64.so.2. Aquí, lo llamo directamente para insistir en el hecho de que todo ldd no es más que un script de shell que recurre al enlazador dinámico para realizar su 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 no enumera libpthread.so.0 como una dependencia de la biblioteca, pero se pone empujados por libcom_err.so.2.

¿Su problema es que ldd no genera un árbol de dependencias de aspecto agradable? Use 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 

Si lo desea, puede leer las cabeceras ELF directamente en lugar de depender del enlazador dinámico.

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

Usted puede también man ld.so para otros trucos linda que usted puede jugar con enlazador dinámico glibc 's.

+0

¡Guau, muchas gracias! – Astro

+0

la sección de árbol de salida 'ldd -v' muestra solo bibliotecas con símbolos versionados – marcin

0

También iba a sugerir "readelf -d" pero también me aseguro de compilar con LDFLAGS = "- Wl, - según sea necesario" si aún no lo hace. Esto te hará atacar este problema con menos frecuencia. Las reserva-libs de Portage 2.2 es agradable, pero creo que fue enmascarado principalmente por eso, tiene fallas.

+0

Los defectos son menores hoy en día. Mientras tanto, creo que se suponía que debería mirarlos más de cerca, como hace un mes o algo así: P. –

60

Veo muchos detalles interesantes pero no hay respuesta directa a la pregunta.

La versión 'jerárquica' de ldd es lddtree (de 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

Usted, señor, es mi héroe. Gracias por mencionar 'lddtree', he estado buscando una herramienta como esta por bastante tiempo. – ack

6

necesitaba algo como esto, así que escribió tldd, aquí está mostrando sus propias dependencias de bibliotecas:

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