gpt4 book ai didi

linux - Linux 中的堆栈内存管理

转载 作者:太空狗 更新时间:2023-10-29 12:29:41 25 4
gpt4 key购买 nike

我有几个关于 Linux 堆栈大小限制的问题。我对 x86_64 系统最感兴趣,但如果存在平台差异,我也想了解它们。我的问题是:

1)Linux如何动态增加栈的大小?

我编写了一个带有递归函数(使用堆栈空间)的测试程序,我可以在其中将迭代次数指定为命令行参数。程序在完成递归后暂停等待用户输入,这使我可以获取有关正在运行的进程的信息。如果我运行少量迭代,然后使用 pmap 查看堆栈大小,它是 132K。

00007fff0aa3c000    132K rw---   [ stack ]

然而,如果我运行更多的迭代,大小会变得更大,我相信默认情况下可达 8192 KB。例如,这是运行更多迭代的输出。

00007fff3ed75000   8040K rw---   [ stack ]

但是如果我在运行应用程序时使用 strace 来跟踪系统调用,我看不到任何与堆栈增长相关的信息。所以我想知道内核正在做什么来管理进程的堆栈空间。

2) 在设置 ulimit -s unlimited 时,Linux 是否以任何方式保护堆栈区域?

如果我使用命令 ulimit -s unlimited,那么我可以运行递归函数的更多迭代,并且堆栈会变得更大。例如,这里是 pmap 的输出

00007ffda43a3000 8031260K rw---   [ stack ]

因为我不想让我的机器崩溃/挂起/锁定,所以我还没有用无限递归进行测试。但是我想知道我是否做了什么会导致内核检测到堆栈溢出。还是 ulimit 是唯一的保护措施,关闭它可以让堆栈无限增长?

3) 如何处理堆栈保护页面?

这与我试验过的任何事情都没有直接关系,但我也想知道 Linux 如何管理堆栈保护页并允许堆栈动态增长。

最佳答案

  1. 对于每个正在运行的进程,Linux 都会保留一个虚拟内存地址区域列表。如果地址引用产生页面错误,Linux 会检查该列表以查看虚拟地址是否合法(在其中一个区域的范围内)。如果区域未声明,应用程序会收到 SIGSEGV 错误,否则内核会分配另一页系统内存并添加到翻译缓存中。如果故障地址只是错过了一个区域,并且该区域用于堆栈(根据机器架构向上或向下增长),那么 Linux 会分配另一个 VM 页面,将其映射到该区域,从而增加堆栈。
  2. 内核不保护堆栈。如果堆栈访问由于物理 VM 页面未附加到进程的内存区域而导致页面错误,则会测试进程的 rlimit 以查看是否允许添加另一个页面。
  3. 一些 malloc(3) 调试器库正在使用堆栈保护页面。这些是将每个内存请求扩展 2 个 VM 页面:新页面之前的一页,新页面之后的一页。额外的页面被标记为完全不可访问,因此如果应用程序离开区域的末尾,或者移动到开始之前,应用程序就会发生访问冲突。

上面的内容已经无耻地过度简化了,但仍然应该给出要点。

关于linux - Linux 中的堆栈内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31328349/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com