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

标签 c gcc ld dynamic-linking

我正在关注this answer覆盖对 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_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告诉链接器,如果共享库具有未解析的 undefined symbol ,它应该发出错误,因此将来出现此类类型的问题将被更早地捕获。选项 -Wl,--as-needed 告诉链接器不要记录对实际上不满足任何 undefined symbol 的库的依赖关系。默认情况下,这两个应该处于启用状态,但由于历史原因,它们并未启用。

关于c - 使用 LD_PRELOAD 重载对共享库的 C 函数的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16217529/

相关文章:

c - 如何(f)在c中同步linux下的目录

c - 使用 CMake 将共享库与静态链接起来

c - getsockopt 类似 TCP_INFO 的 UDP 统计信息

c++ - RedHat 上 GCC 4.4.5 中的运行时问题,但在 Apple llvm 4.2 上运行正常?

c - 进程的退出状态如何取决于它是否是静态构建的?

gcc - 组装结束后附有说明

C编程EXC_BAD_ACCESS(代码:1 ,地址=0x0)错误

c++ - gcc 的 -Wconversion 是否与使用比 int 短的整数类型的复合赋值(+= 等)不兼容?

linux - pkg-config --libs 返回 .la 文件,但 g++ 无法处理它

c++ - ld 没有加载所需的目标文件