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

Accessing memory allocated by shared library after dlclose()

经过一些研究后,我终于转向 SO 来问我的问题:共享库(使用 malloc()new)在使用 dlclose()?我观察到的行为是对此类内存的任何访问(取消引用它,使用 delete 运算符等)都会导致分段错误。它在某处定义了吗?

现在问这个问题似乎很愚蠢,当我知道在我完成内存之前调用 dlclose() 是错误的来源 - 通过在 delete 运算符上触发=11=]-created object received from a shared library - 这几天我一直在苦苦挣扎,但我想知道为什么,而不是仅仅猜测以防我以后遇到类似的情况。

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

what happens to the memory allocated by a shared library after the library is closed with dlclose().

取决于你所说的"allocated"是什么意思。

至少要考虑三种情况:

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

更新:

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

Do you have any clues I should follow to find out what went wrong?

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