我对 Linux 上的 C++ 共享库有一个奇怪的问题。
该过程两次加载和卸载我的库(这是设计使然,无法更改)。
- 在第一个 dlopen() 期间,我的库中的所有静态成员都以正确的顺序初始化。
- 然后,当第一个 dlclose() 被调用时,破坏也按预期进行,顺序与构造相反。
- 在第二次 dlopen() 期间,一切正常 - 构造顺序正确,与第一次相同。
- 但是在第二个 dlclose() 中,破坏的顺序突然被破坏了——析构函数的调用顺序与它们初始化的顺序相同,如果任何静态对象试图访问一个已经被破坏的对象,它通常会导致 SEGFAULT。
- dlopen()/dlclose() 的后续尝试完全重复第 3 步和第 4 步。
我试图用一个最小的例子重现这个问题,但没有成功——使用一个小的假共享库,一切都按预期工作。我的大型图书馆中有一些东西会导致第二个 dlclose() 受到破坏,而且它非常大。
我没有发现对 gcc(尝试 3.2/3.4/4.1.2)和 Linux 发行版(RHEL 4/5,SuSE 10)的依赖。在 Web 中搜索类似案例得到 0 个结果 - 没有类似的。
在实验过程中,我尝试在静态对象构造函数中嵌入一些对 atexit() 的调用,以查看 atexit() 处理程序的顺序是否受到影响,并发现确实如此。步骤 1/2/3 运行良好(dlopen/dlclose/dlopen),然后在第二个 dlclose 上 atexit 注册的处理程序的顺序不正确。
我真的不希望得到答案,但我非常感谢任何有关如何解决问题的建议。
先感谢您,
安德鲁·谢蒂宁
PS 更新 - 我在 GLIBC 的 atexit() 中调试了代码,发现我遇到了一个错误 - 实际上是一个非常简单的错误。它已在 GLIBC 2.4 中修复,我不幸使用 GLIBC 2.3.4