关于sbrk()和malloc()

时间:2015-12-13 07:18:21

标签: c linux operating-system sbrk

我已经彻底阅读了关于sbrk()的linux手册:

  

sbrk()更改程序中断的位置,该位置定义结束   进程的数据段(即,程序中断是第一个)   未初始化数据段结束后的位置。)

我知道用户空间内存的组织如下: enter image description here

问题是: 当我调用sbrk(1)时,为什么说我增加了堆的大小?正如手册所说,我正在改变“数据段& bss”的结束位置。那么,数据段的大小应该增加多少呢? bss,对吧?

2 个答案:

答案 0 :(得分:3)

数据和bss段是固定大小。因此,在这些细分结束后分配给流程的空间不属于这些细分市场;它只是与它们相邻。该空间称为堆空间,用于动态内存分配。

如果您想将其视为'扩展数据/ bss细分市场,那也很好。它不会对程序的行为,或者分配的空间或任何东西产生任何影响。

Mac OS X上的手册页表明你真的不应该使用它们:

  

brk和sbrk函数是虚拟内存管理出现前几天遗留下来的历史好奇心。 brk()函数设置进程的中断或最低地址' s数据段(未初始化的数据)到addr(紧接在bss之上)。数据寻址在addr和到堆栈段的最低堆栈指针之间受到限制。内存由页面大小的brk分配;如果addr不能被系统页面大小整除,则会增加到下一页边界。

     

sbrk(0)可以可靠地返回程序中断的当前值(另请参阅 end(3))。 getrlimit(2)系统调用可用于确定数据段的最大允许大小;我们无法将中断设置为超出rlim_max调用返回的getrlimit值,例如etext + rlp->rlim_max(有关etext的定义,请参阅 end(3)

令人感到有点恼火的是,我找不到 end(3)的手册页,尽管有关于它的指示。即使sbrk()的这个(略显陈旧的)手册页也没有链接。

答案 1 :(得分:2)

请注意,今天很少使用sbrk(2)。大多数malloc实现使用mmap(2) - 至少用于大型分配 - 来获取内存段(以及munmap来释放它)。通常情况下,free只是标记一个内存区域可以被某个未来malloc重用(并且不会向Linux kernel释放任何内存)。

(实际上,现代linux进程的堆由几个段组成,因此比你的图片更精细;多线程进程每个{{3 }})功能

使用thread,尤其是/proc/self/maps/proc/$pid/maps,了解某些proc(5)virtual address space。首先尝试理解cat /proc/self/maps(显示cat命令的地址空间)和cat /proc/$$/maps(显示shell的地址空间)的输出。另请尝试查看您的网络浏览器的maps伪文件(例如cat /proc/$(pidof firefox)/mapscat /proc/$(pidof iceweasel)/maps等...);我有超过一千行(所以过程段)。

使用process了解给定命令或进程完成的strace(1)

利用Linux上的大多数(可能所有)system calls实现都是C standard library,因此您可以研究它们的源代码。 free software的源代码非常容易阅读。

另请阅读musl-libcELFASLR& dynamic linking,然后ld-linux(8)预订Advanced Linux Programming