2

我正在按照这个答案覆盖对 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

我将我program的与 -ldl 链接,但ldd program没有显示到 libdl.so 的链接

它停止于

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

. 我能做些什么来进一步调试呢?我的错误在哪里?

4

1 回答 1

5

当你创建一个共享库时(不管它是否会在 中使用LD_PRELOAD),你需要命名需要解决其依赖关系的所有库。(在某些情况下,dlopened 共享对象可以依赖可执行文件为其提供符号,但最好不要依赖它。)在这种情况下,您需要链接libPreload.solibdl. 在 Makefile 中:

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

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

于 2013-04-25T15:51:00.997 回答