C++ 加载程序如何从动态模块分配/释放静态数据
对于链接器大师的问题。我一直在使用Matlab中的mex文件,遇到了很多无法解释的崩溃,所以我想深入挖掘 您能解释一下,当动态模块正在加载(卸载)时,静态数据是如何在进程的虚拟内存空间中分配(释放)的吗 我假设这发生在C++ 加载程序如何从动态模块分配/释放静态数据,c++,linker,loader,mex,elf,C++,Linker,Loader,Mex,Elf,对于链接器大师的问题。我一直在使用Matlab中的mex文件,遇到了很多无法解释的崩溃,所以我想深入挖掘 您能解释一下,当动态模块正在加载(卸载)时,静态数据是如何在进程的虚拟内存空间中分配(释放)的吗 我假设这发生在\u init()和\u fini()函数中。但是,BSS段是否在堆空间中分配了一块内存以及其他动态内存分配 动态模块中的全局数据如何?是否存在符号名称与主可执行文件冲突的可能性 感谢您为这些问题提供帮助。如果我必须选择一个平台,我想听听ELF专家的意见,因为我大部分的开发都是在L
\u init()
和\u fini()
函数中。但是,BSS段是否在堆空间中分配了一块内存以及其他动态内存分配
动态模块中的全局数据如何?是否存在符号名称与主可执行文件冲突的可能性
感谢您为这些问题提供帮助。如果我必须选择一个平台,我想听听ELF专家的意见,因为我大部分的开发都是在Linux上进行的
您能解释一下,当动态模块正在加载(卸载)时,静态数据是如何在进程的虚拟内存空间中分配(释放)的吗
这一部分很简单:每个ELF
文件都有PT\u LOAD
段,您可以在readelf-Wl foo.so
的输出中看到这些段。加载共享对象时,这些段中的每一段都被mmap
分配到地址空间,并作为该共享对象中任何静态数据的“分配”
卸载foo.so
时,通过munmap
系统调用处理数据(和代码)
我假设这发生在_init()和_fini()函数中
这种假设是不正确的。\u init
和\u fini
是关于动态初始化的(例如C++
中类类型的全局变量,具有非平凡的构造函数/析构函数)。调用\u init
时,所有全局变量的内存已通过mmap
进行“保留”
然而,BSS部门
.bss
部分包含在与其他初始化(可写)数据相同的PT\u LOAD
段中。这就是为什么在ElfXX_Phdr
中有一个单独的p_filesz
和p_memsz
的原因:p_filesz
覆盖了初始化数据,并且(更大的)p_memsz
导致mmap
为初始化数据和bss
数据“分配”空间
动态模块中的全局数据如何
怎么样?我在上面介绍了初始化数据
是否存在符号名称与主可执行文件冲突的可能性
当然可以。您可以定义intfoo=42代码>输入a.out
,和intfoo=24代码>在foo.so
中。通常的规则是,如果foo
在a.out
的动态符号表中可见,则无论从何处引用foo
,都将使用该foo
当a.out
没有导出foo
(如果它没有链接到-rdymac
,也没有链接到foo.so
),或者当foo.so
链接到-Bsymbolic感谢@employeedrussian,我在动态符号表上挖掘了更多信息,似乎只有在指定-rdynamic时,全局符号才会导出到动态符号表中。通常情况下,它们不会被导出,因此动态模块无法从可执行文件访问它们。这是正确的吗?@DKWH从a.out导出符号有三种方法(据我所知):(1)使用-rdynamic
(或-E
,或-export dynamic
)或(2)直接链接foo。因此使用该符号的,或(3)在链接器版本脚本中导出该符号。