static void crash_handler(const char *logfile) { const char *sigdesc = ""; int i; if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1) { fprintf(stderr, "!!! Failed to retrieve info from crashed process\n"); exit(1); } /* Get the signal description */ for(i = 0;signals[i].name;++i) { if(signals[i].signum == crash_info.signum) { sigdesc = signals[i].name; break; } } if(crash_info.has_siginfo) { switch(crash_info.signum) { case SIGSEGV: for(i = 0;sigsegv_codes[i].name;++i) { if(sigsegv_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigsegv_codes[i].name; break; } } break; case SIGFPE: for(i = 0;sigfpe_codes[i].name;++i) { if(sigfpe_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigfpe_codes[i].name; break; } } break; case SIGILL: for(i = 0;sigill_codes[i].name;++i) { if(sigill_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigill_codes[i].name; break; } } break; case SIGBUS: for(i = 0;sigbus_codes[i].name;++i) { if(sigbus_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigbus_codes[i].name; break; } } break; } } fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum); if(crash_info.has_siginfo) fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr); fputc('\n', stderr); if(logfile) { /* Create crash log file and redirect shell output to it */ if(freopen(logfile, "wa", stdout) != stdout) { fprintf(stderr, "!!! Could not create %s following signal\n", logfile); exit(1); } fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid); printf("*** Fatal Error ***\n" "%s (signal %i)\n", sigdesc, crash_info.signum); if(crash_info.has_siginfo) printf("Address: %p\n", crash_info.siginfo.si_addr); fputc('\n', stdout); fflush(stdout); } sys_info(); crash_info.buf[sizeof(crash_info.buf)-1] = '\0'; printf("%s\n", crash_info.buf); fflush(stdout); if(crash_info.pid > 0) { gdb_info(crash_info.pid); kill(crash_info.pid, SIGKILL); } if(logfile) { const char *str; char buf[512]; if((str=getenv("KDE_FULL_SESSION")) && strcmp(str, "true") == 0) snprintf(buf, sizeof(buf), "kdialog --title \"Very Fatal Error\" --textbox \"%s\" 800 600", logfile); else if((str=getenv("GNOME_DESKTOP_SESSION_ID")) && str[0] != '\0') snprintf(buf, sizeof(buf), "gxmessage -buttons \"Okay:0\" -geometry 800x600 -title \"Very Fatal Error\" -center -file \"%s\"", logfile); else snprintf(buf, sizeof(buf), "xmessage -buttons \"Okay:0\" -center -file \"%s\"", logfile); system(buf); } exit(0); }
static void crash_handler(const char *logfile) { const char *sigdesc = ""; int i; if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1) { fprintf(stderr, "!!! Failed to retrieve info from crashed process\n"); exit(1); } /* Get the signal description */ for(i = 0;signals[i].name;++i) { if(signals[i].signum == crash_info.signum) { sigdesc = signals[i].name; break; } } if(crash_info.has_siginfo) { switch(crash_info.signum) { case SIGSEGV: for(i = 0;sigsegv_codes[i].name;++i) { if(sigsegv_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigsegv_codes[i].name; break; } } break; case SIGFPE: for(i = 0;sigfpe_codes[i].name;++i) { if(sigfpe_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigfpe_codes[i].name; break; } } break; case SIGILL: for(i = 0;sigill_codes[i].name;++i) { if(sigill_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigill_codes[i].name; break; } } break; case SIGBUS: for(i = 0;sigbus_codes[i].name;++i) { if(sigbus_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigbus_codes[i].name; break; } } break; } } fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum); if(crash_info.has_siginfo) fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr); fputc('\n', stderr); if(logfile) { // [EP/TP] Needed for the timestamp appending to crash log filename. char newLogfile[64]; time_t timestamp; time( ×tamp ); char *bufferEnd = newLogfile + sizeof( newLogfile ); snprintf( newLogfile, sizeof( newLogfile ), "%s", logfile ); char *appendPoint = strchr( newLogfile, '.' ); if ( appendPoint == NULL ) appendPoint = newLogfile + strlen( newLogfile ); appendPoint += strftime( appendPoint, bufferEnd - appendPoint, "-%m_%d_%Y-%H_%M_%S", localtime( ×tamp ) ); snprintf( appendPoint, bufferEnd - appendPoint, ".%d.log", (int)crash_info.pid ); logfile = (const char *)newLogfile; /* Create crash log file and redirect shell output to it */ if(freopen(logfile, "wa", stdout) != stdout) { fprintf(stderr, "!!! Could not create %s following signal\n", logfile); exit(1); } fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid); printf("*** Fatal Error ***\n" "%s (signal %i)\n", sigdesc, crash_info.signum); if(crash_info.has_siginfo) printf("Address: %p\n", crash_info.siginfo.si_addr); fputc('\n', stdout); fflush(stdout); } sys_info(); crash_info.buf[sizeof(crash_info.buf)-1] = '\0'; printf("%s\n", crash_info.buf); fflush(stdout); if(crash_info.pid > 0) { gdb_info(crash_info.pid); kill(crash_info.pid, SIGKILL); } #ifndef SERVER_ONLY // [BB] The Linux server doesn't have a GUI, so don't bother it with a window. if(logfile) { const char *str; char buf[512]; if((str=getenv("KDE_FULL_SESSION")) && strcmp(str, "true") == 0) snprintf(buf, sizeof(buf), "kdialog --title \"Very Fatal Error\" --textbox \"%s\" 800 600", logfile); else if((str=getenv("GNOME_DESKTOP_SESSION_ID")) && str[0] != '\0') snprintf(buf, sizeof(buf), "gxmessage -buttons \"Okay:0\" -geometry 800x600 -title \"Very Fatal Error\" -center -file \"%s\"", logfile); else snprintf(buf, sizeof(buf), "xmessage -buttons \"Okay:0\" -center -file \"%s\"", logfile); system(buf); } #endif exit(0); }
static void crash_handler(const char *logfile) { const char *sigdesc = "Unknown signal"; const char *codedesc = "unknown code"; int showlog = 0; int i; if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1) { fputs("!!! Failed to retrieve info from crashed process\n", stderr); exit(1); } if(crash_info.version != CRASH_INFO_VERSION) { fputs("!!! Incompatible crash_info structure (library mismatch)\n", stderr); exit(1); } /* Get the signal description */ for(i = 0;signals[i].name;++i) { if(signals[i].signum == crash_info.signum) { sigdesc = signals[i].name; break; } } if(crash_info.has_siginfo) { for(i = 0;generic_codes[i].name;++i) { if(generic_codes[i].code == crash_info.siginfo.si_code) { codedesc = generic_codes[i].name; break; } } if(!generic_codes[i].name) { switch(crash_info.signum) { case SIGSEGV: for(i = 0;sigsegv_codes[i].name;++i) { if(sigsegv_codes[i].code == crash_info.siginfo.si_code) { codedesc = sigsegv_codes[i].name; break; } } break; case SIGFPE: for(i = 0;sigfpe_codes[i].name;++i) { if(sigfpe_codes[i].code == crash_info.siginfo.si_code) { codedesc = sigfpe_codes[i].name; break; } } break; case SIGILL: for(i = 0;sigill_codes[i].name;++i) { if(sigill_codes[i].code == crash_info.siginfo.si_code) { codedesc = sigill_codes[i].name; break; } } break; case SIGBUS: for(i = 0;sigbus_codes[i].name;++i) { if(sigbus_codes[i].code == crash_info.siginfo.si_code) { codedesc = sigbus_codes[i].name; break; } } break; } } fprintf(stderr, "%s, %s (signal %i, code 0x%02x)\n", sigdesc, codedesc, crash_info.signum, crash_info.siginfo.si_code); if(crash_info.signum != SIGABRT) fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr); fputc('\n', stderr); } else fprintf(stderr, "%s (signal %i)\n\n", sigdesc, crash_info.signum); if(logfile && *logfile) { /* Create crash log file and redirect shell output to it */ if(freopen(logfile, "wa", stdout) != stdout) fprintf(stderr, "!!! Could not create %s following signal\n", logfile); else { fprintf(stderr, "Generating %s and killing process %d, please wait...\n", logfile, crash_info.pid); puts("*** Fatal Error ***"); if(!crash_info.has_siginfo) printf("%s (signal %i)\n\n", sigdesc, crash_info.signum); else { printf("%s, %s (signal %i, code 0x%02x)\n", sigdesc, codedesc, crash_info.signum, crash_info.siginfo.si_code); if(crash_info.signum != SIGABRT) printf("Address: %p\n", crash_info.siginfo.si_addr); putchar('\n'); } fflush(stdout); showlog = 1; } } sys_info(); if(crash_info.buf[0] != '\0') { crash_info.buf[sizeof(crash_info.buf)-1] = '\0'; puts(crash_info.buf); fflush(stdout); } if(crash_info.pid > 0) { gdb_info(crash_info.pid); kill(crash_info.pid, SIGKILL); } if(showlog) { const char *str; int ret = 0; if((str=getenv("KDE_FULL_SESSION")) && strcmp(str, "true") == 0) ret = show_kde(&crash_info, sigdesc, logfile); if(!ret) { ret = show_gtk(&crash_info, sigdesc, logfile); if(!ret) ret = show_x11(&crash_info, sigdesc, logfile); } } }
static void crash_handler(const char *logfile) { const char *sigdesc = ""; int i; if(fread(&crash_info, sizeof(crash_info), 1, stdin) != 1) { fprintf(stderr, "!!! Failed to retrieve info from crashed process\n"); exit(1); } /* Get the signal description */ for(i = 0;signals[i].name;++i) { if(signals[i].signum == crash_info.signum) { sigdesc = signals[i].name; break; } } if(crash_info.has_siginfo) { switch(crash_info.signum) { case SIGSEGV: for(i = 0;sigsegv_codes[i].name;++i) { if(sigsegv_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigsegv_codes[i].name; break; } } break; case SIGFPE: for(i = 0;sigfpe_codes[i].name;++i) { if(sigfpe_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigfpe_codes[i].name; break; } } break; case SIGILL: for(i = 0;sigill_codes[i].name;++i) { if(sigill_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigill_codes[i].name; break; } } break; case SIGBUS: for(i = 0;sigbus_codes[i].name;++i) { if(sigbus_codes[i].code == crash_info.siginfo.si_code) { sigdesc = sigbus_codes[i].name; break; } } break; } } fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum); if(crash_info.has_siginfo) fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr); fputc('\n', stderr); if(logfile) { /* Create crash log file and redirect shell output to it */ if(freopen(logfile, "wa", stdout) != stdout) { fprintf(stderr, "!!! Could not create %s following signal\n", logfile); exit(1); } fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid); printf("*** Fatal Error ***\n" "%s (signal %i)\n", sigdesc, crash_info.signum); if(crash_info.has_siginfo) printf("Address: %p\n", crash_info.siginfo.si_addr); fputc('\n', stdout); fflush(stdout); } sys_info(); crash_info.buf[sizeof(crash_info.buf)-1] = '\0'; printf("%s\n", crash_info.buf); fflush(stdout); if(crash_info.pid > 0) { gdb_info(crash_info.pid); kill(crash_info.pid, SIGKILL); } if(logfile) { char cwd[MAXPATHLEN]; getcwd(cwd, MAXPATHLEN); std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '" + std::string(cwd) + "/" + std::string(logfile) + "'.\n Please report this to https://bugs.openmw.org !"; SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), NULL); } exit(0); }