那里的链接大师的问题。我一直在使用Matlab中的mex文件,并且已经收到了大量无法解释的崩溃,所以我想深入挖掘一下。
您可以向我解释当加载(卸载)动态模块时,如何在进程的虚拟内存空间中分配(解除分配)静态数据?
我认为这发生在_init()
和_fini()
函数中。但是,BSS段是否在堆空间中分配了一块内存,以及其他动态内存分配?
动态模块中的全局数据怎么样?是否有可能与主要可执行文件发生符号名称冲突?
感谢您了解这些问题。如果我必须选择一个平台,我想听听ELF专家的意见,因为我在Linux上进行了大部分的开发。
答案 0 :(得分:2)
您能解释一下在加载(卸载)动态模块时,如何在进程的虚拟内存空间中分配(解除分配)静态数据吗?
这部分很简单:每个ELF
文件都有PT_LOAD
个细分,您可以在readelf -Wl foo.so
的输出中看到这些细分。加载共享对象时,每个段都mmap
到地址空间,并作为该共享对象中任何静态数据的“分配”。
卸载foo.so
后,数据(和代码)将通过munmap
系统调用进行处理。
我认为这发生在_init()和_fini()函数
中
这个假设是不正确的。 _init
和_fini
是关于动态初始化的(例如C++
中具有非平凡构造函数/析构函数的类类型的全局变量)。在调用_init
时,所有全局变量的内存已经通过mmap
“保留”。
然而,BSS段
.bss
部分包含在其他初始化(可写)数据所在的PT_LOAD
段中。这就是为什么p_filesz
中有一个单独的p_memsz
和ElfXX_Phdr
:p_filesz
“涵盖”初始化数据,而(更大)p_memsz
导致mmap
{1}}为初始化和.bss
数据“分配”空间。
动态模块中的全局数据怎么样?
怎么样?我在上面介绍了初始化数据。
是否有可能与主要可执行文件发生符号名称冲突?
当然可以。您可以在int foo = 42;
中定义a.out
,在int foo = 24;
中定义foo.so
。通常的规则是如果<{em> foo
在a.out
的动态符号表中可见,则无论引用它在何处,都将使用foo
。
当a.out
未导出foo
时(如果它未与-rdymamic
相关联且未与foo.so
相关联),就会出现并发症,或foo.so
与-Bsymbolic
链接时。