/*====================================== * CORE : Signal Sub Function *--------------------------------------*/ static void sig_proc(int sn) { static int is_called = 0; switch (sn) { case SIGINT: case SIGTERM: if (++is_called > 3) exit(EXIT_SUCCESS); if( shutdown_callback != NULL ) shutdown_callback(); else runflag = CORE_ST_STOP;// auto-shutdown break; case SIGSEGV: case SIGFPE: do_abort(); // Pass the signal to the system's default handler compat_signal(sn, SIG_DFL); raise(sn); break; #ifndef _WIN32 case SIGXFSZ: // ignore and allow it to set errno to EFBIG ShowWarning ("Max file size reached!\n"); //run_flag = 0; // should we quit? break; case SIGPIPE: //ShowInfo ("Broken pipe found... closing socket\n"); // set to eof in socket.c break; // does nothing here #endif } }
void signals_init (void) { compat_signal(SIGTERM, sig_proc); compat_signal(SIGINT, sig_proc); #ifndef _DEBUG // need unhandled exceptions to debug on Windows compat_signal(SIGSEGV, sig_proc); compat_signal(SIGFPE, sig_proc); #endif #ifndef _WIN32 compat_signal(SIGILL, SIG_DFL); compat_signal(SIGXFSZ, sig_proc); compat_signal(SIGPIPE, sig_proc); compat_signal(SIGBUS, SIG_DFL); compat_signal(SIGTRAP, SIG_DFL); #endif }
void signals_init (void) { compat_signal(SIGTERM, sig_proc); compat_signal(SIGINT, sig_proc); // Signal to create coredumps by system when necessary (crash) compat_signal(SIGSEGV, SIG_DFL); compat_signal(SIGFPE, SIG_DFL); compat_signal(SIGILL, SIG_DFL); #ifndef _WIN32 compat_signal(SIGXFSZ, sig_proc); compat_signal(SIGPIPE, sig_proc); compat_signal(SIGBUS, SIG_DFL); compat_signal(SIGTRAP, SIG_DFL); #endif }
/*========================================= * Register the signal handlers *----------------------------------------- */ int sig_init () { void (*func)(int) = sig_dump; #ifdef CYGWIN // test if dumper is enabled char *buf = getenv ("CYGWIN"); if (buf && strstr(buf, "error_start") != NULL) func = SIG_DFL; #endif IMPORT_SYMBOL(server_name, 1); IMPORT_SYMBOL(getrevision, 6); IMPORT_SYMBOL(getuptime, 11); compat_signal(SIGSEGV, func); compat_signal(SIGFPE, func); compat_signal(SIGILL, func); compat_signal(SIGBUS, func); return 1; }
static void sig_proc(int) { for (int i = 1; i < 31; ++i) { DIAG_PUSH(); DIAG_I(old_style_cast); compat_signal(i, SIG_IGN); DIAG_POP(); } runflag = false; }
void sig_dump(int sn) { FILE *fp; char file[256]; int no = 0; crash_flag = 1; // search for a usable filename do { sprintf (file, "log/%s%04d.stackdump", server_name, ++no); } while((fp = fopen(file,"r")) && (fclose(fp), no < 9999)); // dump the trace into the file if ((fp = FOPEN_(file, "w", stderr)) != NULL) { const char *revision; #ifndef CYGWIN void* array[20]; char **stack; size_t size; #endif ShowNotice ("Dumping stack to '"CL_WHITE"%s"CL_RESET"'...\n", file); if ((revision = getrevision()) != NULL) fprintf(fp, "Version: svn%s \n", revision); else fprintf(fp, "Version: %2d.%02d.%02d mod%02d \n", ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION, ATHENA_MOD_VERSION); fprintf(fp, "Exception: %s \n", strsignal(sn)); fflush (fp); #ifdef CYGWIN cygwin_stackdump (); #else fprintf(fp, "Stack trace:\n"); size = backtrace (array, 20); stack = backtrace_symbols (array, size); for (no = 0; no < size; no++) { fprintf(fp, "%s\n", stack[no]); } fprintf(fp,"End of stack trace\n"); free(stack); #endif ShowNotice("%s Saved.\n", file); fflush(stdout); fclose(fp); } sig_final(); // Log our uptime // Pass the signal to the system's default handler compat_signal(sn, SIG_DFL); raise(sn); }