Linux 中的堆栈内存管理 [英] Stack memory management in Linux

查看:70
本文介绍了Linux 中的堆栈内存管理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a few questions related to limitations on the stack size for Linux. I'm most interested in x86_64 systems, but if there are platform differences I'd like to understand them as well. My questions are:

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

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

I've written a test program with a recursive function (to use stack space) where I can specify the number of iterations as a command line parameter. The program pauses waiting for user input after finishing the recursion, which allows me to get information about the running process. If I run with a small number of iterations and then use pmap to view the stack size it is 132K.

00007fff0aa3c000    132K rw---   [ stack ]

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

Whereas if I run with a larger number of iterations the size can grow much larger, I believe up to 8192 KB by default. For example here's output from running with more iterations.

00007fff3ed75000   8040K rw---   [ stack ]

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

But if I use strace to trace the system calls when running the application I don't see any associated with growing the stack. So I'm wondering what the kernel is doing to manage the stack space for a process.

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

2) Does Linux protect the stack region in any way when setting ulimit -s unlimited?

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

If I use the command ulimit -s unlimited then I'm able to run many more iterations of my recursive function and the stack grows much larger. For example here's output from pmap

00007ffda43a3000 8031260K rw---   [ stack ]

因为我不想让我的机器崩溃/挂起/锁定,所以我还没有测试过无限递归.但我想知道我是否做了任何会导致内核检测堆栈溢出的事情.或者是 ulimit 是唯一的保护并关闭它允许堆栈无限增长?

Since I don't want to cause my machine to crash/hang/lockup I haven't tested with infinite recursion yet. But I'm wondering if I did is there anything that would cause the kernel to detect stack overflow. Or is ulimit the only protection and turning that off allows the stack to grow unbounded?

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

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

This isn't directly related to anything I've experimented with, but I'm also wondering how Linux manages stack guard pages in conjunction with allowing the stack to grow dynamically.

推荐答案

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

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

The above has been shamelessly over-simplified but still should give the gist.

这篇关于Linux 中的堆栈内存管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆