在dlclose()之后访问由共享库分配的内存

4
经过一些研究之后,最终我向SO提出了我的问题:使用malloc()new动态分配的内存在共享库被dlclose()关闭后会发生什么?我观察到的行为是,访问这样的内存(解引用它,在其中使用delete运算符等)会导致段错误。这是否有明确定义?
现在看来这似乎是一个愚蠢的问题,因为我知道在完成内存使用之前调用dlclose()是导致由共享库接收的new创建的对象上使用delete运算符时遇到的错误源,我已经为此奋斗了几天,但我想知道为什么会这样,而不仅仅是猜测,以防将来遇到类似情况。

可能相关的问题:https://stackoverflow.com/questions/31375177/why-might-mallocd-memory-from-a-shared-library-be-inaccessible-to-the-applicati https://dev59.com/ZFPTa4cB1Zd3GeqPj4Sk https://dev59.com/jZXfa4cB1Zd3GeqPjb_Q - Maelkum
2个回答

6
使用dlclose()关闭共享库后,由共享库分配的内存会发生什么取决于"分配"的含义。至少有以下三种情况需要考虑:
1. 使用mallocnew分配的内存。 dlclose不会产生影响。
2. 库内部全局变量。 dlclose()可能munmap()内存(也可能不会,这取决于是否使用了库中的其他符号)。如果发生munmap,则该内存将完全无法访问。
3. 库创建了全局对象(例如全局std::string)。对象使用::new为自己分配内部存储空间(就像string那样)。当库被dlclose时,对象可能被析构。如果它被析构,则会::delete该内存。该内存可能仍然可访问,但访问它会引发未定义行为(就像任何对悬挂内存的访问一样)。
更新:对于情况#1,new的内存仍然可以访问。但是,该new对象内的任何嵌套指针可能无法访问。在C++中,如果对象具有虚函数,则虚表指针可能变得无法访问(它指向卸载的foo.so中的只读数据),此情况等同于#2。
“你有任何线索可以帮助我查找出了什么问题吗?”是的:使用常规的调试技术:在GDB下运行程序,找出它精确崩溃的位置。如果仍然无法理解崩溃,请使用一些代码编辑您的问题,以显示程序正在执行的操作,以及它的GDB输出。

1
谢谢。我编辑了问题以澄清我正在访问由运算符new分配的内存。但是,如果您说dlclose()关闭库对这样的内存没有影响,那么错误必须出现在其他地方 - 对我来说,看起来确实是这种情况,并且访问对象触发了段错误。您有任何线索应该跟随以找出出了什么问题吗? - Maelkum
2
@EmployedRussion 这就是我在寻找的:虚表指针可能变得不可访问。由.so分配的对象具有虚析构函数 - 这解释了为什么调用delete运算符会触发段错误。感谢您分享知识。我将您的答案标记为已接受的答案。 - Maelkum

-1

内存被释放回操作系统。任何剩余的引用都是无效的,不再属于您的进程,这就是为什么尝试对它们进行任何操作都会触发段错误。


这是一个完全虚假的答案。 - Employed Russian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接