¿Cómo antepongo un directorio a la ruta de la biblioteca al cargar un archivo principal en gdb en Linux?
Pregunta
Tengo un archivo central generado en un sistema remoto al que no tengo acceso directo.También tengo copias locales de los archivos de la biblioteca del sistema remoto y el archivo ejecutable del programa que falla.
Me gustaría analizar este volcado de memoria en gdb.
Por ejemplo:
gdb path/to/executable path/to/corefile
Mis bibliotecas están en el directorio actual.
En el pasado, he visto a los depuradores implementar esto al proporcionar la opción "-P". o "-p /=.";entonces mi pregunta es:
¿Cómo puedo especificar que las bibliotecas se carguen primero desde las rutas relativas a mi directorio actual al analizar un archivo central en gdb?
Solución
Inicie gdb sin especificar el archivo ejecutable o principal, luego escriba los siguientes comandos:
set solib-absolute-prefix ./usr
file path/to/executable
core-file path/to/corefile
Deberá asegurarse de reflejar la ruta de su biblioteca exactamente desde el sistema de destino.Lo anterior está destinado a depurar objetivos que no coinciden con su host, por eso es importante replicar la estructura de su sistema de archivos raíz que contiene sus bibliotecas.
Si está depurando remotamente un servidor que tiene la misma arquitectura y versión de Linux/glibc que su host, entonces puede hacer lo siguiente fd sugirió:
set solib-search-path <path>
Si está intentando anular algunas de las bibliotecas, pero no todas, puede copiar la estructura del directorio de la biblioteca de destino en un lugar temporal y usar el solib-absolute-prefix
solución descrita anteriormente.
Otros consejos
No estoy seguro de que esto sea posible dentro de gdb, pero no soy un experto.
Sin embargo puedo comentar sobre el linux enlazador dinámico.Lo siguiente debería imprimir la ruta de todas las bibliotecas compartidas resueltas y las no resueltas.
ldd path/to/executable
Necesitamos saber cómo se vincularon sus bibliotecas compartidas con su ejecutable.Para hacer esto, use el siguiente comando:
readelf -d path/to/executable | grep RPATH
Si el comando no imprime nada, el vinculador dinámico utilizará ubicaciones estándar más la variable de entorno LD_LIBRARY_PATH para encontrar las bibliotecas compartidas.
Si el comando imprime algunas líneas, el vinculador dinámico ignorará LD_LIBRARY_PATH y utilizará las rutas codificadas en su lugar.
Si las rutas enumeradas son absolutas, la única solución que conozco es copiar (o vincular simbólicamente) sus bibliotecas a las ubicaciones enumeradas.
Si las rutas enumeradas son relativas, contendrán un $ORIGIN que será reemplazado en tiempo de ejecución por la ruta del ejecutable.Mueva el ejecutable o las bibliotecas para que coincidan.
Para obtener más información, puede comenzar con:
man ld.so
Encontré este extracto en desarrollador.apple.com
set solib-search-path path
Si se establece esta variable, PATH es una lista de directorios separados por colon para buscar bibliotecas compartidas.
solib-search-path' is used after
SOLIB-ABSOLUTE-PREFIX 'no puede ubicar la biblioteca, o si la ruta a la biblioteca es relativa en lugar de absoluta.Si quieres usarsolib-search-path' instead of
Solib-Absolute-Prefix ', asegúrese de establecer' Solib-Absolute-Prefix 'en un directorio inexistente para evitar que GDB encuentre las bibliotecas de su host.
EDITAR:
No creo que el uso de la configuración anterior anteponga los directorios que agregué, pero sí parece agregarlos, por lo que los archivos que faltan en mi sistema actual se recogen en las rutas que agregué.Supongo que configurar el prefijo absoluto de solib en algo falso y agregar directorios en la ruta de búsqueda de solib en el orden que necesito podría ser una solución completa.
También puede simplemente configurar LD_PRELOAD para cada una de las bibliotecas o LD_LIBRARY_PATH para el directorio actual al invocar gdb.Esto sólo causará problemas si el propio gdb intenta utilizar cualquiera de las bibliotecas que está precargando.
Una nota importante:
Si está haciendo una compilación cruzada e intentando depurar con GDB, entonces después de haberlo hecho file ECECUTABLE_NAME
si ves algocomo :
Using host libthread_db library "/lib/libthread_db.so.1"
luego verifique si tiene libthread_db para su sistema de destino.Encontré muchos problemas similares en la web.Este problema no se puede resolver simplemente usando "set solib-", también debe compilar libthread_db usando su compilador cruzado.