Recebendo a mensagem "Não encontrado" ao executar um binário de 32 bits em um sistema de 64 bits

70

Atualmente, tenho um problema estranho no debian (wheezy / amd64).

Eu criei um chroot para instalar um servidor (não posso dar mais detalhes sobre isso, desculpe). Vamos chamar o seu caminho /chr_path/. Para facilitar as coisas, eu inicializei esse chroot com um debootstrap (também wheezy / amd64).

Tudo parecia funcionar bem dentro do chroot, mas quando iniciei o script de instalação do meu servidor, obtive: zsh: Not found /some_path/perl(o instalador inclui um binário perl por alguns motivos)

Naturalmente, verifiquei a /some_path/localização e encontrei o binário "perl". fileno ambiente chroot retorna:

/some_path/perl ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped

O arquivo existe, parece bom, tem direitos corretos. Eu posso usar file, ls, vimsobre ele, mas assim que eu tentar executá-lo - ./perlpor exemplo - eu recebo: zsh: Not found ./perl.

Esta situação é bastante compreensível para mim. Além disso:

  • Eu posso executar outros binários básicos (/ bin / ls, ...) no chroot sem obter erros
  • Tenho os mesmos problemas para outros binários que vieram com o projeto
  • Quando tento executar o binário a partir da raiz principal ( /chr_path/some_path/perl), ele funciona.
  • Eu tentei colocar um dos binários com uma cópia do meu ls. Eu verifiquei se os direitos de acesso eram os mesmos, mas isso não mudou nada (um estava funcionando e o outro não)
Elenaher
fonte
11
Esse é o mesmo problema que "Esse arquivo ou diretório não existe" nos binários instalados do Optware . Observe que seu Perl é um executável de 32 bits. Está faltando o sistema de tempo de execução de 32 bits ( libc6-i386pacote ou ia32-libsse você deseja muitas bibliotecas).
Gilles 'SO- stop be evil'
@Gilles: Muito obrigado! Uma instalação do aptitude ia32-libs resolveu o problema !! Eu tinha visto que o perl tinha 32 bits, mas como estava funcionando no sistema principal (mesma distribuição), presumi que não estava vinculado. Na verdade, eu devo ter instalado o sistema de tempo de execução de 32 bits no sistema principal em algum momento.
Elenaher
11
@ Gilles: Eu acho que acrescentaria isso como uma resposta concisa em vez de marcar isso como uma pergunta duplicada. O ambiente é diferente o suficiente para que, embora o problema seja o mesmo, as pessoas que pesquisam têm maior probabilidade de atingir uma ou outra.
Caleb
11
@ Caleb Não excluímos duplicatas exatamente por esse motivo; os pesquisadores que encontrarem este apenas seguirão o link duplicado para o outro post. Se este é o mesmo problema que provavelmente só deve ser fechado
Michael Mrozek
@MichaelMrozek Mudei de idéia sobre esta questão: embora o problema subjacente seja o mesmo, o remédio concreto é um pouco diferente (sem misturar ABIs do ARM em um caso, permitindo suporte de 32 bits em uma distribuição Linux amd64 no outro) . Então, acho que essa pergunta está aberta, afinal.
Gilles 'SO- stop be evil' (

Respostas:

72

Quando você falha em executar um arquivo que depende de um "carregador", o erro que você recebe pode se referir ao carregador e não ao arquivo que você está executando.

  • O carregador de um executável nativo vinculado dinamicamente é a parte do sistema responsável pelo carregamento de bibliotecas dinâmicas. É algo como /lib/ld.soou /lib/ld-linux.so.2e deve ser um arquivo executável.
  • O carregador de um script é o programa mencionado na linha shebang, por exemplo, /bin/shpara um script que começa com #!/bin/sh. (Bash e zsh dão a mensagem "intérprete incorreto" em vez de "comando não encontrado" neste caso.)

A mensagem de erro é bastante enganosa ao não indicar que o carregador é o problema. Infelizmente, corrigir isso seria difícil porque a interface do kernel só tem espaço para relatar um código de erro numérico, não para também indicar que o erro de fato diz respeito a um arquivo diferente. Alguns shells fazem o trabalho eles mesmos para scripts (lendo a #!linha no script e refazendo a condição de erro), mas nenhum que eu tenha visto tenta fazer o mesmo com os binários nativos.

lddtambém não funcionará nos binários porque funciona definindo algumas variáveis ​​de ambiente especiais e executando o programa, permitindo que o carregador faça o trabalho. stracetambém não forneceria nenhuma informação significativa, pois não reportaria mais do que o que o kernel informa e, como vimos, o kernel não pode relatar tudo o que sabe.

Essa situação geralmente ocorre quando você tenta executar um binário para o sistema certo (ou família de sistemas) e a superarquitetura, mas a subarquitetura errada. Aqui você tem binários ELF em um sistema que espera binários ELF, portanto o kernel os carrega perfeitamente. Eles são binários do i386 executados em um processador x86_64, portanto as instruções fazem sentido e levam o programa ao ponto em que ele pode procurar seu carregador. Mas o programa é um programa de 32 bits (como a filesaída indica), procurando o carregador de 32 bits /lib/ld-linux.so.2, e você presumivelmente instalou apenas o carregador de 64 bits /lib64/ld-linux-x86-64.so.2no chroot.

Você precisa instalar o sistema de tempo de execução de 32 bits no chroot: o carregador e todas as bibliotecas que os programas precisam. A partir do Debian wheezy em diante, se você deseja suporte para i386 e x86_64, comece com uma instalação amd64 e ative o suporte a multiarch : execute dpkg --add-architecture i386then apt-get updatee apt-get install libc6:i386 zlib1g:i386 …(se você deseja gerar uma lista das dependências do pacote perl do Debian, para ver quais bibliotecas provavelmente necessário, você pode usar aptitude search -F %p '~Rdepends:^perl$ ~ri386'). Você pode obter uma coleção de bibliotecas comuns instalando o ia32-libspacote (primeiro é necessário ativar o suporte a multiarch). No Debian amd64 até chiado, o carregador de 32 bits está no libc6-i386pacote. Você pode instalar um conjunto maior de bibliotecas de 32 bits instalando ia32-libs.

Gilles 'SO- parar de ser mau'
fonte
É a única coisa que pode acionar a mensagem de erro? Eu tenho as bibliotecas de 32 bits instaladas e aqui está a saída,ldd mas ainda recebo o mesmo erro.
Nathan Osman
11
@NathanOsman Provavelmente unix.stackexchange.com/questions/76490/…
Gilles 'SO- deixa de ser mau'
Eu tentei instalar, lsb-coremas isso não pareceu ajudar. Acho melhor abrir uma nova pergunta para isso.
Nathan Osman
Obrigado por isso, você acabou de terminar dois dias de coçar a cabeça. Eu pensei que tudo estava sendo estaticamente compilado, mas não estava!
Finn O'leary
5

Execute ldd(1)no seu perlbinário. Muitas vezes, o Not founderro aparentemente confuso em um arquivo que existe claramente ocorre porque uma das bibliotecas compartilhadas usadas pelo programa não foi encontrada.

Portanto, é possível que seu chroot esteja incompleto com relação às bibliotecas compartilhadas necessárias aos seus binários.

camh
fonte
Na verdade, recebo: perl is not a dynamic executablequando estou no chroot e recebo a lista correta de dependências de fora. Atualmente, estou verificando se há algo estranho, mas usei um debootstrap para evitar esse tipo de falta e já há muitas bibliotecas (existe um executável perl no sistema chroot que funciona bem, mas é uma versão diferente; talvez eu faça apenas algumas link simbólico?)
Elenaher
Para ser sincero, eu esperava que o debootstrap produzisse um chroot completo, portanto não esperaria que minha resposta fosse correta nesse sentido. Mas eu já encontrei a biblioteca que estava faltando no problema chroot antes, então pensei em ver se minha resposta voaria.
Camh
cf. comentar para Gilles no post principal: Você estava certo. Faltaram algumas bibliotecas. A principal vantagem do debootstrap é que eu poderia resolver o problema com uma aptidão básica instalar :)
Elenaher