RFC: Change what assert does on error

Jonathan M Davis newsgroup.d at jmdavisprog.com
Fri Jul 4 07:21:12 UTC 2025


On Friday, July 4, 2025 12:29:26 AM Mountain Daylight Time Walter Bright via Digitalmars-d wrote:
> On 7/3/2025 12:21 AM, Adam Wilson wrote:
> > It is an absolute non-negotiable business requirement that I be able to get
> > debugging information out of the server without physical access to the device.
> > If you won't deliver the logging data, corrupted or not, on an assert, then no
> > business can justify using D in production.
>
> I did mention that logging the error before terminating the process was
> acceptable. My point is that recovering is not acceptable.

Even if recovering is not acceptable, if the proper clean up is done when
the stack is unwound, then it's possible to use destructors, scope
statements, and catch blocks to get additional information about the state
of the program as the stack unwinds. If the proper clean up is not done as
the stack unwinds, then those destructors, scope statements, and catch
statements will either not be run (meaning that any debugging information
which could have been obtained from them wouldn't be), and/or only some of
them will be run. And of course, for each such piece of clean up code that's
skipped, the more invalid the state of the program becomes, making it that
much riskier for any of the code that does run while the stack unwinds to
log any information about the state of the program.

And since in many cases, the fact that an Error was thrown means that memory
corruption was about to occur rather than it actually having occurred, the
state of the program could actually be perfectly memory safe while the stack
unwinds if all of the clean up code is run correctly. It would be buggy,
obviously, because the fact that an Error was thrown means that there's a
bug, but it could still be very much memory safe. However, if that clean up
code is skipped, then the logic of the program is further screwed up (since
code that's normally guaranteed to run is not run), and that runs the risk
of making it so that the code that does run during shutdown is then no
longer memory safe, since the ability of the language to guarantee memory
safety at least partially relies on the code actually following the normal
rules of the language (which would include running destructors, scope
statements, and catch statements).

It's quite possible to simultaneously say that it's bad practice to attempt
to recover from an Error and to make it so that all of the normal clean up
code runs while the stack unwinds with an Error. Wanting to recover from an
Error and to continue to run the program is not the only reason to want the
stack to unwind correctly. It can also be critical for getting accurate
information while the program is shutting down due to an Error (especially
in programs where the programmer is not the one running the program and
isn't going to be able to reproduce the problem without additional
information). And honestly, if the clean up code isn't going to be run
properly, what was even the point of making Error a Throwable instead of
just printing something out and terminating the program at the source of the
Error?

Having the stack unwind properly in the face of Errors gives us a valuable
debugging tool. It does not mean that we're endorsing folks attempting to
recover from Errors  - and some folks do that already simply because Error
is a Throwable, and it's completely possible to attempt it whether it's a
good idea or not. If you hadn't wanted that to be possible, you shouldn't
have ever made Error a Throwable. But the fact that it is a Throwable makes
it possible to get better information out of a program that's being killed
by an Error - especially if the stack unwinds properly in the process.
So, fixing the stack unwinding to work properly with Errors won't change the
fact that some folks will try to recover from Errors, but it will make it
easier to get information about the program's state when an Error occurs and
therefore make it easier to fix such bugs.

At the end of the day, whether the programmer does the right thing with
Errors is up to the programmer, and we have the opportunity here to make it
work better for folks who _are_ trying to do the right thing and have the
program shut down on such failures. They just want to be able to get better
information during the shutdown without faulty stack unwinding potentially
introducing memory safety issues in the process.

If a programmer is determined to shoot themselves in the foot by trying to
recover from an Error, they're going to do that whether we like it or not.

- Jonathan M Davis






More information about the Digitalmars-d mailing list