[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