-
-
Notifications
You must be signed in to change notification settings - Fork 420
Gracefully handle assertion errors during runtime startup/teardown #1651
base: master
Are you sure you want to change the base?
Conversation
af3a932
to
c686693
Compare
Fixed the line-number-sensitive test case. |
assert() is used throughout the various bits and pieces involved in druntime startup and teardown. However, the default assert handler (throwing an AssertError) requires the GC and exception handling to be up and running, which is not the case for failures e.g. in the module registry code. Of course, these assertions should never be triggered in shipped versions of druntime. But they might be during development, and this change ensures that a sensible error message is printed instead of hitting an infinite recursion or a GC deadlock.
c686693
to
7da7bd6
Compare
The coverage hit can't really be avoided unless we want to add a special flag to make druntime assert during startup. |
That's why the coverage test is advisory, not definitive! |
There's no reason to |
Can we fix/ban the usage of assert instead of patching the assertHandler for everyone? |
This type of issue doesn't only arise for startup / teardown. I think we should create a policy / checklist regarding use of |
I think calling abort if the GC isn't available is the right approach. Using a statically allocated AssertError could be ok, too, but should probably be thread local. It needs to disable exception chaining omehow, though.
That doesn't work if the assert is in some commonly used function called both at startup and during normal operation.
The asserts inside the GC are also pretty bad, because they get hidden by a different error or corrupt the GC. A couple of issues regardig this PR:
BTW: IMO making errors part of exception handling was not the best decision. An abort function that can be hooked with a (thread local) handler function would work just as well without confusion about non-existing guarantees of stack cleanup. |
Could something along the lines of https://github.com/dlang/druntime/blob/v2.075.0-b4/src/rt/deh.d#L22 and https://github.com/dlang/druntime/blob/v2.075.0-b4/src/core/exception.d#L702 be used to detect if an exception is statically allocated, so that the rest of the runtime would treat it appropriately? |
Using the initializer is just one possibilty, even a pretty bad one, because you have to modify it to store location information and message. That precludes putting the initializer into readonly memory.
staticError is better.
What would be appropriate? Aborting immediately if trying to chain the same exception again? |
Yeah, the exception chaining is a no-go for |
@rainers I meant that we need to do something on top of what |
assert() is used throughout the various bits and pieces involved in
druntime startup and teardown. However, the default assert handler
(throwing an AssertError) requires the GC and exception handling to
be up and running, which is not the case for failures e.g. in the
module registry code.
Of course, these assertions should never be triggered in shipped
versions of druntime. But they might be during development, and
this change ensures that a sensible error message is printed
instead of hitting an infinite recursion or a GC deadlock.
@MartinNowak