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

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

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

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

5个回答

10
简单来说:
一个进程有几个内存段:
- 代码(文本)段,包含要执行的代码。 - 数据段,包含编译器知道的数据(全局变量和静态变量)。 - 栈段,包含(鼓声……)栈。
(当然,现在它更加复杂。还有一个rodata段、一个未初始化的数据段、通过mmap分配的映射、一个vdso等等。)
Unix-like操作系统中程序请求更多内存的传统方法之一是增加数据段的大小,并使用内存分配器(即malloc()实现)来管理结果空间。这是通过brk()系统调用完成的,它改变了数据段“断裂”/结束的点。

5
程序中断是进程数据段的结束。又称为...
程序中断是未初始化数据段结束后的第一个位置。
至于它从哪里开始,这取决于系统,但可能不是0x00。

2
@cpuer:由操作系统决定的位置。 - Andrew White
我们应该使用统一的术语以避免误解。data段用于初始化全局和静态变量。程序断点是堆段的结束。 - Chris Bao

3
这些天,sbrk(2)(和brk)几乎已经过时了(你可以几乎忘记它们并忽略旧的断点概念;专注于理解mmap(2))。请注意sbrk(2) man页面在其NOTES部分中说:

避免使用brk()sbrk()malloc(3)内存分配包是分配内存的便捷可移植方法。

(强调我的)


大多数 malloc(3) 的实现(特别是在 musl-libc 中)通常使用 mmap(2) 从内核中请求内存并增加其 虚拟地址空间(查看该 虚拟地址空间 维基页面,它有一张漂亮的图片)。一些 malloc 使用 sbrk 进行小分配,mmap 进行大分配。
使用strace(1)命令来查找某个进程或命令所调用的系统调用(列在syscalls(2)中)。顺便提一下,你会发现bashls(以及可能许多其他程序)不会对sbrk进行任何调用。
通过使用proc(5)探索某个进程的虚拟地址空间。尝试运行cat /proc/$$/mapscat /proc/self/maps,甚至是cat /proc/$$/smaps,并阅读一些内容以理解输出结果。
要注意ASLRvdso(7)
“而且,sbrk 不是非常适合多线程。”
“(我的回答重点在于 Linux 系统)”

2
基于以下广泛使用的图表: enter image description here 程序断点,在许多文章中也称为brk,指向堆段末尾的地址。
当你调用malloc时,它会更改程序断点的地址。

1
您说sbrk()是一个过时的系统调用,我们应该使用malloc(),但是根据她的文档,在分配少于128 KiB(32页)的内存时,malloc()会使用它。因此,我们不应直接使用sbrk(),而是让malloc()使用它。如果分配大于128 KiB的内存,则malloc()使用mmap()来为用户空间分配私有页面。最后,了解sbrk()至少对理解“程序断点”的概念是个好主意。

这完全取决于系统和实现。有各种不同的malloc实现。 - Vladimir F Героям слава
这实际上是对Basile Starynkevitch的回答的评论吗? - Vladimir F Героям слава

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接