- libtree es una herramienta que convierte la salida de
ldden un árbol y explica cómo se encontró una biblioteca compartida, o por qué no se pudo encontrar - En la salida predeterminada oculta algunas dependencias estándar, y con
-v,-vv,-vvvse pueden ver de forma gradual las bibliotecas ocultas e incluso las dependencias de bibliotecas ya encontradas --patho-pmuestra la ruta en lugar del soname, y con--max-depthse puede limitar la profundidad de la exploración recursiva- La instalación está disponible mediante binarios precompilados de v3.1.1, Fedora/RHEL/CentOS, Ubuntu 22.04+ y GNU Guix
- Para compilar desde el código fuente se requiere un compilador de C que entienda C99, y al usar
makese recomiendaLDFLAGS=-static
Qué hace libtree
- libtree es una herramienta que convierte
ldda una forma de árbol - Explica cómo se encuentran las bibliotecas compartidas, o por qué no se puede ubicar su ruta
- El README incluye una captura de pantalla en
doc/screenshot.png
Opciones de salida
- En la salida predeterminada no se muestran algunas dependencias estándar
- La salida más detallada se controla con opciones de verbosity
libtree -v: muestra las bibliotecas que se omiten de forma predeterminadalibtree -vv: también muestra las dependencias de las bibliotecas que se omiten de forma predeterminadalibtree -vvv: también muestra las dependencias de las bibliotecas ya encontradas
- La bandera
--patho-pmuestra la ruta en lugar del soname- Ejemplo:
libtree -p $(which tar)
- Ejemplo:
--max-depthlimita la profundidad de recursión
Métodos de instalación
- Binarios precompilados para v3.1.1: ofrece binarios precompilados para Linux
- En Fedora / RHEL / CentOS se instala con
dnf- En RHEL y distribuciones derivadas, primero se habilita
epel-release dnf install libtree-ldd
- En RHEL y distribuciones derivadas, primero se habilita
- En Ubuntu 22.04+ se instala con
apt-get install libtree - En GNU Guix se instala con
guix install libtree - También está disponible la versión anterior v2.0.0
Compilar desde el código fuente
libtreerequiere un compilador de C que entienda C99- El procedimiento básico de compilación consiste en clonar el repositorio y luego ejecutar
makegit clone https://github.com/haampie/libtree.gitcd libtreemake
- Al usar
makese recomiendaLDFLAGS=-static - El README también ofrece, en una sección plegable aparte, comandos de instalación rápida insegura para descargar
libtree.cconcurly compilarlo
2 comentarios
Opiniones de Hacker News
¿Esta herramienta también conserva el comportamiento inesperado de
lddde ejecutar realmente parte de las bibliotecas que está inspeccionando?https://catonmat.net/ldd-arbitrary-code-execution
lddde aproximadamente más de 5 años ya no ejecutan el binario objetivoReferencia: https://manpages.debian.org/unstable/manpages/ldd.1.en.html#...
En realidad parece que parsea directamente el archivo ELF y también parsea las dependencias de forma recursiva, así que está bastante bueno
objdump, te imprime los datos tal como están codificados en el archivo ELFIncluso incluye la lista de bibliotecas que buscará vdso
Hay una herramienta similar llamada lddtree
https://github.com/gentoo/pax-utils/tree/master
Tener que rastrear recursivamente las dependencias faltantes con
lddse vuelve bastante tediosoAsí que esto parece una buena mejora, y pienso probarlo la próxima vez que me encuentre con un
not foundambiguoBásicamente es como la versión de CLI en Linux de depends.exe
Es mejor usar https://github.com/lucasg/Dependencies. Tampoco está totalmente al día, pero…
Si instalaste Visual Studio y seleccionaste
x64/x86 build tools (latest)en el instalador, ejecutardumpbin /dependentsdesde VS Developer Command Prompt sigue siendo la opción más confiable[1] https://www.dependencywalker.com/
Para quienes se pregunten qué significan los colores, lo dejo anotado; no lo encontré en la manpage/README
Magenta: está en la lista de exclusión, solo se muestra con
-v[v[v]]Azul: es un elemento visto antes, así que permite encontrar dependencias que aparecen varias veces
¿Qué significa “por qué se encuentra o no se encuentra una biblioteca”? ¿No es simplemente que está o no está en
LD_LIBRARY_PATH?Solo con la captura de pantalla no me queda claro a qué se refiere
Hay varias formas distintas de buscar directorios, como rutas de búsqueda del sistema, runpath, rpath,
LD_LIBRARY_PATH, etc.Las bibliotecas normalmente se enlazan con un nombre corto como
foo.so, pero también pueden enlazarse dinámicamente usando la ruta completa de la bibliotecaAdemás, en general es mucho mejor evitar configurar
LD_LIBRARY_PATHsi se puede. No siempre es posible, pero al configurarlo sube al primer lugar en la prioridad de búsqueda para todas las ejecuciones. Aunque algo esté enlazado dinámicamente con la ruta completa de una biblioteca,LD_LIBRARY_PATHtiene prioridad y termina aplanando por completo la forma de búsquedaLD_LIBRARY_PATHpara ser encontradaLa idea del título es que libtree facilita encontrar la ruta desde un ejecutable hacia todas sus dependencias directas e indirectas. Uno de sus usos es ayudar a diagnosticar problemas de dependencias faltantes
En la práctica, si usas un sistema de paquetes, no suele faltar una dependencia, así que probablemente uses libtree por otros motivos
LD_LIBRARY_PATH; también existe RPATH, que se evalúa en el momento de carga para cada bibliotecaEl punto más importante es que las dependencias forman un grafo y que este puede mostrarse como un árbol. Es útil saber por culpa de qué biblioteca que requería otra biblioteca no se pudo encontrar una biblioteca específica
LD_LIBRARY_PATH. El loader también considera varias otras fuentes para encontrarlasEn una configuración normal, es una combinación de los campos ELF habituales de cada binario cargado y otras rutas conocidas por el loader
En un sistema con varias versiones de la misma biblioteca o varias bibliotecas con el mismo nombre, depender de
LD_LIBRARY_PATHpuede ser muy cortoplacista. Para cada binario, el loader busca en orden las rutas deLD_LIBRARY_PATHy elige la primera biblioteca que coincide. Si no configuraste una ruta de mayor prioridad por otro medio, puede que esa biblioteca no sea la que realmente quieres, y eso puede terminar en errores inesperados en runtimeUna mejor forma es configurar el RPATH del binario hacia la ubicación donde están las bibliotecas que necesita
Si el entorno y la configuración de RPATH no son consistentes, incluso puedes terminar cargando varias versiones de la misma biblioteca al mismo tiempo. Esta herramienta ayuda a entender si hay un problema y por qué
LD_LIBRARY_PATHComo esta herramienta se basa en
ldd, probablemente también interpreteDYLD_LIBRARY_PATH,DYLD_FALLBACK_FRAMEWORK_PATH,DYLD_FALLBACK_LIBRARY_PATH,@executable_path,@loader_pathy@rpathRealmente útil. Normalmente termino leyendo las secciones con
readelfpara averiguar cuáles son los requisitos reales¿No alcanza con
LD_DEBUG=libs?No sé si es un bug, pero en el ejemplo de vim
lddy libtree muestran bibliotecas distintasPor ejemplo,
linux-vdso.so.1aparece al principio de la lista enldd, pero no aparece para nada en libtreelinux-vdso.so.1no es una biblioteca real que puedas encontrar en algún lugar del sistema de archivos y tampoco está referenciada dentro del archivo ELF, así que libtree no puede conocerlaEn cambio, el kernel la mapea automáticamente en el espacio de direcciones de un proceso recién iniciado. Es una optimización para evitar el overhead de llamadas al sistema en funciones como
gettimeofday. Referencia: https://man7.org/linux/man-pages/man7/vdso.7.htmlAlguna vez hice un scriptcito desprolijo que ejecutaba
lddde forma recursiva para averiguar qué tenía que incluir para correr binarios de código cerrado en NixOSSi vuelvo a tener que hacer algo así, pienso probar esta herramienta
¡¡Se ve bien!!