Como trabalhar com dependências de objetos compartilhados (biblioteca) en Linux

Conteúdo

texto da biblioteca em fundo branco

Erro ao carregar bibliotecas compartilhadas: o erro temido que mais cedo ou mais tarde todo usuário Linux encontrará. Algo deu errado com as dependências de objetos compartilhados (As bibliotecas) usado pelo executável. Aprenda como consertar esses problemas e muito mais!!

Que e um Dependência de objeto compartilhado?

Um objeto compartilhado (também chamada de biblioteca) é um binário (geralmente não executável diretamente) usado por vários programas / aplicativos em uma instância do Linux. Essas bibliotecas são frequentemente instaladas no nível do sistema operacional e compartilhadas (daí o nome objeto compartilhado o libraries) para uso por um ou mais (e até mesmo muitos) aplicativos executáveis ​​diretamente.

Como um exemplo, um programa que inclui arquivos compactados pode exigir a biblioteca bz2 (bzip2) libbz2.so.1.0 para faze-lo. O fim Biblioteca É usado com mais frequência nos círculos Linux e é o jargão preferido entre os profissionais, ainda quando objeto compartilhado (e biblioteca compartilhada) são ambos tecnicamente corretos. Também é interessante notar que o .so A extensão de nome de arquivo usada em muitas bibliotecas significa objeto compartilhado!

Um executável pode ter zero, uma ou várias bibliotecas nas quais se baseia. Quanto menos bibliotecas, mais avancado (ao atualizar seu sistema operacional, como um exemplo) será compatibilidade. Quanto mais bibliotecas, quanto maior a chance de, Tarde ou cedo, qualquer dependência da biblioteca foi quebrada. Esta também é a razão pela qual os provedores de aplicativos às vezes decidem lançar statically compiled binaries ao invés de dynamically compiled binaries.

A diferença entre binários compilados estaticamente e dinamicamente é simples, mas tem consequências de longo alcance. Um binário compilado estaticamente tem as bibliotecas (disponível no sistema de desenvolvimento em tempo de construção) compilado em binário / executável resultante. Um binário compilado dinamicamente usará as bibliotecas instaladas, disponível e compartilhado no sistema do usuário.

Como você pode ver imediatamente, isso exigiria que o usuário instale as dependências necessárias, A menos que sejam atendidos no sistema operacional ou nos detalhes e no sistema de gerenciamento de pacotes do fornecedor do aplicativo. É por isso que executar um comando simples como sudo apt install ...some_app... frequentemente produzirá um conjunto de outras coisas associadas (Em outras palavras, Bibliotecas necessárias) a ser co-instalado ao mesmo tempo.

Tanto a compilação estática quanto a dinâmica têm prós e contras. Como um exemplo, se você usar compilação estática e uma biblioteca incluída em seu pacote de software (da perspectiva de um fornecedor de software) agora você tem um bug de segurança ou uma atualização crítica, você pode precisar republicar seu pacote de software, mesmo que nada tenha mudado em seu código.

Mas, de novo, usuário confiável para instalar bibliotecas, especialmente para programas complexos, ou quando a compilação automática de software é necessária, saber que os usuários finais muitas vezes lutam com essas coisas, também não é ideal. É uma área complexa e o assunto tem sido discutido com frequência.

Para os fins desta postagem, vamos analisar as bibliotecas compartilhadas em ligação com um programa que foi compilado dinamicamente, como geralmente é o caso com programas / executáveis / ferramentas do sistema operacional. Com programas compilados estaticamente (que são menos comuns), é altamente improvável que um erro como 'Falha ao carregar bibliotecas compartilhadas' seja exibido, uma vez que as bibliotecas estão incluídas no executável a menos que o programa seja parcialmente dinâmico e inclua apenas um conjunto limitado de arquivos embutidos. em bibliotecas estáticas.

Erro ao carregar bibliotecas compartilhadas!

Vamos mudar para raiz modo por um tempo (usando sudo su) e explorar como as bibliotecas compartilhadas funcionam quando se trata de uma ferramenta como /usr/bin/zip que está incluído ou pode ser instalado com as principais distribuições de Linux.

Usando ldd no Linux

Aqui, mudamos os diretórios para /usr/bin e verifiquei se o zip Programa / trilhas / executável está presente. Encontrando-o presente, então verificamos a versão invocando-a com --version e pegando apenas as duas primeiras linhas da saída, canalizando a saída (usando |) para evitar saída longa fornecida de outra forma.

Para terminar, nós usamos o ldd ferramenta (um programa que imprime dependências de objetos compartilhados) para ver quais bibliotecas o executável precisa. Como podemos ver, o programa precisa de quatro bibliotecas compartilhadas. A lista de bibliotecas necessárias geralmente está no formato da biblioteca necessária, seguido por um caminho onde a biblioteca nomeada já foi encontrada.

Para algumas bibliotecas de nível superior ou de nível de sistema operacional especial (O que linux-vdso.so.1), nenhuma rota é mostrada. Apesar disto, contanto que nenhum erro seja exibido em qualquer entrada, você saberá que está bom e disponível (ou é preferível). Na realidade, linux-vdso.so.1 É um objeto / biblioteca virtual compartilhada especial injetada em cada procedimento pelo kernel Linux, você não tem um arquivo físico no disco para o mesmo. Ele existe para tornar as chamadas do sistema mais eficientes.

Então, vamos quebrar as coisas um pouco e renomear uma das bibliotecas necessárias para que o binário não possa mais descobri-la automaticamente:

Erro ao carregar bibliotecas compartilhadas e biblioteca ausente

Como você pode ver, aqui nós mudamos o nome / movemos o arquivo de /lib/x86_64-linux-gnu/libbz2.so.1.0 para /lib/x86_64-linux-gnu/libbz2.so.1.0.NOT_PRESENT. Isso quebrou nosso aplicativo zip, e quando tentamos executá-lo, nós temos o temido error while loading shared libraries erro. Apesar disto, olhando um pouco mais de perto, a mensagem de erro é bastante descritiva:

fecho eclair: erro ao carregar bibliotecas compartilhadas: libbz2.so.1.0: não pode abrir o arquivo de objeto compartilhado: Não existe tal arquivo ou diretório

Qualquer check-in e check-out serão sempre cuidadosamente revisados ​​por um engenheiro de TI experiente / informações do programa apresentadas a você antes de fazer uma chamada sobre um obstáculo. Também valeria a pena aqui, uma vez que o arquivo necessário é exibido claramente, libbz2.so.1.0, e o problema também é mostrado claramente. Existem No such file or directory. Em outras palavras, libbz2.so.1.0 Está perdido!

Também podemos verificar o mesmo com ldd, como você pode ver na imagem acima. Uma limpeza libbz2.so.1.0 => not found nos ajuda a saber o que está acontecendo. Uma vez que entendemos claramente como binários compilados dinamicamente (a maioria dos binários do sistema operacional são compilados desta forma) carregar e exigir bibliotecas, e como ver se um está faltando (ou se você for informado disso através da mensagem de erro), as coisas não funcionam. não parece mais tão complicado.

Ao mesmo tempo, uma vez que sabemos o nome da biblioteca necessária, uma pesquisa rápida em seu mecanismo de pesquisa favorito mostrará o pacote de complemento a ser instalado (irá reinstalá-lo) para obter o nome da biblioteca necessária. Muitas vezes, o nome do pacote pode até ser construído diretamente a partir do nome da biblioteca. Apesar disto, para este caso, o nome da biblioteca runtime está um pouco errado.

Existem dois tipos de bibliotecas: bibliotecas de tempo de execução e bibliotecas de desenvolvimento. Nesta circunstância, o nome do pacote que contém o libbz2.so.1.0 a biblioteca é provável bzip2, e tentar desinstalar provavelmente quebraria vários outros itens, como você pode ver em uma longa lista de programas que serão removidos se você tentar desinstalar ou limpar o bzip2 pacote.

O segundo tipo de biblioteca é uma biblioteca de desenvolvimento. Frequentemente, Eles são necessários ao tentar compilar programas e, frequentemente, estão mais intimamente relacionados aos nomes dos arquivos reais da biblioteca. Como um exemplo, no Ubuntu, basta pegar o nome da biblioteca e adicionar -dev. Como um exemplo, se quisermos instalar o pacote de desenvolvimento relacionado ao libbz2.so.1.0 pacote, poderíamos considerar a instalação libbz2-dev:

Instalando uma biblioteca de desenvolvimento

Considerando que esta biblioteca de desenvolvimento não está diretamente relacionada ao nosso libbz2.so.1.0 biblioteca de tempo de execução, é útil saber a sintaxe de nomenclatura da maioria dos nomes de pacotes de desenvolvimento no Ubuntu (prefixo de lib e sufixo de -dev com o nome da biblioteca entre aqueles) definitivamente que uma certa biblioteca de desenvolvimento é necessária (que geralmente é necessário ao compilar software).

Ao mesmo tempo, suponha que alguma biblioteca quebra de alguma forma. Nesse caso, uma das soluções rápidas mais fáceis é limpar a biblioteca sudo apt purge your_library_name comando (isso limparia totalmente a biblioteca / programa anterior), seguido por uma reinstalação usando o sudo apt install your_library_name comando.

E quando você está em uma situação semelhante à anterior, onde desinstalar a biblioteca de tempo de execução que você precisa desinstalar / limpar o programa principal, e onde está purgando / a remoção é uma parte muito grande do sistema operacional ou afetaria muitas outras coisas, você pode usar uma opção de reinstalação em vez:

Reinstale um aplicativo ou biblioteca

sudo apt reinstalar bzip2

Apesar disto, nem sempre é tão simples, mesmo sabendo do acima (e especialmente a convenção de nomenclatura em termos de adição -dev) ajuda enormemente na correção de problemas e, frequentemente, vai resolver o problema diretamente.

Também ajuda muito saber como as bibliotecas podem ser verificadas usando ldde, para terminar, entender que uma biblioteca é apenas um executável (mesmo que não diretamente) .so arquivo que reside em um subdiretório de /lib o en /usr/lib ou outros diretórios semelhantes.

As vezes, bibliotecas e / ou pacotes entram em conflito uns com os outros, ou certos pacotes requerem certas versões de bibliotecas, ou certas bibliotecas requerem outras bibliotecas, em versões específicas. sim, fica um pouco complexo. Também é algo fácil, quando fica tão complexo, bagunçar um pouco o sistema. As vezes, é até mesmo possível interromper completamente a instalação de um sistema operacional devido à transferência de uma biblioteca muito importante, etc.

Frequentemente, é um pouco mais seguro criar um link simbólico (um link virtual com um nome de arquivo específico, bruxa refere-se a / links para outro arquivo existente ou outro link simbólico em si, que por sua vez aponta para um arquivo real) para uma biblioteca remanescente em uma versão anterior, como exemplo e apontando esse link simbólico para a última versão instalada. Nem sempre funciona, mas no caso de falhar, o link simbólico pode ser removido, esperançosamente mais seguro (assumindo que nenhum link simbólico ou arquivo com o mesmo nome existia de antemão).

A melhor maneira de corrigir esses problemas mais complexos é sempre tentar um apt (ou uma ferramenta de gerenciamento de pacote semelhante em seu sistema operacional), primeiro uma solução. Neste ponto, você também vai querer ler como usar o dkpg para consertar o apt, pois mostra uma maneira mais granular de gerenciar pacotes (Mesmo quando tiver cuidado, uma vez que mais controle implica mais responsabilidade!).

Se todo o resto falhar, tente criar um link simbólico ou até mesmo adicionar manualmente o arquivo de biblioteca. (Por favor, certifique-se de que todos os arquivos baixados estão livres de vírus, como um exemplo, verificando com VirusTotal, e é sempre melhor usar os repositórios fornecidos pelo fornecedor do Linux para baixar binários).

in extremis, é possível que você também possa encontrar uma biblioteca em um sistema operacional Linux vizinho. Como um exemplo, um executável do Ubuntu será executado no Mint e vice-versa. Copiar uma biblioteca de outro PC que você também tem é uma abordagem viável às vezes.

Final

O gerenciamento refinado de bibliotecas é uma habilidade vitalícia para se aprender. É quase uma arte. Esta postagem forneceu as informações / conhecimento básico e ferramentas para usar e listou algumas dicas mais avançadas de solução de problemas para quando as coisas ficarem confusas, e mais cedo ou mais tarde, eles farão se você for um usuário frequente de Linux que instala pacotes regularmente.

Da próxima vez que você vir o erro 'Erro ao carregar bibliotecas compartilhadas’ em sua máquina Linux, você estará melhor equipado para entender de onde o problema pode vir ao usar uma ferramenta como ldd, como explicado neste post. Também analisamos binários estáticos versus binários compilados dinamicamente., e como bibliotecas compartilhadas ou integradas se encaixam e funcionam com ambos.

Se você gostou deste post, também gostaria de ler a postagem sobre dpkg previamente ligado, bem como como adicionar o universo, o multiverso e os repositórios restritos no Ubuntu.

Assine a nossa newsletter

Nós não enviaremos SPAM para você. Nós odiamos isso tanto quanto você.