4 ms·
The fact that two major attempts to do split/segmented stacks, Go and Rust, both ended up abandoning that approach to me indicates that there are fairly big pro
by zokier 3y ago
The fact that two major attempts to do split/segmented stacks, Go and Rust, both ended up abandoning that approach to me indicates that there are fairly big problems trying to go beyond traditional stack model. Without even acknowledging the difficulty, nevermind proposing solutions, the blog post reads very much like "I want a pony"
- quotemstr 3y agoOr the blog author wants something that isn't Unix. Part of the problem is that dealing with stack overflow on your typical POSIX system is practically impossible: the compilers don't do stack probing consistently, and even if they did, it'd be difficult to do anything in response to failed probes because the design of the signal handler installation mechanisms makes it hard for components within a process to share an exception like SIGSEGV. It's one of those situations in which nobody uses the feature because it's broken, and it stays broken because nobody uses the feature. Sad. I've been trying to get this fixed for years: https://sourceware.org/legacy-ml/libc-alpha/2018-03/msg00214.html https://sourceware.org/legacy-ml/libc-alpha/2018-03/msg00214... Windows has recover from stack overflow just fine with SEH. If we limited the maximum per frame stack size and probed properly, we could do split stacks no problem. We just choose not to solve this problem, like we've chosen not to solve many other problems in Unix, and things are in practice going to stay broken until the heat death of the universe or AGI just writes a PaperclipOS for itself.
- mananaysiempre 3y ago> If we limited the maximum per frame stack size and probed properly, we could do split stacks no problem. IIRC the initial Go implementation of split stacks also worked no problem (the benefits of owning the compiler and the ABI), and the reason it was ultimately abandoned was that it got very slow when you happened to repeatedly call a function when you had too little stack space left in the current segment (because you can’t grow the current segment, because you can’t move stack segments, because they may have pointers into them). If that is the problem, replacing a check in the function prologue with a page fault hitting the guard page looks unlikely to make this particular slow case faster.
- throwaway894345 3y agoGo doesn’t have traditional stacks; it has growable stacks and they work out very well in practice. But yeah they aren’t segmented to my knowledge.
- addaon 3y agoGo has auto-copied stacks [1]. This replaces a deterministic, statically-analyzable problem ("how much stack space does this need, worst case?") with unboundedly bad performance. Yay? [1] https://blog.cloudflare.com/how-stacks-are-handled-in-go/ https://blog.cloudflare.com/how-stacks-are-handled-in-go/
- znkr 3y agoOnly, it’s not statically analyzable. Rice’s theorem still holds afaik
- addaon 3y agoIt's not statically analyzable for arbitrary programs. Don't write arbitrary programs -- design for analysis, just like you design for test.
- znkr 3y agoWhile that’s possible, it would put severe limitations on what you can do. For example, it would be very difficult to parse nested input data and I don’t see how dynamic function Dispatch would be possible at all. I am not convinced that the benefits would outweigh the costs.
- addaon 3y agoThis is standard practice for embedded and high-reliability systems.
- throwaway894345 3y ago
- kayo_20211030 3y agoReading this, I did think "I want a pony". And also, "if my grandmother had wheels, she'd be a bicycle". The world we have is the world we've been given and stacks are a scarce resource simply because they actually run out. Wishing otherwise doesn't change anything.