gpt4 book ai didi

c++ - 动态加载使用 --wrap=malloc 编译的库时未解析的符号 __real_malloc

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:56:27 26 4
gpt4 key购买 nike

如其他 SO 答案中所述,我使用 GNU ld 的包装机制拦截对 Linux 上的 malloc 的调用(有关示例,请参见 here)。使用的链接器标志是 -Wl,--wrap=malloc 并且还定义了相应的 void __wrap_malloc(size_t)。这在所有编译单元都链接到同一个二进制文件的测试应用程序中运行良好。

现在,我需要修改通过dlopen() 加载到主程序中的动态链接库。链接库成功,但将其加载到主程序失败并显示 undefined symbol: __real_malloc

在库上运行 nm 显示 __wrap_malloc 已定义,但 __real_malloc 未定义。但是,根据 man ldthis所以回答,malloc 应该被替换为 __wrap_malloc 并且 __real_malloc 在使用这种技术时应该指向 malloc

在测试应用程序中,我看到 __real_malloc 在已编译的目标文件中未定义,但在链接到可执行文件后已解析。

那么,为什么在测试应用中解析了符号,而在动态库中却没有呢?在这两种情况下,都会执行最后的链接步骤来解析此符号。或者是否需要在动态库的链接步骤中添加另一个库才能解析__real_malloc

以防万一,无法修改通过dlopen加载动态库的目标应用。

最佳答案

它应该可以工作,只需要对您链接的问题中的代码稍作改动。

测试应用.c

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

typedef void f_t(void);

int main()
{
void* h = dlopen("./malloc_wrapper.so", RTLD_NOW);
if (h == NULL)
{
puts(dlerror());
exit(1);
}

f_t* f = (f_t*)dlsym(h, "test");

if (f == NULL)
{
puts(dlerror());
exit(1);
}

(*f)();

return 0;
}

malloc_wrapper.c

#include <stdlib.h> /* added */
#include <stdio.h>
void *__real_malloc (size_t);

/* This function wraps the real malloc */
void *__wrap_malloc(size_t size)
{
void *lptr = __real_malloc(size);
printf("Malloc: %lu bytes @%p\n", size, lptr);
return lptr;
}

void test(void) /* added */
{
free(malloc(1024));
}

编译运行

gcc -Wl,-wrap,malloc -shared -fpic malloc_wrapper.c -o malloc_wrapper.so
gcc testapp.c -o testapp -ldl
./testapp
Malloc: 1024 bytes @0x1d44680

像这样编译 malloc_wrapper.so 会重现您描述的错误:

gcc -shared -fpic malloc_wrapper.c -o malloc_wrapper.so
./testapp
./malloc_wrapper.so: undefined symbol: __real_malloc

也许您在编译和链接可执行文件而不是共享对象时使用了换行?

关于c++ - 动态加载使用 --wrap=malloc 编译的库时未解析的符号 __real_malloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25568595/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com