Eli Zaretskii <address@hidden
> schrieb am Mi., 23. Dez. 2015 um 17:10 Uhr:
> Cc: address@hidden, address@hidden, address@hidden,
> address@hidden, address@hidden
> From: Paul Eggert <address@hidden>
> Date: Tue, 22 Dec 2015 15:28:03 -0800
> Is that practical? One problem that I, as a module developer would
> face, is to estimate the amount of stack I'd need for unwinding.
> Where do I begin?
> We could merely require that any module needing recursion must call a new stack-size-checking function at each level of recursion, in order to detect stack overflow.
That's performance penalty. I don't think we should incur that, on
behalf of a problem that really should "never" happen.
It's also impossible. Modules will be written in arbitrary languages and make use of arbitrary libraries, some of which might not even know about Emacs's existence. We cannot impose any constraints on module code.
> Also, any module with an unbounded amount of computation should call the equivalent of QUIT every now and then. If the module API doesn't let (or ideally, require) modules to do that now, it should. Otherwise it's an Emacs freeze waiting to happen.
I agree, but I think it's unrelated to stack overflow. (Though I
think we will need to have a module-specific version of QUIT, as long
as we keep the constraint of not directly longjmping from module
There's no harm in providing such a functionality (but of course we can't enforce its use). Alternatively modules can run computations in background threads and update Emacs state in timer functions.
> Hitting stack overflow when some module runs is even rarer.
> Why is it a disaster to fail to invoke the unwinders in those cases?
> Often I expect it wouldn't be a disaster; it'd just be a memory leak. I suppose there could be some modules where it would be a disaster. But perhaps we can just ask people to not write such modules, by making it a part of the Emacs API that unwinders might not be invoked.
I think if we adopt the view that the user should save and exit ASAP
following recovery from stack overflow (similar to what we expect when
we run out of memory), the probability of a "disaster" in this
scenario becomes much lower, perhaps negligible.
The disaster is that longjmps cause undefined behavior in C++ if destructors would be skipped (and I don't even want to imagine what would happen to higher-level languages such as Java or Haskell). Even if we assume "benign UB" (which is dangerous because UB tends to become more malign as compilers evolve), it will cause internal state to become inconsistent, which is truly disastrous. Resuming operation in such a situation is a non-starter.
All in all, I think the current recovery is "good enough", and
investing significant efforts into making it slightly better will
waste resources that are better applied to more important problems.
handle_sigsegv already has several cases where the longjmp is skipped: when in a GC, when the signal is received from the wrong thread, and when it's not guaranteed to be a SO. In those cases Emacs aborts (still autosaving). Why can't we do the same if SO is detected while a module function is active?