4 ms·
This doesn't work in practice, see my above comment. You can't put guard pages into the middle of stack segment (using mprotect()--the kernel will just override
by titzer 5y ago
This doesn't work in practice, see my above comment. You can't put guard pages into the middle of stack segment (using mprotect()--the kernel will just override that mapping, happily growing right over top of it). Even putting a guard page at the end doesn't work, as you can still have spurious SIGSEGVs, as you mention, because programs might just stride more than 4KiB at a time; you can't trust a C compiler to insert strided accesses for you, and that's just overhead.
The only way you can reliably do this, I've found, is to allocate your own stack segment.
- cryptonector 5y agoOf course you can have a SIGSEGV when you exceed the max stack size. That's fine and to be expected. What's NOT fine is for a large stack allocation to cause the program to silently scribble over another stack or heap.
- masklinn 5y ago> Of course you can have a SIGSEGV when you exceed the max stack size. That's fine and to be expected. It's more that you can't expect anything better, having an actual stack overflow error would be a lot more helpful.
- cryptonector 5y agoRight. With 64-bit ISAs you can address 2^64 bytes, but... you can't exactly have 2^64 bytes. At some point the system will fail. How it fails is important. A ran-out-of-resources errors is a lot better than undefined behavior resulting from random memory corruption. And yes, portable C has finite size_t. Therefore portable C must fail in some way when limits are exceeded.
- gpderetta 5y agoHave you considered --split-stack? It provides infinitely growable stacks (up to the heap limit I guess) and a defined ABI to find the stack boundaries. The cost is slower function calls and an ABI break.