Be a bit more precise with backtrace prints. Don't include the signal handler, and make sure the faulting frame is not corrupted by the handler on x86.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4326 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
98d4e12ffc
commit
6b41038183
1 changed files with 39 additions and 13 deletions
|
@ -645,34 +645,57 @@ void Sys_Shutdown (void)
|
||||||
|
|
||||||
#ifdef __linux__ /*should probably be GNUC but whatever*/
|
#ifdef __linux__ /*should probably be GNUC but whatever*/
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
static void Friendly_Crash_Handler(int sig)
|
#ifdef __i386__
|
||||||
|
#define __USE_GNU
|
||||||
|
#include <ucontext.h>
|
||||||
|
#endif
|
||||||
|
static void Friendly_Crash_Handler(int sig, siginfo_t *info, void *vcontext)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
void *array[10];
|
void *array[10];
|
||||||
size_t size;
|
size_t size;
|
||||||
|
int firstframe = 0;
|
||||||
|
char signame[32];
|
||||||
|
|
||||||
|
switch(sig)
|
||||||
|
{
|
||||||
|
case SIGILL: strcpy(signame, "SIGILL"); break;
|
||||||
|
case SIGFPE: strcpy(signame, "SIGFPE"); break;
|
||||||
|
case SIGBUS: strcpy(signame, "SIGBUS"); break;
|
||||||
|
case SIGSEGV: Q_snprintfz(signame, sizeof(signame), "SIGSEGV (%p)", info->si_addr); break;
|
||||||
|
default: Q_snprintfz(signame, sizeof(signame), "%i", sig); break;
|
||||||
|
}
|
||||||
|
|
||||||
// get void*'s for all entries on the stack
|
// get void*'s for all entries on the stack
|
||||||
size = backtrace(array, 10);
|
size = backtrace(array, 10);
|
||||||
|
|
||||||
|
#if defined(__i386__)
|
||||||
|
ucontext_t *uc = vcontext;
|
||||||
|
array[1] = uc->uc_mcontext.gregs[REG_EIP];
|
||||||
|
firstframe = 1;
|
||||||
|
#elif defined(__amd64__)
|
||||||
|
firstframe = 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
// print out all the frames to stderr
|
// print out all the frames to stderr
|
||||||
fprintf(stderr, "Error: signal %d:\n", sig);
|
fprintf(stderr, "Error: signal %s:\n", signame);
|
||||||
backtrace_symbols_fd(array, size, 2);
|
backtrace_symbols_fd(array+firstframe, size-firstframe, 2);
|
||||||
|
|
||||||
fd = open("crash.log", O_WRONLY|O_CREAT|O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
|
fd = open("crash.log", O_WRONLY|O_CREAT|O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP);
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
time_t rawtime;
|
time_t rawtime;
|
||||||
struct tm * timeinfo;
|
struct tm * timeinfo;
|
||||||
char tbuffer [80];
|
char buffer [80];
|
||||||
|
|
||||||
time (&rawtime);
|
time (&rawtime);
|
||||||
timeinfo = localtime (&rawtime);
|
timeinfo = localtime (&rawtime);
|
||||||
strftime (buffer, sizeof(buffer), "Time: %Y-%m-%d %H:%M:%S\n",timeinfo);
|
strftime (buffer, sizeof(buffer), "Time: %Y-%m-%d %H:%M:%S\n",timeinfo);
|
||||||
write(fd, buffer, strlen(buffer));
|
write(fd, buffer, strlen(buffer));
|
||||||
|
|
||||||
Q_snprintf(buffer, sizeof(buffer), "Binary: "__DATE__" "__TIME__"\n");
|
Q_snprintfz(buffer, sizeof(buffer), "Binary: "__DATE__" "__TIME__"\n");
|
||||||
write(fd, buffer, strlen(buffer));
|
write(fd, buffer, strlen(buffer));
|
||||||
Q_snprintf(buffer, sizeof(buffer), "Ver: %i.%02i%s\n", FTE_VER_MAJOR, FTE_VER_MINOR
|
Q_snprintfz(buffer, sizeof(buffer), "Ver: %i.%02i%s\n", FTE_VER_MAJOR, FTE_VER_MINOR,
|
||||||
#ifdef OFFICIAL_RELEASE
|
#ifdef OFFICIAL_RELEASE
|
||||||
" (official)");
|
" (official)");
|
||||||
#else
|
#else
|
||||||
|
@ -682,13 +705,12 @@ static void Friendly_Crash_Handler(int sig)
|
||||||
#ifdef SVNREVISION
|
#ifdef SVNREVISION
|
||||||
if (strcmp(STRINGIFY(SVNREVISION), "-"))
|
if (strcmp(STRINGIFY(SVNREVISION), "-"))
|
||||||
{
|
{
|
||||||
Q_snprintf(buffer, sizeof(buffer), "Revision: %s\n", SVNREVISION);
|
Q_snprintfz(buffer, sizeof(buffer), "Revision: %s\n", STRINGIFY(SVNREVISION));
|
||||||
write(fd, buffer, strlen(buffer));
|
write(fd, buffer, strlen(buffer));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size = backtrace(array, 10);
|
backtrace_symbols_fd(array + firstframe, size - firstframe, fd);
|
||||||
backtrace_symbols_fd(array, size, fd);
|
|
||||||
write(fd, "\n", 1);
|
write(fd, "\n", 1);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
@ -723,10 +745,14 @@ int main(int argc, char *argv[])
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if (!COM_CheckParm("-nodumpstack"))
|
if (!COM_CheckParm("-nodumpstack"))
|
||||||
{
|
{
|
||||||
signal(SIGILL, Friendly_Crash_Handler);
|
struct sigaction act;
|
||||||
signal(SIGFPE, Friendly_Crash_Handler);
|
memset(&act, 0, sizeof(act));
|
||||||
signal(SIGSEGV, Friendly_Crash_Handler);
|
act.sa_sigaction = Friendly_Crash_Handler;
|
||||||
signal(SIGBUS, Friendly_Crash_Handler);
|
act.sa_flags = SA_SIGINFO | SA_RESTART;
|
||||||
|
sigaction(SIGILL, &act, NULL);
|
||||||
|
sigaction(SIGFPE, &act, NULL);
|
||||||
|
sigaction(SIGSEGV, &act, NULL);
|
||||||
|
sigaction(SIGBUS, &act, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue