Cómo trabajar con dependencias de objetos compartidos (biblioteca) en Linux

Contenidos

texto de la biblioteca sobre fondo blanco

Error al cargar bibliotecas compartidas: el temido error con el que tarde o temprano se encontrará todo usuario de Linux. Algo salió mal con las dependencias de objetos compartidos (las bibliotecas) utilizadas por el ejecutable. ¡Aprenda a arreglar estos problemas y más!

Que es un Dependencia de objetos compartidos?

Un objeto compartido (además llamado biblioteca) es un binario (de forma general no ejecutable de forma directa) utilizado por múltiples programas / aplicaciones en una instancia de Linux. Estas bibliotecas a menudo se instalan en el nivel del sistema operativo y se comparten (de ahí el nombre objeto compartido o libraries) para su uso por una o más (e inclusive muchas) aplicaciones de forma directa ejecutables.

A modo de ejemplo, un programa que incluye archivos comprimidos puede requerir la biblioteca bz2 (bzip2) libbz2.so.1.0 para hacerlo. El término Biblioteca se utiliza con más frecuencia en los círculos de Linux y es la jerga preferida entre los profesionales, aún cuando objeto compartido (y biblioteca compartida) son ambos técnicamente correctos. Además es interesante notar que el .so La extensión de nombre de archivo utilizada en muchas bibliotecas significa objeto compartido!

Un ejecutable puede tener cero, una o muchas bibliotecas en las que se base. Cuantas menos bibliotecas, más avanzada (al actualizar su sistema operativo, a modo de ejemplo) será la compatibilidad. Cuantas más bibliotecas, mayor será la oportunidad de que, tarde o temprano, se rompa alguna dependencia de la biblioteca. Esta es además el motivo por la que los proveedores de aplicaciones a veces deciden lanzar statically compiled binaries en lugar de dynamically compiled binaries.

La diferencia entre los binarios compilados estática y dinámicamente es simple pero tiene consecuencias de gran alcance. Un binario compilado estáticamente tiene las bibliotecas (disponibles en el sistema de desarrollo en el momento de la compilación) compiladas en el binario / ejecutable resultante. Un binario compilado dinámicamente utilizará las bibliotecas instaladas, disponibles y compartidas en el sistema del usuario.

Como puede ver de inmediato, esto requeriría que el usuario instale las dependencias requeridas, a menos que se cuiden las mismas en el sistema operativo o en los detalles y el sistema de administración de paquetes del proveedor de la aplicación. Es es por esto que que ejecutar un comando simple como sudo apt install ...some_app... a menudo producirá un conjunto de otras cosas asociadas (dicho de otra forma, bibliotecas requeridas) para ser co-instaladas al mismo tiempo.

Tanto la compilación estática como la dinámica disponen pros y contras. A modo de ejemplo, si utiliza la compilación estática y una biblioteca que ha incluido en su paquete de software (desde la perspectiva de un proveedor de software) ahora tiene un error de seguridad o una actualización crítica, es probable que tenga que volver a publicar su paquete de software, inclusive si nada ha cambiado en su código.

Pero, de nuevo, confiar en que el usuario instale bibliotecas, especialmente para programas complejos, o cuando se necesita la autocompilación de software, sabiendo que los usuarios finales a menudo luchan con tales cosas, tampoco es ideal. Es un área compleja y el tema se ha discutido a menudo.

A los efectos de este post, analizaremos las bibliotecas compartidas en vinculación con un programa que se compiló dinámicamente, como suele ser el caso de los programas / ejecutables / herramientas del sistema operativo. Con programas compilados estáticamente (que son menos comunes), es muy poco probable que se muestre un error como ‘Error al cargar bibliotecas compartidas’, puesto que las bibliotecas están incluidas en el ejecutable a menos que el programa sea parcialmente dinámico y solo incluya un conjunto limitado de archivos integrados. en bibliotecas estáticas.

¡Error al cargar bibliotecas compartidas!

Vamos a cambiar a raíz modo por un tiempo (usando sudo su) y explore cómo funcionan las bibliotecas compartidas cuando se trata de una herramienta como /usr/bin/zip que se incluye o se puede instalar con las principales distribuciones de Linux.

Usando ldd en Linux

Aquí, cambiamos los directorios a /usr/bin y comprobó si el zip programa / binario / ejecutable está presente. Al encontrarlo presente, después verificamos la versión invocándola con --version y tomando solo las dos líneas superiores de la salida canalizando la salida (usando |) para evitar la salida larga dada de otra manera.

Para terminar, usamos el ldd tool (un programa que imprime dependencias de objetos compartidos) para ver qué bibliotecas necesita el ejecutable. Como podemos ver, el programa necesita cuatro bibliotecas compartidas. La lista de bibliotecas requeridas de forma general tiene el formato de la biblioteca requerida, seguida de una ruta donde ya se encontró la biblioteca nombrada.

Para algunas bibliotecas de nivel superior o especiales de nivel de sistema operativo (como linux-vdso.so.1), no se muestra tal ruta. A pesar de esto, siempre que no se muestre ningún error en ninguna entrada, sabrá que está bien y disponible (o es preferible). En realidad, linux-vdso.so.1 es un objeto / biblioteca virtual compartido especial inyectado en cada procedimiento por el Kernel de Linux, que no tiene un archivo físico en el disco para el mismo. Está ahí para hacer que las llamadas al sistema sean más eficientes.

Entonces, rompamos un poco las cosas y cambiemos el nombre de una de las bibliotecas requeridas para que el binario ya no pueda descubrirla automáticamente:

Error al cargar bibliotecas compartidas y la biblioteca que falta

Como puede ver, aquí cambiamos el nombre / movimos el archivo de /lib/x86_64-linux-gnu/libbz2.so.1.0 para /lib/x86_64-linux-gnu/libbz2.so.1.0.NOT_PRESENT. Esto rompió nuestra aplicación zip, y cuando intentamos ejecutarlo, obtenemos el temido error while loading shared libraries error. A pesar de esto, mirando un poco más de cerca, el mensaje de error es bastante descriptivo:

zip: error while loading shared libraries: libbz2.so.1.0: cannot open shared object file: No such file or directory

Un ingeniero de TI experimentado siempre revisará cuidadosamente cualquier registro y salida / información del programa que se le presente antes de realizar una llamada sobre un obstáculo. Además valdría la pena aquí, puesto que el archivo requerido se muestra claramente, libbz2.so.1.0, y el problema además se muestra claramente. Hay No such file or directory. Dicho de otra forma, libbz2.so.1.0 ¡Está perdido!

Además podemos verificar lo mismo con ldd, como se puede ver en la imagen de arriba. Una limpieza libbz2.so.1.0 => not found nos ayuda a saber qué está pasando. Una vez que entendemos claramente cómo los binarios compilados dinámicamente (la mayoría de los binarios en el sistema operativo se compilan de esta manera) cargan y requieren bibliotecas, y cómo ver si falta una (o si se le informa de la misma a través del mensaje de error), las cosas no funcionan. ya no parece tan complicado.

Al mismo tiempo, una vez que sepamos el nombre de la biblioteca requerida, una búsqueda rápida en su motor de búsqueda favorito mostrará el paquete adicional que se instalará (o reinstalará) para obtener el nombre de biblioteca requerido. Muy a menudo, el nombre del paquete puede inclusive construirse de forma directa a partir del nombre de la biblioteca. A pesar de esto, para este caso, el nombre de la biblioteca en tiempo de ejecución está un poco desplazado.

Hay dos tipos de bibliotecas: bibliotecas en tiempo de ejecución y bibliotecas de desarrollo. En esta circunstancia, el nombre del paquete que contiene el libbz2.so.1.0 la biblioteca es probable bzip2, y tratar de desinstalar probablemente rompería varios otros ítems, como se puede ver en una larga lista de programas que se eliminarán si se intenta desinstalar o purgar el bzip2 paquete.

El segundo tipo de biblioteca es una biblioteca de desarrollo. A menudo, estos son necesarios cuando se intenta compilar programas y, a menudo, están más estrechamente relacionados con los nombres de los archivos de biblioteca reales. A modo de ejemplo, en Ubuntu, simplemente tome el nombre de la biblioteca y agregue -dev. A modo de ejemplo, si quisiéramos instalar el paquete de desarrollo relacionado con el libbz2.so.1.0 paquete, podríamos considerar la instalación libbz2-dev:

Instalación de una biblioteca de desarrollo

Considerando que esta biblioteca de desarrollo no está de forma directa relacionada con nuestro libbz2.so.1.0 biblioteca de tiempo de ejecución, es útil conocer la sintaxis de nomenclatura de la mayoría de los nombres de paquetes de desarrollo en Ubuntu (prefijo de lib y sufijo de -dev con el nombre de la biblioteca entre esos) de forma definitiva que se requiera una determinada biblioteca de desarrollo (que suele ser necesaria al compilar software).

Al mismo tiempo, suponga que alguna biblioteca se estropea de alguna manera. En ese caso, una de las soluciones rápidas más fáciles es purgar la biblioteca sudo apt purge your_library_name comando (que purgaría totalmente la biblioteca / programa pasado), seguido de una reinstalación usando el sudo apt install your_library_name mando.

Y cuando se encuentra en una situación semejante a la anterior, donde desinstalar la biblioteca en tiempo de ejecución necesita desinstalar / purgar el programa principal, y donde tal purgar / quitar es una parte demasiado grande del sistema operativo o afectaría muchas otras cosas, usted puede utilizar una opción de reinstalación en su lugar:

Reinstalar una aplicación o biblioteca

sudo apt reinstall bzip2

A pesar de esto, no siempre es tan sencillo, aún cuando conociendo lo anterior (y especialmente la convención de nomenclatura en términos de agregar -dev) ayuda enormemente al momento de arreglar problemas y, a menudo, solucionará el problema de forma directa.

Además ayuda mucho saber cómo se pueden verificar las bibliotecas usando lddy, para terminar, comprender que una biblioteca es solo un ejecutable (aún cuando no de forma directa) .so archivo que vive en un subdirectorio de /lib o en /usr/lib u otros directorios similares.

A veces, las bibliotecas y / o los paquetes entran en conflicto entre sí, o ciertos paquetes requieren ciertas versiones de bibliotecas, o ciertas bibliotecas requieren otras bibliotecas, en versiones específicas. Sí, se torna un poco complejo. Además es algo fácil, cuando se torna tan complejo, estropear un poco un sistema. A veces, inclusive es bastante factible interrumpir por completo la instalación de un sistema operativo debido al traslado de una biblioteca demasiado importante, etc.

A menudo, es algo más seguro crear un link simbólico (un link virtual con un nombre de archivo determinado, que hace referencia / enlaza a otro archivo existente u otro link simbólico en sí mismo, que a su vez apunta a un archivo real) para una biblioteca que resta en una versión anterior, a modo de ejemplo y apuntando ese link simbólico a la última versión instalada. No siempre funciona, pero en caso de que falle, el link simbólico se puede quitar, con suerte más seguro (asumiendo que no existía tal link simbólico o archivo con el mismo nombre de antemano).

La mejor manera de arreglar estos problemas más complejos es intentar siempre un apt (o una herramienta de administración de paquetes semejante en su sistema operativo), primero una solución. En este punto, además querrá leer cómo utilizar dkpg para arreglar apt, puesto que le muestra una forma más granular de administrar paquetes (¡aún cuando tenga cuidado, puesto que más control implica más responsabilidad!).

Si todo lo demás falla, intente crear un link simbólico o inclusive agregue manualmente el archivo de la biblioteca. (Por favor, asegúrese de que cualquier archivo descargado esté libre de virus, a modo de ejemplo, verificándolo con VirusTotal, y siempre es mejor utilizar los repositorios proporcionados por el proveedor de Linux para descargar binarios).

In extremis, es factible que además pueda hallar una biblioteca en un sistema operativo Linux vecino. A modo de ejemplo, un ejecutable de Ubuntu se ejecutará en Mint y viceversa. Copiar una biblioteca de otra PC que tenga además es un enfoque viable en ocasiones.

Terminando

La administración de bibliotecas de grano fino es una habilidad que se necesita toda una vida para aprender. Es casi un arte. Este post ha proporcionado la información / conocimientos básicos y las herramientas para utilizar y ha enumerado algunas sugerencias de solución de problemas más avanzadas para cuando las cosas se vuelvan turbias, y tarde o temprano, lo harán si es un usuario frecuente de Linux que instala paquetes con regularidad.

La próxima vez que vea el error ‘Error al cargar bibliotecas compartidas’ en su máquina Linux, estará mejor equipado para comprender de dónde puede venir el problema al utilizar una herramienta como ldd, como se explica en este post. Además analizamos binarios estáticos versus binarios compilados dinámicamente, y cómo las bibliotecas compartidas o integradas encajan y funcionan con ambos.

Si le gustó este post, además le gustaría leer el post sobre dpkg vinculado previamente, así como Cómo agregar el universo, el multiverso y los repositorios restringidos en Ubuntu.

Suscribite a nuestro Newsletter

No te enviaremos correo SPAM. Lo odiamos tanto como tú.