int brk(void *end_data_segment);
void *sbrk(intptr_t increment);
使用增量调用sbrk() 0 可用于查找程序中断的当前位置。
什么是程序中断?从哪里开始,0x00?
答案 0 :(得分:5)
简单化:
进程有几段内存:
(当然,现在它要复杂得多。有一个rodata段,一个未初始化的数据段,通过mmap分配的映射,一个vdso,......)
程序可以在类Unix操作系统中请求更多内存的一种传统方式是增加数据段的大小,并使用内存分配器(即malloc()
实现)来管理结果空间。这是通过brk()
系统调用完成的,该调用会更改数据段“中断”/结束的点。
答案 1 :(得分:3)
程序中断是流程数据段的结束。 AKA ...
程序中断是第一个 结束后的位置 未初始化的数据段
至于它从何处开始,它取决于系统,但可能不是0x00。
答案 2 :(得分:2)
你是说sbrk()是一个绝对的系统调用,我们应该使用malloc(),但是根据她的文档,malloc(),当分配的内存少于128 KiB(32页)时使用它。因此我们不应该直接使用sbrk(),但malloc()会使用它,如果分配大于128 KiB,则malloc()使用mmap()将私有页面分配给用户空间。 最后理解sbrk()是一个好主意,至少是为了理解“程序中断”概念。
答案 3 :(得分:1)
现在,sbrk(2)(和brk
)几乎是过时的系统调用(您几乎可以忘记它们并忽略旧的notion of break;专注于理解mmap(2) )。请注意,sbrk(2) man
页面在其 NOTES 中显示:
避免使用
brk()
和sbrk()
: malloc(3)内存分配包 是分配内存的便携而舒适的方式。
(强调我的)
malloc(3)的大多数实现(尤其是musl-libc中的那个)都使用mmap(2)来从内核中请求内存 - 并增加它们的virtual address space(看看那个virtual address space wikipage,它有一个很好的图片)。有些malloc
- 使用sbrk
进行小额分配,mmap
进行大型分配。
使用strace(1)查找由某个给定进程或命令完成的系统调用(在syscalls(2)中列出)。顺便说一下,您会发现bash
和ls
(可能还有许多其他程序)不会拨打sbrk
。
使用proc(5)探索某个进程的虚拟地址空间。试试cat /proc/$$/maps
和cat /proc/self/maps
甚至是cat /proc/$$/smaps
,然后阅读一下以了解输出。
并且sbrk
不是非常友好的。
(我的回答集中在Linux)