| 614 | } |
| 615 | |
| 616 | static void signal_handler_callback(int sig) { |
| 617 | // Prevent recursion if handler crashes |
| 618 | static volatile sig_atomic_t already_dumping = 0; |
| 619 | if (already_dumping) { |
| 620 | signal(sig, SIG_DFL); |
| 621 | raise(sig); |
| 622 | return; |
| 623 | } |
| 624 | already_dumping = 1; |
| 625 | |
| 626 | auto& self = instance(); |
| 627 | self.begin_crash_dump(); |
| 628 | |
| 629 | printf("\n=== INTERNAL CRASH HANDLER (SIGNAL) ===\n"); |
| 630 | fprintf(stderr, "Error: signal %d:\n", sig); |
| 631 | |
| 632 | switch (sig) { |
| 633 | case SIGABRT: printf("Signal: SIGABRT (Abort)\n"); break; |
| 634 | case SIGFPE: printf("Signal: SIGFPE (Floating Point Exception)\n"); break; |
| 635 | case SIGILL: printf("Signal: SIGILL (Illegal Instruction)\n"); break; |
| 636 | case SIGINT: printf("Signal: SIGINT (Interrupt)\n"); break; |
| 637 | case SIGSEGV: printf("Signal: SIGSEGV (Segmentation Fault)\n"); break; |
| 638 | case SIGTERM: printf("Signal: SIGTERM (Termination)\n"); break; |
| 639 | default: printf("Signal: Unknown (%d)\n", sig); break; |
| 640 | } |
| 641 | |
| 642 | self.print_stacktrace_windows(); |
| 643 | printf("=== END INTERNAL HANDLER ===\n\n"); |
| 644 | |
| 645 | self.end_crash_dump(); |
| 646 | |
| 647 | printf("Uninstalling crash handler and re-raising signal %d for external debugger...\n", sig); |
| 648 | fflush(stdout); |
| 649 | |
| 650 | signal(sig, SIG_DFL); |
| 651 | raise(sig); |
| 652 | exit(1); |
| 653 | } |
| 654 | |
| 655 | // --- Setup --- |
| 656 |
nothing calls this directly
no test coverage detected