[OT] OT: Null checks.
Walter Bright
newshound2 at digitalmars.com
Tue May 6 00:04:58 UTC 2025
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.
>> 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":
```C
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ucontext.h>
void segfault_handler(int sig, siginfo_t *info, void *context) {
// Check if the fault was due to a null pointer access
if (info->si_addr == NULL) {
fprintf(stderr, "Caught segmentation fault: Null pointer access at
RIP=%p\n",
(void*)((ucontext_t*)context)->uc_mcontext.gregs[REG_RIP]);
} else {
fprintf(stderr, "Caught segmentation fault at address %p\n",
info->si_addr);
}
// Print basic stack trace (simplified)
void *buffer[10];
int nptrs = backtrace(buffer, 10);
char **strings = backtrace_symbols(buffer, nptrs);
if (strings) {
fprintf(stderr, "Stack trace:\n");
for (int i = 0; i < nptrs; i++) {
fprintf(stderr, "%s\n", strings[i]);
}
free(strings);
}
// Exit the program
exit(EXIT_FAILURE);
}
int setup_segfault_handler(void) {
struct sigaction sa;
// Clear the structure
memset(&sa, 0, sizeof(struct sigaction));
// Set handler
sa.sa_sigaction = segfault_handler;
sa.sa_flags = SA_SIGINFO; // Use sa_sigaction instead of sa_handler
// Register handler for SIGSEGV
if (sigaction(SIGSEGV, &sa, NULL) == -1) {
perror("Failed to set up SIGSEGV handler");
return -1;
}
return 0;
}
// Example usage
int main(void) {
if (setup_segfault_handler() != 0) {
return EXIT_FAILURE;
}
// Trigger a null pointer dereference
int *ptr = NULL;
*ptr = 42; // This will cause a segfault
return 0;
}
```
>> 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.
```
More information about the Digitalmars-d
mailing list