Obteniendo el mensaje "No encontrado" cuando se ejecuta un binario de 32 bits en un sistema de 64 bits

70

Actualmente tengo un problema extraño en debian (wheezy / amd64).

He creado un chroot para instalar un servidor (no puedo dar más detalles al respecto, lo siento). Llamemos a su camino /chr_path/. Para facilitar las cosas, he inicializado este chroot con un debootstrap (también wheezy / amd64).

Todo parecía funcionar bien dentro del chroot, pero cuando comencé el script de instalación de mi servidor obtuve: zsh: Not found /some_path/perl(el instalador incluye un binario perl por algunas razones)

Naturalmente, verifiqué la /some_path/ubicación y encontré el binario "perl". fileen entorno chroot devuelve:

/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

El archivo existe, parece estar bien, tiene los derechos correctos. Puedo usar file, ls, vimen él, pero tan pronto como trato de ejecutarlo - ./perlpor ejemplo - me sale: zsh: Not found ./perl.

Esta situación es bastante comprensible para mí. Por otra parte:

  • Puedo ejecutar otros binarios básicos (/ bin / ls, ...) en el chroot sin obtener errores
  • Tengo los mismos problemas para otros binarios que vinieron con el proyecto
  • Cuando intento ejecutar el binario desde la raíz principal ( /chr_path/some_path/perl), funciona.
  • He tratado de poner uno de los binarios con una copia de mi ls. Verifiqué que los derechos de acceso eran los mismos, pero esto no cambió nada (uno estaba funcionando y el otro no)
Elenaher
fuente
1
Este es el mismo problema que "No existe tal archivo o directorio" en los binarios instalados de Optware . Tenga en cuenta que su Perl es un ejecutable de 32 bits. Te falta el sistema de tiempo de ejecución de 32 bits ( libc6-i386paquete, o ia32-libssi quieres muchas bibliotecas).
Gilles 'SO- deja de ser malvado'
@Gilles: ¡Muchas gracias! ¡Una instalación de aptitud ia32-libs ha resuelto el problema! Había visto que el perl era de 32 bits, pero como funcionaba en el sistema principal (misma distribución), supuse que no estaba vinculado. En realidad, debo haber instalado el sistema de tiempo de ejecución de 32 bits en el sistema principal en algún momento.
Elenaher
1
@Gilles: Creo que agregaría eso como una respuesta concisa en lugar de marcar esto como una pregunta duplicada. El entorno es lo suficientemente diferente como para que aunque el problema sea el mismo, es más probable que las personas que realizan búsquedas golpeen a uno u otro.
Caleb
1
@Caleb No eliminamos duplicados exactamente por esa razón; los buscadores que encuentren este solo seguirán el enlace duplicado a la otra publicación. Si este es el mismo problema, probablemente debería cerrarse
Michael Mrozek
@MichaelMrozek He cambiado de opinión sobre esta pregunta: si bien el problema subyacente es el mismo, el remedio concreto es un poco diferente (no mezclar ABI ARM en un caso, lo que permite el soporte de 32 bits en una distribución Linux amd64 en el otro) . Así que supongo que esta pregunta pertenece abierta después de todo.
Gilles 'SO- deja de ser malvado'

Respuestas:

72

Cuando no puede ejecutar un archivo que depende de un "cargador", el error que obtiene puede referirse al cargador en lugar del archivo que está ejecutando.

  • El cargador de un ejecutable nativo vinculado dinámicamente es la parte del sistema responsable de cargar las bibliotecas dinámicas. Es algo como /lib/ld.soo /lib/ld-linux.so.2, y debería ser un archivo ejecutable.
  • El cargador de un script es el programa mencionado en la línea shebang, por ejemplo, /bin/shpara un script que comienza con #!/bin/sh. (Bash y zsh dan un mensaje de "mal intérprete" en lugar de "comando no encontrado" en este caso).

El mensaje de error es bastante engañoso al no indicar que el cargador es el problema. Desafortunadamente, solucionar esto sería difícil porque la interfaz del núcleo solo tiene espacio para informar un código de error numérico, no para indicar también que el error en realidad se refiere a un archivo diferente. Algunos shells hacen el trabajo por sí mismos para los scripts (leer la #!línea del script y volver a resolver la condición de error), pero ninguno de los que he visto intenta hacer lo mismo para los binarios nativos.

lddtampoco funcionará en los binarios porque funciona estableciendo algunas variables de entorno especiales y luego ejecutando el programa, dejando que el cargador haga el trabajo. stracetampoco proporcionaría ninguna información significativa, ya que no informaría más de lo que informa el núcleo, y como hemos visto, el núcleo no puede informar todo lo que sabe.

Esta situación a menudo surge cuando intenta ejecutar un binario para el sistema correcto (o la familia de sistemas) y superar la arquitectura pero la subarquitectura incorrecta. Aquí tiene binarios ELF en un sistema que espera binarios ELF, por lo que el núcleo los carga perfectamente. Son binarios i386 que se ejecutan en un procesador x86_64, por lo que las instrucciones tienen sentido y llevan el programa al punto en el que puede buscar su cargador. Pero el programa es un programa de 32 bits (como lo fileindica la salida), busca el cargador de 32 bits /lib/ld-linux.so.2, y presumiblemente solo ha instalado el cargador de 64 bits /lib64/ld-linux-x86-64.so.2en el chroot.

Debe instalar el sistema de tiempo de ejecución de 32 bits en el chroot: el cargador y todas las bibliotecas que necesitan los programas. Desde Debian wheezy en adelante, si desea soporte para i386 y x86_64, comience con una instalación de amd64 y active el soporte multiarch : ejecute dpkg --add-architecture i386entonces apt-get updatey apt-get install libc6:i386 zlib1g:i386 …(si desea generar una lista de las dependencias del paquete perl de Debian, para ver qué bibliotecas pueden ser necesario, puedes usar aptitude search -F %p '~Rdepends:^perl$ ~ri386'). Puede obtener una colección de bibliotecas comunes instalando el ia32-libspaquete (primero debe habilitar el soporte multiarch). En Debian amd64 hasta wheezy, el cargador de 32 bits está en el libc6-i386paquete. Puede instalar un conjunto más grande de bibliotecas de 32 bits mediante la instalación ia32-libs.

Gilles 'SO- deja de ser malvado'
fuente
¿Es esto lo único que puede activar el mensaje de error? Tengo instaladas las bibliotecas de 32 bits y aquí está el resultado,ldd pero sigo teniendo el mismo error.
Nathan Osman
1
@NathanOsman Probablemente unix.stackexchange.com/questions/76490/…
Gilles 'SO- deja de ser malvado'
Intenté instalar lsb-corepero eso no pareció ayudar. Creo que mejor abro una nueva pregunta para esto.
Nathan Osman
Gracias por esto, acabas de terminar dos días de rascarte la cabeza. ¡Pensé que todo se estaba compilando estáticamente, pero no fue así!
Finn O'leary
5

Corre ldd(1)en tu perlbinario. A menudo, el Not founderror aparentemente confuso en un archivo que claramente existe es porque no se encuentra una de las bibliotecas compartidas utilizadas por el programa.

Por lo tanto, es posible que su chroot esté incompleto con respecto a las bibliotecas compartidas que necesitan sus binarios.

camh
fuente
En realidad obtengo: perl is not a dynamic executablecuando estoy en el chroot y obtengo la lista correcta de dependencias desde el exterior. Actualmente estoy verificando si hay algo extraño, pero usé un debootstrap para evitar este tipo de falta y ya tengo muchas libs instaladas (hay un ejecutable perl en el sistema chroot que funciona bien pero es una versión diferente; tal vez solo haga algo enlace simbólico?)
Elenaher
Para ser honesto, hubiera esperado que debootstrap hubiera producido un chroot completo, por lo que no esperaría que mi respuesta fuera correcta a ese respecto. Pero me he encontrado con la biblioteca que falta en el problema chroot antes, así que pensé en ver si mi respuesta saldría volando.
camh
cf. comentar a Gilles en la publicación principal: Tenías razón. Faltaban algunas librerías. La principal ventaja de debootstrap es que podría resolver el problema con una instalación básica de aptitud :)
Elenaher