在/proc/self/maps输出中分段到堆

在/proc/self/maps输出中分段到堆,c,operating-system,linux-kernel,virtual-memory,C,Operating System,Linux Kernel,Virtual Memory,我的程序在执行过程中的某个时刻,逐行读取自己的/proc/self/maps,直到(包括)堆。程序的路径为“/home/t4”。以下是输出: 00400000-00403000 r-xp 00000000 68:06 21629911 /home/t4 00602000-00603000 r--p 00002000 68:06 21629911 /home/t4 00603000-00604000 rw-p 00003000 68:06 21629911 /home/t4 00604000-00

我的程序在执行过程中的某个时刻,逐行读取自己的/proc/self/maps,直到(包括)堆。程序的路径为“/home/t4”。以下是输出:

00400000-00403000 r-xp 00000000 68:06 21629911 /home/t4
00602000-00603000 r--p 00002000 68:06 21629911 /home/t4
00603000-00604000 rw-p 00003000 68:06 21629911 /home/t4
00604000-00608000 rw-p 00000000 00:00 0
01905000-01926000 rw-p 00000000 00:00 0 [heap]

我只期望四个部分:代码、常量、静态变量、堆;但是这里有五个。第一个显然必须是代码,最后一个是堆。也许第二个是常数,但另外两个是什么呢?谢谢

初始化的静态变量后面是未初始化的静态变量(.BSS)-不需要存储在二进制文件中。

初始化的静态变量后面是未初始化的静态变量(.BSS)-不需要存储在二进制文件中。

第一个是可执行部分本身(由于x位),第二个可能是
.rodata
(缺少w位),第三个是其他所有内容(
.bss
.data
)。第四个是使用
MAP\u ANONYMOUS
进行的一些
mmap
调用的结果。请注意,
malloc
(3)可以很好地使用
mmap
(2)而不是
sbrk
(2)来实现。那里的
[heap]
对象是经典的sbrk堆(仅此而已),不包括使用mmap获得的私有可写区域。传统堆栈将被列为
[stack]
,但是子线程的堆栈可以使用任何内存区域来存储它们的堆栈,通常是malloc'd,因此您也不会看到多个
[stack]


完全混淆?:-)

第一个是可执行部分本身(由于x位),第二个可能是
.rodata
(没有w位),第三个是其他所有部分(
.bss
.data
)。第四个是使用
MAP\u ANONYMOUS
进行的一些
mmap
调用的结果。请注意,
malloc
(3)可以很好地使用
mmap
(2)而不是
sbrk
(2)来实现。那里的
[heap]
对象是经典的sbrk堆(仅此而已),不包括使用mmap获得的私有可写区域。传统堆栈将被列为
[stack]
,但是子线程的堆栈可以使用任何内存区域来存储它们的堆栈,通常是malloc'd,因此您也不会看到多个
[stack]


完全混淆?:-)

谢谢!我无法调用mprotect将(已映射的)初始化的静态变量段设置为只读,这有什么原因吗?当我这样做的时候,我得到一个segfault,而我可以使未初始化的静态变量和堆段只读,而没有任何segfault。这取决于其中的内容。如果您的程序立即修改了某些内容,那么当然存在segfault。例如,用于链接的.got全局偏移表。谢谢!我无法调用mprotect将(已映射的)初始化的静态变量段设置为只读,这有什么原因吗?当我这样做的时候,我得到一个segfault,而我可以使未初始化的静态变量和堆段只读,而没有任何segfault。这取决于其中的内容。如果您的程序立即修改了某些内容,那么当然存在segfault。例如,用于链接的.get全局偏移表。第四个实际上可能是
.bss
,因为
.bss
段不占用二进制文件中的任何空间,因此无法从那里映射。第四个实际上可能是
.bss
,由于
.bss
段不占用二进制文件中的任何空间,因此无法从那里映射。