Corrupt Unwinding on Errors

Steven Schveighoffer schveiguy at gmail.com
Thu Jan 24 16:52:06 UTC 2019


On 1/22/19 4:48 AM, Eyal Lotem wrote:
> On Tuesday, 22 January 2019 at 09:14:30 UTC, Iain Buclaw wrote:
>> On Tue, 22 Jan 2019 at 09:15, Eyal Lotem via Digitalmars-d 
>> <digitalmars-d at puremagic.com> wrote:
>>
>> Throwing an Error inside a nothrow function is allowed, unlike an 
>> Exception.  As for what happens if that were to ever happen is 
>> undefined, because you're not supposed to recover from it.
> 
> If you're not supposed to recover, then what's the point of corrupt 
> unwinding of the stack?
> 
> It would be much safer to terminate the program right there, allowing a 
> user-installed handler to do its thing before termination.
> 
> Not unwinding is far better than *corrupt* unwinding.

So a couple things here:

1. It's not possible to correctly recover from Errors because of the 
corrupt unwinding, as you say. This is because D compilers take 
advantage of nothrow attribution to avoid building costly unwinding 
handlers in functions. It's in fact unwinding the stack, but the 
compiler *has omitted* the unwinding code that would normally be executed.
2. If you don't unwind, this means that throwing an error isn't exactly 
throwing. It's basically aborting. That is, the advantage of catching 
the error in an outer scope is lost.

I agree with you that corrupt unwinding can cause more problems than no 
unwinding. I think it should be made possible to at least *opt-in* to 
aborting instead of unwinding.

Another possibility is not to unwind the stack, but simply pop the stack 
without executing any unwinding (even proper unwinding code), until you 
get to the handler, which must assume nothing has been unwound in the 
case of an Error. This would be similar to the abort mechanism, but 
gives the control to the appropriate catch statement.

A problem with druntime today is that Throwable is caught in the thread 
startup and main routines. No recovery is attempted, the system is 
aborted, but there's still an attempt to print out the stack trace. See 
here: 
https://github.com/dlang/druntime/blob/master/src/rt/dmain2.d#L480-L484

This assumes some things are still available, e.g. C malloc and stderr, 
when really, an Error could actually mean that they aren't valid to be used.

I'd also like to see an option to have nothrow still generate unwinding 
code, especially in debug/non-release mode.

-Steve


More information about the Digitalmars-d mailing list