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() 关闭共享库后,共享库分配的内存会发生什么变化。

取决于你所说的“分配”是什么意思。

至少要考虑三种情况:

    使用mallocnew 分配内存。 dlclose无效。 库中的全局变量。 dlclose() 可能 munmap() 内存(或没有;取决于是否使用了库中的其他符号)。如果munmap 确实发生了,内存将完全无法访问。 库创建一个全局对象(如全局std::string)。该对象使用::new 为自己分配内部存储空间(就像string 那样)。当库为dlclosed 时,对象可能被破坏。如果它被破坏,它将::delete该内存。内存可能仍然可以访问,但访问它会调用未定义的行为(就像对悬空内存的任何其他访问一样)。

更新:

对于案例 #1,newd 内存仍然可以访问。但是newd 对象中的任何嵌套 指针可能不是。在C++中,如果对象有虚函数,虚表指针可能会变得不可访问(它指向现在卸载的foo.so中的只读数据),这种情况相当于#2。

你有什么线索可以让我找出问题所在吗?

是的:使用通常的调试技术:在 GDB 下运行程序,找出 哪里 它到底崩溃了。如果您仍然无法理解崩溃,请使用一些代码编辑您的问题,这些代码显示程序正在执行的操作,以及它的 GDB 输出。

【讨论】:

谢谢。我编辑了问题以澄清我正在访问由操作员new 分配的内存。但是,如果您说dlclose()-ing 该库对此类内存没有影响,则该错误必须在其他地方-对我来说,情况确实如此,并且访问该对象触发了段错误。你有什么线索可以让我找出问题所在吗? @EmployedRussion 这就是我要找的:*虚拟表指针可能变得不可访问*。 .so 分配的对象具有虚拟析构函数——这解释了为什么调用 delete 运算符会触发段错误。谢谢分享知识。我将您的答案标记为已接受。【参考方案2】:

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

【讨论】:

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

以上是关于dlclose() 后访问共享库分配的内存的主要内容,如果未能解决你的问题,请参考以下文章

RSS/PSS/VSZ

共享库不能访问程序的内存

Linux C++ libdl.so dlfcn.h使用方法(dlopen()dlsym()dlclose()dlerror())(用于动态链接库操作)(懒加载立即加载)共享库符号动态库

c# 通过内存映射实现文件共享内存

adb 查看内存,cpu,流量

限制子进程访问共享内存和消息队列