2

I'm following this answer to override a call to a C function of a C library.

I think I did everything correctly, but it doesn't work:

I want to override the "DibOpen"-function. This is my code of the library which I pass to LD_PRELOAD environment-variable when running my application:

DIBSTATUS DibOpen(void **ctx, enum Board b)
{
    printf("look at me, I wrapped\n");

    static DIBSTATUS (*func)(void **, enum Board) = NULL;
    if(!func)
        func = dlsym(RTLD_NEXT, "DibOpen");
    printf("Overridden!\n");
    return func(pContextAddr, BoardType, BoardHdl);
}

The output of nm lib.so | grep DibOpen shows

000000000001d711 T DibOpen

When I run my program like this

LD_PRELOAD=libPreload.so ./program

I link my program with -ldl but ldd program does not show a link to libdl.so

It stops with

 symbol lookup error: libPreload.so: undefined symbol: dlsym

. What can I do to debug this further? Where is my mistake?

Community
  • 1
  • 1
Patrick B.
  • 11,773
  • 8
  • 58
  • 101
  • 2
    You need to link *`libPreload.so`*, not `program`, with `-ldl`. If you're already doing that, please post your Makefile. – zwol Apr 25 '13 at 14:34
  • 1
    I wasn't even aware that you can link libraries between each others. It works now. Make your comment an answer, please. I use cmake. – Patrick B. Apr 25 '13 at 14:36

1 Answers1

5

When you create a shared library (whether or not it will be used in LD_PRELOAD), you need to name all of the libraries that it needs to resolve its dependencies. (Under some circumstances, a dlopened shared object can rely on the executable to provide symbols for it, but it is best practice not to rely on this.) In this case, you need to link libPreload.so against libdl. In Makefile-ese:

libPreload.so: x.o y.o z.o
        $(CC) -shared -Wl,-z,defs -Wl,--as-needed -o $@ $^ -ldl

The option -Wl,-z,defs tells the linker that it should issue an error if a shared library has unresolved undefined symbols, so future problems of this type will be caught earlier. The option -Wl,--as-needed tells the linker not to record a dependency on libraries that don't actually satisfy any undefined symbols. Both of these should be on by default, but for historical reasons, they aren't.

zwol
  • 135,547
  • 38
  • 252
  • 361