在 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"是什么意思。
至少要考虑三种情况:
- 使用
malloc
或new
分配内存。 dlclose
将 无效。
- 库中的全局变量。
dlclose()
可能 munmap()
内存(或不;取决于是否使用了库中的其他符号)。如果确实发生munmap
,内存将完全无法访问。
- 库创建一个全局对象(例如全局
std::string
)。该对象使用 ::new
(就像 string
那样)为自己分配内部存储空间。当库为dlclose
d时,对象可能被销毁。如果它被破坏,它将 ::delete
那段记忆。内存可能仍然可以访问,但访问它会调用未定义的行为(就像对悬空内存的任何其他访问一样)。
更新:
对于情况 #1,new
d 内存仍然可以访问。但是该 new
d 对象中的任何 嵌套 指针可能不是。在C++
中,如果对象有虚函数,虚table指针可能变得不可访问(它指向现在卸载的foo.so
中的只读数据),这种情况等同于#2.
Do you have any clues I should follow to find out what went wrong?
是:使用通常的调试技术:运行 GDB下的程序,找出哪里它崩溃了。如果您仍然无法理解崩溃,请使用一些代码来编辑您的问题,这些代码可以显示程序正在做什么,以及 GDB 的输出。
经过一些研究后,我终于转向 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"是什么意思。
至少要考虑三种情况:
- 使用
malloc
或new
分配内存。dlclose
将 无效。 - 库中的全局变量。
dlclose()
可能munmap()
内存(或不;取决于是否使用了库中的其他符号)。如果确实发生munmap
,内存将完全无法访问。 - 库创建一个全局对象(例如全局
std::string
)。该对象使用::new
(就像string
那样)为自己分配内部存储空间。当库为dlclose
d时,对象可能被销毁。如果它被破坏,它将::delete
那段记忆。内存可能仍然可以访问,但访问它会调用未定义的行为(就像对悬空内存的任何其他访问一样)。
更新:
对于情况 #1,new
d 内存仍然可以访问。但是该 new
d 对象中的任何 嵌套 指针可能不是。在C++
中,如果对象有虚函数,虚table指针可能变得不可访问(它指向现在卸载的foo.so
中的只读数据),这种情况等同于#2.
Do you have any clues I should follow to find out what went wrong?
是:使用通常的调试技术:运行 GDB下的程序,找出哪里它崩溃了。如果您仍然无法理解崩溃,请使用一些代码来编辑您的问题,这些代码可以显示程序正在做什么,以及 GDB 的输出。