Will the stack of a C program ever shrink?

為{幸葍}努か 提交于 2019-12-20 01:35:20

问题


I've noticed that every running C program has a private mapping called [stack] that is initially quite small (128k on my machine), but will grow to accomodate any automatic variables (up to the stack size limit). I assume this is where the call stack of my program is located.

However, it doesn't seem to ever shrink back to its original size. Is there any way to free up that memory without terminating the process?

How is the C stack implemented internally; what increases the size of the [stack] mapping on demand? Some compiler generated code, the C library or the operating system? Where is the increase triggered?

Update: I'm using Linux 3.0.0, gcc 4.6.1 and glibc6 on x86-64; as this is probably pretty implementation specific, any information on how it works there would be fine.


回答1:


In Linux/MMU (in !MMU you cannot grow the stack), the stack is grown in the page fault handler. For x86, whether to grow the stack is decided by the following code from arch/x86/mm/fault.c:do_page_fault():

        if (error_code & PF_USER) {
            /*
             * Accessing the stack below %sp is always a bug.
             * The large cushion allows instructions like enter
             * and pusha to work. ("enter $65535, $31" pushes
             * 32 pointers and then decrements %sp by 65535.)
             */
            if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) {
                    bad_area(regs, error_code, address);
                    return;
            }
    }
    if (unlikely(expand_stack(vma, address))) {
            bad_area(regs, error_code, address);
            return;
    }

expand_stack() checks the usual RLIMITS (RLIMIT_AS, RLIMIT_STACK, RLIMIT_MEMLOCK), whether LSMs will allow to grow the stack, whether there's too much overcommit, etc..., and finally grows the stack.




回答2:


It's implementation specific, but I know of no commonly used platform which shrinks committed stack memory. It is common for stacks to grow on demand but once space is committed it stays committed.




回答3:


I believe that the Linux kernel is growing the stack segment (only for the main thread). It is not in the compiler (except by incrementing the stack pointer at calls, and ignoring the experimental -fsplit-stack option of recent GCC), and not in the libC.

If you are sure your stack has grown too big, and you won't need it, you might perhaps munmap the unused part (but be careful; kernel developers don't think of this so it might not work as expected; in the early 1990-s I remembered having crashed SunOS5.0 on Sparc with such dirty tricks).

And on Linux, x86-64, with a decent machine, you really should not care. The stack is not that big...

My guess is that the stack segment is mmap-ed with MAP_NORESERVE MAP_STACK MAP_GROWSDOWN but I may be wrong.



来源:https://stackoverflow.com/questions/8203110/will-the-stack-of-a-c-program-ever-shrink

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!