尽管dlclose,动态加载的库仍然会加载

时间:2015-04-03 11:56:52

标签: linux dynamic-loading

今天我正在寻找动态装载机内部深层魔法的一些启示。我正在调试/排除在Linux上运行的C ++应用程序的插件系统故障。它通过dlopen(RTLD_NOW | RTLS_LOCAL)加载插件,并使用dlclose释放它们。没有什么特别的 - 人们会想。

但是,我注意到即使在成功调用{sup> * dlclose之后,仍会加载一些插件。在使用pmap查看正在运行的进程内存映射后,我得出结论。有些库会立即从进程内存中删除,而其他库则会无限期地挥之不去。

继续,dlopen man页面说明:

  

函数dlclose()减少动态的引用计数   库句柄。如果引用计数降为零而不是   其他加载的库在其中使用符号,然后动态库是   卸载。

这意味着问题归结为这两种可能性;引用计数不是零,或者其他加载的库使用来自某些插件(但不是全部)插件的符号。

我很确定(尽管不是100%)引用计数为零。应用程序的插件管理器处理所有插件完全相同。它还确保插件不会多次加载。 IMO loading&因此,对于所有插件,卸载应该表现相同。

这留下了第二种可能性:其他加载的库正在使用插件中的符号。另一个典型案例'应该永远不会发生'。虽然这当然是可能的。我们正在使用gcc和默认可见性,据我所知,没有任何东西被剥离,因此导出了大量的符号。实际上,这让我更加担心,因为这些插件应该是独立的。

此时此处是我的开放性问题:

  • 到目前为止我的结论是否正确?
  • 您是否知道验证dlopen引用计数的方法?
  • 如果我的插件的内部符号(意外地)被其他库使用,是否有办法追踪谁在使用哪些符号?

我的机器是: Linux 3.13.0-43-generic#72-Ubuntu SMP Mon Dec 8 19:35:44 UTC 2014 i686 i686 i686 GNU / Linux

* 我应该提到所有的加载和卸载都发生在主线程中,因此这里不存在多线程问题。

1 个答案:

答案 0 :(得分:1)

  

其他已加载的库正在使用插件中的符号

如果其他lib在链接时未链接到该共享库,则引用共享库的符号不会阻止卸载该共享库。

将运行时链接程序集环境变量LD_DEBUG调试为all,例如LD_DEBUG=all ./my_app。有关详细信息,请参阅man ld.so