使用LD_PRELOAD重载对共享库的C函数的调用

使用LD_PRELOAD重载对共享库的C函数的调用,c,gcc,ld,dynamic-linking,C,Gcc,Ld,Dynamic Linking,下面我将重写对C库的C函数的调用 我认为我做的每件事都是正确的,但它不起作用: 我想覆盖“DibOpen”函数。这是我在运行应用程序时传递给LD_PRELOAD环境变量的库代码: DIBSTATUS DibOpen(void **ctx, enum Board b) { printf("look at me, I wrapped\n"); static DIBSTATUS (*func)(void **, enum Board) = NULL; if(!func)

下面我将重写对C库的C函数的调用

我认为我做的每件事都是正确的,但它不起作用:

我想覆盖“DibOpen”函数。这是我在运行应用程序时传递给LD_PRELOAD环境变量的库代码:

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);
}
nm lib.so | grep DibOpen的输出显示

000000000001d711 T DibOpen
当我像这样运行我的程序时

LD_PRELOAD=libPreload.so ./program
我用-ldl链接了我的
程序
,但是
ldd程序
没有显示到libdl.so的链接

它以

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

。我可以做些什么来进一步调试它?我的错误在哪里?

当您创建共享库时(无论它是否将用于
LD\u PRELOAD
),您需要命名它解决其依赖关系所需的所有库。(在某些情况下,
dlopen
ed共享对象可以依赖可执行文件为其提供符号,但最好不要依赖于此。)在这种情况下,您需要链接
libPreload。因此
libdl
相对。在Makefile ese中:

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

选项
-Wl,-z,defs
告诉链接器,如果共享库中有未解析的未定义符号,则链接器应发出错误,因此此类型的未来问题将在前面发现。选项
-Wl,--as-needed
告诉链接器不要记录对实际上不满足任何未定义符号的库的依赖关系。默认情况下,这两个选项都应该启用,但由于历史原因,它们没有启用。

您需要链接
libPreload。因此
,而不是
程序
,使用
-ldl
。如果你已经这样做了,请发布你的Makefile。我甚至不知道你可以互相链接库。现在可以了。请回答你的评论。我使用cmake。