Obtendo a mensagem “Não encontrado” ao executar um binário de 32 bits em um sistema de 64 bits

64

Eu tenho atualmente 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 seu caminho /chr_path/ . Para facilitar as coisas, inicializei este chroot com um debootstrap (também wheezy / amd64).

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

Naturalmente, verifiquei o local /some_path/ e encontrei o binário "perl". file no 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 ok, tem direitos corretos. Eu posso usar file , ls , vim , mas assim que eu tentar executá-lo - ./perl por 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 receber erros
  • Eu 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 . Verifiquei que os direitos de acesso eram os mesmos, mas isso não alterou nada (um estava funcionando e o outro não)
por Elenaher 18.05.2011 / 17:09

2 respostas

67

Quando você não consegue executar um arquivo que depende de um "carregador", o erro que você recebe pode se referir ao carregador, em vez do 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.so ou /lib/ld-linux.so.2 e deve ser um arquivo executável.
  • O carregador de um script é o programa mencionado na linha shebang, por ex. /bin/sh para um script que começa com #!/bin/sh . (Bash e zsh dão uma mensagem "intérprete ruim" em vez de "comando não encontrado" neste caso.)

A mensagem de erro é bastante enganadora, não indicando que o carregador seja o problema. Infelizmente, consertar 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 indicar também que o erro de fato diz respeito a um arquivo diferente. Algumas shells fazem o trabalho para scripts (lendo a linha #! no script e refazendo a condição de erro), mas nenhuma que eu tenha visto tenta fazer o mesmo com binários nativos.

ldd não funciona nos binários porque funciona definindo algumas variáveis de ambiente especiais e executando o programa, deixando o carregador fazer o trabalho. strace também não forneceria nenhuma informação significativa, já que ela não reportaria mais do que o kernel reporta, e como vimos, o kernel não pode relatar tudo o que sabe.

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

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

    
por 18.05.2011 / 21:49
5

Execute ldd(1) no seu perl binário. Muitas vezes, o erro Not found aparentemente confuso em um arquivo que está claramente lá é porque uma das bibliotecas compartilhadas usadas pelo programa não foi encontrada.

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

    
por 18.05.2011 / 17:21