Ldd jerárquico (1)

Debido al uso de Gentoo, a menudo sucede que después de una actualización, los progtwigs 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 detectará.

¿Hay una variante “jerárquica” de ldd que me muestre 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é.

Si está ejecutando Portage≥2.2 con FEATURES=preserve-libs , rara vez necesitará revdep-rebuild más viejo .so. vers se conservará según sea necesario (aunque aún necesita reconstruirlo con cuidado, ya que las cosas siguen siendo kaboom cuando libA.so.0 quiere libC.so.0 y libB.so.0 quiere libC.so.1 y algunos binarios quieren ambos libA.so.0 y libB.so.0 ).


Una vez dicho esto, lo que hace ldd es hacer que el enlazador dynamic cargue el ejecutable o la biblioteca como lo haría normalmente, pero imprima algo de información en el camino. Esta es una búsqueda recursiva de “biblioteca de necesidades binarias necesita otra biblioteca & hellip”, porque eso es lo que hace el enlazador dynamic.

Actualmente estoy ejecutando Linux / ppc32; en Linux / x86, el enlazador dynamic suele ser /lib/ld-linux.so.2 , y en Linux / x86_64, el enlazador dynamic suele ser /lib/ld-linux-x86-64.so.2 . Aquí, lo llamo directamente solo para ldd que todo ldd no es más que un script de shell que recurre al enlazador dynamic para realizar su magia.

 $ /lib/ld.so.1 / sbin / badblocks
 Uso: / sbin / badblocks [-b tamaño_bloque] [-i archivo_entrada] [-o archivo_salida] [-svwnf]
        [-c blocks_at_once] [-d delay_factor_between_reads] [-e max_bad_blocks]
        [-p num_passes] [-t test_pattern [-t test_pattern [...]]]
        dispositivo [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 lista libpthread.so.0 como una dependencia de biblioteca, pero libcom_err.so.2 .

¿Su problema es que ldd no ldd un árbol de dependencia 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)

         Información de versión:
         / 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 los encabezados ELF directamente en lugar de depender del vinculador dynamic.

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

También puede man ld.so para otros trucos lindos que puede jugar con el enlazador dynamic de glibc .

Veo muchos detalles interesantes pero ninguna 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 

Necesitaba algo como esto, así que escribí tldd , aquí está mostrando sus propias dependencias de biblioteca:

 $ ./tldd ./tldd
 ./tldd
 └─libstdc ++. So.6 => /lib64/libstdc++.so.6 (0x0000003687c00000)
   ├─libm.so.6 => /lib64/libm.so.6 (0x0000003685000000)
   │ iblibc.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)

También iba a sugerir “readelf -d” pero también me aseguro de comstackr 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.