[OT] OT: Null checks.
Timon Gehr
timon.gehr at gmx.ch
Tue May 6 03:05:30 UTC 2025
On 5/6/25 02:04, Walter Bright wrote:
> On 5/4/2025 1:06 PM, Timon Gehr wrote:
>> My understanding is all of those features are under constant threat of
>> being broken for "Error" and not guaranteed to work in the first place.
>
> We learned our lesson to not break existing code. For example, we
> deprecated use of complex numbers maybe 15 years ago, and yet there's
> still active code using them. This is annoying to me because it makes
> doing the AArch64 code generator significantly harder.
> ...
Well, personally I am mostly upset about this deprecation because
`creal` was my favorite D keyword. 😋
Also I had actually bought the justification for why they were built-in.
>
>>> Worst case, you can write a signal handler for any of the signals
>>> that can be generated (not just null pointer signals), and have the
>>> handler write all it can to a file that can be emailed to you.
>
> I asked grok "write a signal handler for linux that catches a null
> pointer seg fault":
> ...
Sure, it's not rocket science. Anyway, if you recall, the mysterious
crash was on _Windows_, on a machine I do not control. I am sure I will
be able to get out stack traces on segfault there too using SEH and by
perhaps shipping debug info.
I can solve or work around problems. However, I think it is better to
eliminate said problems at the source, for everyone.
The point is:
- by default you just get nothing. even if druntime prints a stack trace
(which it might do on windows, I am not a windows user myself, so have
not seen that), I suspect it just deletes the console window immediately
anyway.
- you have to do some manual steps, which you most likely only do once
you actually face an irreproducible issue
- you have to wait for the next report, which may be months later (and
next report is not the same as the next time it happens, as I don't like
putting telemetry in my software)
- running the scope guards as advertised fixes the issue, e.g. on
Windows I wrapped the main function in:
```d
try ...
catch(Throwable e){
writeln(e.toString());
system("pause");
return 1;
}
```
This way my users can actually see the stack trace in cases where it is
actually printed. And even before that, _other scope guards will have
gathered useful information related to the crash beyond just a call
stack trace_.
- cases where destructors/scope guards used to run are actively being
broken so that scope guards no longer run. Branches are actively being
coded into druntime to result in invalid instruction errors even if the
programmer does not compile with a flag that means they want this. This
has to stop, it's terrible UX.
>>> You can also hook atexit() as maybe your program is exiting that way.
>>
>> Well, yes. As I said, I can probably figure it out at some point. It's
>> just a lot more work than necessary in some other languages for
>> comparable situations.
>
> https://man7.org/linux/man-pages/man3/atexit.3.html
>
> ```
> #include <stdlib.h>
>
> int atexit(typeof(void (void)) *function);
>
> DESCRIPTION
>
> The atexit() function registers the given function to be called at
> normal process termination, either via exit(3) or via return from
> the program's main(). Functions so registered are called in the
> reverse order of their registration; no arguments are passed.
> ```
Sure. I guess I could try to put the `system("pause")` call into this
instead, then at least stderr will be visible to users somewhat more
often, even in cases where scope guards are skipped entirely.
The entire point though is that I do not want destructors and scope
guards to be skipped. x) None of your proposed workarounds so far fix this.
The additional work I am referring to is mostly _fixing the issue with
only bare-bones information_ and _waiting for the next report_. I care
less about _getting the program to spit out more than zero information
on crash_. It seems you misunderstood me. Adding signal handlers is a
nuisance, but this is not what causes the bulk of additional work. I do
consider it a waste of time in its own right, though.
Of course, there will always be situations where destructors/scope
guards don't run, e.g., if there is a hardware or power failure, but
there can at least be a best effort to run them instead of actively
working to suppress them. It will be sufficient in almost all cases.
Unless you are saying actually running the destructors and scope guards
is similarly easy, I have not dug this deep into druntime so far. Then
it should maybe be officially supported at least in an opt-in fashion.
Also I suspect grok would be of limited utility for making this work, if
doing so in a signal handler is even workable.
I understand that in cases where there is memory corruption you may not
actually want to run them, but I feel D in standard usage is memory safe
enough for me to make the call that running them always if possible at
all will be overall vastly more helpful than running them unreliably.
More information about the Digitalmars-d
mailing list