Configurar mi lib para LD_PRELOAD hace que algunos procesos produzcan errores de carga

3 minutos de lectura

avatar de usuario de nakiya
nakiya

Recibo el siguiente error cuando intento ejecutar un script para el que solo tengo acceso de ejecución:

uname: symbol lookup error: /home/dumindara/random/sotest/a.out: undefined symbol: dlsym

Esto es después de haber establecido LD_PRELOAD variable de entorno a /home/dumindara/random/sotest/a.out.

a.out tiene una prueba malloc función y llamadas dlsym internamente.

No tengo este problema cuando ejecuto ls. La mayoría de los procesos dan este error. ¿Por qué sucede esto y qué puedo hacer para que funcione?

  • En general, es una buena idea configurar LD_PRELOAD solo para a.out, en lugar de modificar el entorno de shell. En la mayoría de los shells de UNIX puede escribir: LD_PRELOAD=xyz ./a.out. De lo contrario, intente ( LD_PRELOAD=xyz; ./a.out ).

    – Tony Delroy

    8 de diciembre de 2010 a las 8:08

  • @Tony: creo que a.out es un objeto compartido en este caso, a pesar de su nombre mal elegido. El OP aparentemente está tratando de anular malloc() con su propia versión y luego pasar al malloc real.

    – Thkala

    8 de diciembre de 2010 a las 8:25


  • @tkhala: ah, buena captura… sería más como LD_PRELOAD=`pwd`/a.out program_to_test entonces….

    – Tony Delroy

    8 de diciembre de 2010 a las 8:52


No puedo comentar la respuesta aceptada, sin embargo, vale la pena mencionar aquí que uno puede encontrar el problema de no tener libdl.so.2 vinculado correctamente cuando -ldl se usa delante del comando de compilación (suponiendo que el enlace y la compilación se ejecutan con el mismo comando; esto es posible ya que las bibliotecas LD_PRELOAD generalmente se basan en un archivo fuente).

Así que llama a gcc con -ldl al final:

gcc -shared -fPIC fakeuname.c -o libfakeuname.so -ldl

en mi caso tener -ldl en el frente resultó en el mismo error que en la pregunta:

uname: symbol lookup error: ./libfakehostname.so: undefined symbol: dlsym

  • si pulgar arriba!!! la respuesta de thkala todavía me dio un error, pero su “-ldl” al final resolvió todo.

    – Peter Teoh

    16 oct 2015 a las 10:19

avatar de usuario de thkala
thkala

Supongo que su archivo a.out es un objeto compartido y no un ejecutable y sigo adelante…

dlsym() es una función de la biblioteca libdl, que normalmente reside en el objeto compartido libdl.so.2 en los sistemas Linux modernos.

Me arriesgaré a adivinar que su objeto compartido a.out no está vinculado a libdl. Eso significa que cuando precarga un binario simple como uname que no extrae muchas otras bibliotecas, es posible que libdl.so.2 no se extraiga y obtenga un error de símbolo indefinido.

Si, por otro lado, lo precarga en un binario que está vinculado y finalmente extrae libdl.so.2, su objeto compartido funciona bien.

consultaría con ldd si su propio objeto compartido está vinculado contra libdl como debería, y también qué bibliotecas se extraen directa o indirectamente cuando uname y ls correr.

EDITAR:

Acabo de confirmar esto. La forma de corregir este error es vincular su objeto compartido con libdl. agregando -ldl a su LDFLAGS debería hacer el truco.

  • Tenga en cuenta que -ldl puede necesitar estar antes de los otros archivos .o, por ejemplo, “gcc -ldl -shared foo.o bar.o -o baz.so”.

    – Señor Fooz

    8 mayo 2012 a las 16:34

  • Como se mencionó en la respuesta a continuación, -ldl en realidad debería ir al final de gcc línea si el enlace y la compilación se hacen juntos. He leído la explicación de que gcc crea una lista de símbolos a partir de archivos y luego los busca en las bibliotecas mencionadas después de sus nombres por alguna razón.

    – Marisha

    1 de octubre de 2019 a las 0:37

¿Ha sido útil esta solución?