首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >多次打开/关闭共享库后错误的静态销毁顺序

多次打开/关闭共享库后错误的静态销毁顺序
EN

Stack Overflow用户
提问于 2011-11-08 16:30:11
回答 2查看 815关注 0票数 0

我在Linux上的C++共享库有一个奇怪的问题。

该进程两次加载和卸载我的库(它是按设计进行的,不能更改)。

  1. 在第一个dlopen()期间,我的库中的所有静态成员都按照修正后的顺序初始化。然后,当调用第一个dlclose()时,破坏也会按预期的顺序进行,按照与construction.
  2. During相反的顺序(第二个dlopen() ),一切正常--构造的顺序与第一次一样。
  3. 但是在第二个dlclose()上,破坏的顺序突然被打破--析构函数的调用顺序与初始化的顺序相同,如果任何静态对象试图访问已经销毁的对象,则常常会导致SEGFAULT。
  4. 随后尝试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),那么在第二步中,atexit注册处理程序的顺序是不正确的。

我并不是真的希望得到答案,但我会非常感激任何关于如何解决这个问题的建议。

提前谢谢你,

施泰宁

更新--我在GLIBC中调试了atexit()中的代码,发现我碰到了一个bug --实际上是一个很简单的bug。它是在GLIBC 2.4中修正的,我不太幸运地使用GLIBC 2.3.4

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-15 08:53:15

它是GLIBC 2.3.x中的一个bug,它是在GLIBC 2.4中修复的。

这个bug是在非常特殊的条件下触发的--当一个进程打开并关闭一个C++库时,它在不同的对象文件中不止一次地使用了大量的静态变量。

atexit()条目组织在一个由32个处理程序指针组成的数组的单链列表中,atexit()中的旧代码将新的处理程序插入到单链列表中的错误页面中,从而打破了atexit()调用处理程序的契约,使它们按照注册的相反顺序完成处理程序。

票数 3
EN

Stack Overflow用户

发布于 2011-11-08 23:38:28

我不相信你可以依靠静态的ctor/dtor顺序通过任何想象力。你只是没有得到任何保证。

我希望看到设置和解压缩函数,您只调用一次。确保你只做了一次就属于你了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8053799

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档