【问题标题】:unresolved symbol __real_malloc while dynamically loading a library which is compiled with --wrap=malloc动态加载使用 --wrap=malloc 编译的库时未解析的符号 __real_malloc
【发布时间】:2014-10-23 11:37:22
【问题描述】:

正如其他 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 SO answer,malloc 应该被替换为__wrap_malloc__real_malloc 在使用这种技术时应该指向malloc

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

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

以防万一,不能修改通过dlopen加载动态库的目标应用程序。

【问题讨论】:

    标签: c++ linux linker dynamic-library dynamic-loading


    【解决方案1】:

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

    testapp.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
    

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

    【讨论】:

    • 感谢您的示例,很抱歉这么晚才回来。将extern "C" 声明添加到函数后,将包含更改为c++ 等效项,并使用g++ 编译文件,它适用于本示例。不幸的是,我正在处理的项目要复杂得多。所以它似乎是它的构建过程中的一个问题。如果我有更多关于这个问题的细节,也许我会更新这个问题。
    猜你喜欢
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 2017-04-13
    相关资源
    最近更新 更多