8
int brk(void *end_data_segment);
void *sbrk(intptr_t increment);

以 0 为增量调用 sbrk() 可用于查找程序中断的当前位置。

什么是程序中断?它从哪里开始,0x00?

4

4 回答 4

7

过度简化:

一个进程有几个内存段:

  • 代码(文本)段,其中包含要执行的代码。
  • 数据段,其中包含编译器知道的数据(全局和静态)。
  • 堆栈段,其中包含(drumroll...)堆栈。

(当然,现在它要复杂得多。有一个rodata段,一个未初始化的数据段,通过mmap分配的映射,一个vdso,......)

程序在类 Unix 操作系统中请求更多内存的一种传统方式是增加数据段的大小,并使用内存分配器(即malloc()实现)来管理结果空间。这是通过brk()系统调用完成的,它改变了数据段“中断”/结束的点。

于 2011-06-14T22:54:54.273 回答
5

程序中断是进程数据段的结束。又名...

程序中断是未初始化数据段结束后的第一个位置

至于它从哪里开始,它取决于系统,但可能不是 0x00。

于 2011-06-14T01:33:57.683 回答
2

您是说 sbrk() 是一个过时的系统调用,我们应该使用 malloc(),但是根据她的文档,当分配的内存少于 128 KiB(32 页)时,malloc() 会使用它。所以我们不应该直接使用 sbrk(),而是 malloc() 使用它,如果分配大于 128 KiB,那么 malloc() 使用 mmap() 将私有页面分配给用户空间。最后,了解 sbrk() 是一个好主意,至少对于了解“程序中断”概念而言。

于 2017-11-02T20:16:31.423 回答
1

如今,sbrk(2) (and brk) 几乎是过时的系统调用(您几乎可以忘记它们并忽略break 的旧概念;专注于理解mmap(2))。请注意,sbrk(2) man页面在其NOTES中说:

避免使用brk()and sbrk()malloc(3)内存分配包是一种可移植且舒适的内存分配方式。

(强调我的)


malloc(3)的大多数实现(尤其是musl-libc中的那个)宁愿使用mmap(2)来从内核请求内存 - 并增加它们的虚拟地址空间(看看那个 虚拟地址空间维基页面,它有一个很好的图片)。一些malloc-ssbrk用于小分配,mmap用于大分配。

使用strace(1)找出某个给定进程或命令完成的系统调用(在syscalls(2)中列出)。顺便说一句,您会发现bash并且ls(可能还有许多其他程序)不会对sbrk.

使用proc(5)探索某个进程的虚拟地址空间。尝试cat /proc/$$/maps并阅读一下cat /proc/self/mapscat /proc/$$/smaps了解输出。

请注意ASLRvdso(7)

并且sbrk不是很友好的线程。

(我的回答集中在 Linux 上)

于 2017-10-09T17:53:00.487 回答