1
0
Fork 0
forked from fte/fteqw

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:
Spoike 2013-05-04 04:01:47 +00:00
parent 98d4e12ffc
commit 6b41038183

View file

@ -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