dlclose() 后访问共享库分配的内存
Posted
技术标签:
【中文标题】dlclose() 后访问共享库分配的内存【英文标题】:Accessing memory allocated by shared library after dlclose() 【发布时间】:2016-04-09 23:37:06 【问题描述】:在做了一些研究之后,我终于转向 SO 问我的问题:在使用 dlclose()
关闭库后,共享库(使用 malloc()
或 new
)动态分配的内存会发生什么?我观察到的行为是对此类内存的任何访问(取消引用它,使用delete
运算符等)都会导致分段错误。它是在某个地方定义的吗?
现在这似乎是一个愚蠢的问题,当我知道在我完成内存之前调用 dlclose()
是错误的来源 - 通过在收到的 new
创建的对象上使用 delete
运算符触发来自共享库 - 过去几天我一直在苦苦挣扎,但我想知道为什么,而不是仅仅猜测以防我将来遇到类似情况。
【问题讨论】:
可能相关问题:***.com/questions/31375177/…***.com/questions/4732018/…***.com/questions/36420174/… 【参考方案1】:使用
dlclose()
关闭共享库后,共享库分配的内存会发生什么变化。
它取决于你所说的“分配”是什么意思。
至少要考虑三种情况:
-
使用
malloc
或new
分配内存。 dlclose
将无效。
库中的全局变量。 dlclose()
可能 munmap()
内存(或没有;取决于是否使用了库中的其他符号)。如果munmap
确实发生了,内存将完全无法访问。
库创建一个全局对象(如全局std::string
)。该对象使用::new
为自己分配内部存储空间(就像string
那样)。当库为dlclose
d 时,对象可能被破坏。如果它被破坏,它将::delete
该内存。内存可能仍然可以访问,但访问它会调用未定义的行为(就像对悬空内存的任何其他访问一样)。
更新:
对于案例 #1,new
d 内存仍然可以访问。但是new
d 对象中的任何嵌套 指针可能不是。在C++
中,如果对象有虚函数,虚表指针可能会变得不可访问(它指向现在卸载的foo.so
中的只读数据),这种情况相当于#2。
你有什么线索可以让我找出问题所在吗?
是的:使用通常的调试技术:在 GDB 下运行程序,找出 哪里 它到底崩溃了。如果您仍然无法理解崩溃,请使用一些代码编辑您的问题,这些代码显示程序正在执行的操作,以及它的 GDB 输出。
【讨论】:
谢谢。我编辑了问题以澄清我正在访问由操作员new
分配的内存。但是,如果您说dlclose()
-ing 该库对此类内存没有影响,则该错误必须在其他地方-对我来说,情况确实如此,并且访问该对象触发了段错误。你有什么线索可以让我找出问题所在吗?
@EmployedRussion 这就是我要找的:*虚拟表指针可能变得不可访问*。 .so
分配的对象具有虚拟析构函数——这解释了为什么调用 delete
运算符会触发段错误。谢谢分享知识。我将您的答案标记为已接受。【参考方案2】:
内存被释放回操作系统。剩下的任何引用都是无效的,不再属于您的进程,这就是为什么尝试对它们做任何事情都会导致段错误。
【讨论】:
这是一个完全虚假的答案。以上是关于dlclose() 后访问共享库分配的内存的主要内容,如果未能解决你的问题,请参考以下文章
Linux C++ libdl.so dlfcn.h使用方法(dlopen()dlsym()dlclose()dlerror())(用于动态链接库操作)(懒加载立即加载)共享库符号动态库