dlclose出错:"仍然引用的共享对象"

时间:2015-03-05 16:03:25

标签: linux shared-libraries posix qnx

我在dlclose()' d .so上出现以下错误:"仍然引用的共享对象"。我没有找到太多关于它的信息。你之前有过这样的问题吗?什么样的编程错误(或编译选项?)会导致这种情况?

我尝试的唯一一件事就是找到我的模块是否已成功释放所有引用的共享对象,但是我看到它们都是正常的。至少有希望。我还不能真正使用LD_DEBUG。

2 个答案:

答案 0 :(得分:2)

(在问题评论中发表重新讨论。)

以下可能在QNX上触发该错误/警告。我们首先需要两个共享库:

  • shared_needs.c

    /* References a function defined elsewhere. */
    
    void defined_elsewhere(void);
    
    void f(void) {
        defined_elsewhere();
    }
    
  • shared_has.c

    /* Has the function referenced above. */
    
    void defined_elsewhere(void) {}
    

我们按如下方式编译它们(使用sonames并省略其他好的做法以保持简单):

$ gcc -shared -fPIC shared_has.c -o shared_has.so
$ gcc -shared -fPIC shared_needs.c -o shared_needs.so

我们现在使用以下代码( loader.c )加载/卸载库,

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

int main(void) {
    void *shared_has;

    /* Pass RTLD_GLOBAL so that defined_elsewhere() becomes
       available to libraries loaded later. */
    shared_has = dlopen("shared_has.so", RTLD_NOW | RTLD_GLOBAL);
    if (shared_has == NULL) {
        fprintf(stderr, "%s\n", dlerror());
        return 1;
    }

    /* shared_needs.so resolves defined_elsewhere() from
       shared_has.so. */    
    if (dlopen("shared_needs.so", RTLD_NOW) == NULL) {
        fprintf(stderr, "%s\n", dlerror());
        return 1;
    }

    /* Might get warning here on QNX, since defined_elsewhere()
       is still used. */
    if (dlclose(shared_has) != 0) {
        fprintf(stderr, "%s\n", dlerror());
        return 1;
    }

    return 0;
}

,我们按如下方式编译和运行:

$ gcc loader.c -ldl -o loader
$ LD_LIBRARY_PATH=. ./loader

以上可能会在QNX上打印警告。它应该是安全的(因为它在Linux上),因为QNX上的dlclose()手册页说明如下:

  

在关闭对该对象的所有引用(通过dlopen()或其他对象的依赖关系)之前,不会从地址空间中删除对象。

作为旁注,您可以运行objdump -T shared_needs.so以查看 shared_needs.so defined_elsewhere()的未定义引用(查找 ** UND ** )。

答案 1 :(得分:1)

我无法找到&#34;仍然引用的共享对象&#34; Linux或开源库中的错误消息。此消息仅在QNX的上下文中提及。

此QT补丁https://qt.gitorious.org/qt/qtbase/commit/4af257eb3cfeef93adefda5f981742ffb58ba0ad表示此错误信息丰富,可以忽略

  

仅限QNX&#34;信息丰富&#34;

     

仍然引用的共享对象&#34; dlerror实际上应该被视为&#34;为了您的信息&#34;只是,而不是实际错误。

我们可以通过其他信息更多地了解错误: