Setting my lib for LD_PRELOAD makes some processes produce loader errors
Asked Answered
G

2

18

I get the following error when I try to run a script I have only execution access for:

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

This is after I have set LD_PRELOAD environment variable to /home/dumindara/random/sotest/a.out.

a.out has a test malloc function, and calls dlsym internally.

I don't get this problem when running ls. Most processes do give this error. Why does this happen and what can I do to make it work?

Genocide answered 8/12, 2010 at 7:33 Comment(3)
It's generally a good idea to set LD_PRELOAD only for a.out, rather than modifying the shell environment. In most UNIX shells you can type: LD_PRELOAD=xyz ./a.out. Otherwise, try ( LD_PRELOAD=xyz; ./a.out ).Mellen
@Tony: I think that a.out is a shared object in this case, despite its ill-chosen name. The OP is apparently trying to override malloc() with their own version and then pass-through to the real malloc.Lackluster
@tkhala: ah, good catch... would be more like LD_PRELOAD=`pwd`/a.out program_to_test then....Mellen
L
18

I assume that your a.out file is a shared object and not a executable and move on...

dlsym() is a function from the libdl library, which usually resides in the libdl.so.2 shared object on modern Linux systems.

I'll hazzard a guess that your a.out shared object is not linked to libdl. That means that when you preload in a simple binary like uname that does not pull in a lot of other libraries, libdl.so.2 may not be pulled in and you get an undefined symbol error.

If, on the other hand, you preload it to a binary that is linked to and finally pulls in libdl.so.2, your shared object works fine.

I'd check with ldd if your own shared object is linked against libdl as it should, and also what libraries are directly or indirectly pulled in when uname and ls run.

EDIT:

I just confirmed this. The way to fix this error is to link your shared object against libdl. Adding -ldl to its LDFLAGS should do the trick.

Lackluster answered 8/12, 2010 at 7:51 Comment(2)
Note that -ldl may need to be before the other .o files, e.g. "gcc -ldl -shared foo.o bar.o -o baz.so".Pyramid
As happened to be mentioned in answer below, -ldl actually should go at the end of gcc line if linking and compilation is done together. I've read explanation that gcc builds list of symbols from files and then searches for them in libraries mentioned after their names for some reason.Mcgovern
K
38

I am unable to comment to the accepted answer, however it is worth to mention here that one can encounter issue of not having libdl.so.2 linked properly when -ldl is used in front of compile command (assuming that linking and compilation is executed by the same command; this is possible since LD_PRELOAD libs are usually based on one source file).

So call gcc with -ldl at the end:

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

In my case, having -ldl at front resulted in error same as in question:

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

Khabarovsk answered 24/10, 2012 at 9:8 Comment(1)
yes thumbs up!!! thkala answer still gave me error, but your "-ldl" at the end solved everything.Pissarro
L
18

I assume that your a.out file is a shared object and not a executable and move on...

dlsym() is a function from the libdl library, which usually resides in the libdl.so.2 shared object on modern Linux systems.

I'll hazzard a guess that your a.out shared object is not linked to libdl. That means that when you preload in a simple binary like uname that does not pull in a lot of other libraries, libdl.so.2 may not be pulled in and you get an undefined symbol error.

If, on the other hand, you preload it to a binary that is linked to and finally pulls in libdl.so.2, your shared object works fine.

I'd check with ldd if your own shared object is linked against libdl as it should, and also what libraries are directly or indirectly pulled in when uname and ls run.

EDIT:

I just confirmed this. The way to fix this error is to link your shared object against libdl. Adding -ldl to its LDFLAGS should do the trick.

Lackluster answered 8/12, 2010 at 7:51 Comment(2)
Note that -ldl may need to be before the other .o files, e.g. "gcc -ldl -shared foo.o bar.o -o baz.so".Pyramid
As happened to be mentioned in answer below, -ldl actually should go at the end of gcc line if linking and compilation is done together. I've read explanation that gcc builds list of symbols from files and then searches for them in libraries mentioned after their names for some reason.Mcgovern

© 2022 - 2024 — McMap. All rights reserved.