예제 #1
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)
	{
		/* 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);
}
예제 #2
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( &timestamp );
		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( &timestamp ) );

		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);
}
예제 #3
0
파일: main.c 프로젝트: scrawl/crash-catcher
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);
        }
    }
}
예제 #4
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)
    {
        /* 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);
}