C++ 加载程序如何从动态模块分配/释放静态数据

C++ 加载程序如何从动态模块分配/释放静态数据,c++,linker,loader,mex,elf,C++,Linker,Loader,Mex,Elf,对于链接器大师的问题。我一直在使用Matlab中的mex文件,遇到了很多无法解释的崩溃,所以我想深入挖掘 您能解释一下,当动态模块正在加载(卸载)时,静态数据是如何在进程的虚拟内存空间中分配(释放)的吗 我假设这发生在\u init()和\u fini()函数中。但是,BSS段是否在堆空间中分配了一块内存以及其他动态内存分配 动态模块中的全局数据如何?是否存在符号名称与主可执行文件冲突的可能性 感谢您为这些问题提供帮助。如果我必须选择一个平台,我想听听ELF专家的意见,因为我大部分的开发都是在L

对于链接器大师的问题。我一直在使用Matlab中的mex文件,遇到了很多无法解释的崩溃,所以我想深入挖掘

您能解释一下,当动态模块正在加载(卸载)时,静态数据是如何在进程的虚拟内存空间中分配(释放)的吗

我假设这发生在
\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)在链接器版本脚本中导出该符号。