我在Linux上的C++共享库有一个奇怪的问题。
该进程两次加载和卸载我的库(它是按设计进行的,不能更改)。
我尝试用一个最小的例子来重现这个问题,但是没有成功--用一个小的假共享库--一切都像预期的那样工作。我的大型库中有一些东西导致了第二个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),那么在第二步中,atexit注册处理程序的顺序是不正确的。
我并不是真的希望得到答案,但我会非常感激任何关于如何解决这个问题的建议。
提前谢谢你,
施泰宁
更新--我在GLIBC中调试了atexit()中的代码,发现我碰到了一个bug --实际上是一个很简单的bug。它是在GLIBC 2.4中修正的,我不太幸运地使用GLIBC 2.3.4
发布于 2011-11-15 08:53:15
它是GLIBC 2.3.x中的一个bug,它是在GLIBC 2.4中修复的。
这个bug是在非常特殊的条件下触发的--当一个进程打开并关闭一个C++库时,它在不同的对象文件中不止一次地使用了大量的静态变量。
atexit()条目组织在一个由32个处理程序指针组成的数组的单链列表中,atexit()中的旧代码将新的处理程序插入到单链列表中的错误页面中,从而打破了atexit()调用处理程序的契约,使它们按照注册的相反顺序完成处理程序。
发布于 2011-11-08 23:38:28
我不相信你可以依靠静态的ctor/dtor顺序通过任何想象力。你只是没有得到任何保证。
我希望看到设置和解压缩函数,您只调用一次。确保你只做了一次就属于你了。
https://stackoverflow.com/questions/8053799
复制相似问题