POSIX signal handler now outputs a plaintext file.
It uses strlen(), which is not required to be signal safe, but I can't imagine it to be not reentrant and suffering from heap/stack corruption... It uses strsignal(), which is a GNU extension. strsignal is implemented using the signum as an index into an array of signal descriptions, which should be easily cloneable for non GNU systems if needed. git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@1190 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
8cdad4a810
commit
bc50d5185d
|
@ -20,7 +20,7 @@
|
|||
#include "frame.h"
|
||||
|
||||
|
||||
static char * programCommand = NULL, * programVersion = NULL, * compileDate = NULL;
|
||||
static char * programCommand = NULL;
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -92,25 +92,17 @@ static LONG WINAPI windowsExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
|
|||
#include <sys/utsname.h>
|
||||
|
||||
|
||||
#define MAX_BACKTRACE 20
|
||||
|
||||
|
||||
typedef void(*SigHandler)(int);
|
||||
|
||||
|
||||
static SigHandler oldHandler[NSIG] = {SIG_DFL};
|
||||
|
||||
static struct utsname sysInfo;
|
||||
static uint32_t sysInfoValid = 0, programCommandSize = 0, programVersionSize = 0, compileDateSize = 0;
|
||||
|
||||
static const uint32_t gdmpVersion = 1;
|
||||
static const uint32_t sizeOfVoidP = sizeof(void*), sizeOfUtsname = sizeof(struct utsname), sizeOfChar = sizeof(char);
|
||||
|
||||
|
||||
static void setErrorHandler(SigHandler signalHandler)
|
||||
{
|
||||
sysInfoValid = (uname(&sysInfo) == 0);
|
||||
programCommandSize = strlen(programCommand);
|
||||
programVersionSize = strlen(programVersion);
|
||||
compileDateSize = strlen(compileDate);
|
||||
|
||||
// Save previous signal handler, eg. SDL parachute
|
||||
oldHandler[SIGFPE] = signal(SIGFPE, signalHandler);
|
||||
if ( oldHandler[SIGFPE] == SIG_IGN )
|
||||
|
@ -146,9 +138,10 @@ static void errorHandler(int sig)
|
|||
raise(sig);
|
||||
allreadyRunning = 1;
|
||||
|
||||
void * btBuffer[128];
|
||||
struct utsname sysInfo;
|
||||
void * btBuffer[MAX_BACKTRACE] = {NULL};
|
||||
char * gDumpPath = "/tmp/warzone2100.gdmp";
|
||||
uint32_t btSize = backtrace(btBuffer, 128), signum = sig;
|
||||
uint32_t btSize = backtrace(btBuffer, MAX_BACKTRACE);
|
||||
|
||||
int dumpFile = open(gDumpPath, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
|
||||
|
||||
|
@ -158,28 +151,53 @@ static void errorHandler(int sig)
|
|||
return;
|
||||
}
|
||||
|
||||
write(dumpFile, &gdmpVersion, sizeof(uint32_t));
|
||||
|
||||
write(dumpFile, &sizeOfChar, sizeof(uint32_t));
|
||||
write(dumpFile, &sizeOfVoidP, sizeof(uint32_t));
|
||||
write(dumpFile, &sizeOfUtsname, sizeof(uint32_t));
|
||||
write(dumpFile, "Program command: ", strlen("Program command: "));
|
||||
write(dumpFile, programCommand, sizeof(char)*strlen(programCommand));
|
||||
write(dumpFile, "\n", sizeof(char));
|
||||
|
||||
write(dumpFile, &programCommandSize, sizeof(uint32_t));
|
||||
write(dumpFile, programCommand, sizeOfChar*programCommandSize);
|
||||
write(dumpFile, "Version: ", strlen("Version: "));
|
||||
write(dumpFile, VERSION, sizeof(char)*strlen(VERSION));
|
||||
write(dumpFile, "\n", sizeof(char));
|
||||
|
||||
write(dumpFile, &programVersionSize, sizeof(uint32_t));
|
||||
write(dumpFile, programVersion, sizeOfChar*programVersionSize);
|
||||
write(dumpFile, "Compiled on: ", strlen("Compiled on: "));
|
||||
write(dumpFile, __DATE__, sizeof(char)*strlen(__DATE__));
|
||||
write(dumpFile, "\n\n", sizeof(char)*2);
|
||||
|
||||
write(dumpFile, &compileDateSize, sizeof(uint32_t));
|
||||
write(dumpFile, compileDate, sizeOfChar*compileDateSize);
|
||||
|
||||
write(dumpFile, &sysInfoValid, sizeof(uint32_t));
|
||||
write(dumpFile, &sysInfo, sizeOfUtsname);
|
||||
if (uname(&sysInfo) != 0)
|
||||
write(dumpFile, "System information may be invalid!\n",
|
||||
strlen("System information may be invalid!\n\n"));
|
||||
|
||||
write(dumpFile, &signum, sizeof(uint32_t));
|
||||
write(dumpFile, "Operating system: ", strlen("Operating system: "));
|
||||
write(dumpFile, sysInfo.sysname, strlen(sysInfo.sysname));
|
||||
write(dumpFile, "\n", sizeof(char));
|
||||
|
||||
write(dumpFile, "Node name: ", strlen("Node name: "));
|
||||
write(dumpFile, sysInfo.nodename, strlen(sysInfo.nodename));
|
||||
write(dumpFile, "\n", sizeof(char));
|
||||
|
||||
write(dumpFile, "Release: ", strlen("Release: "));
|
||||
write(dumpFile, sysInfo.release, strlen(sysInfo.release));
|
||||
write(dumpFile, "\n", sizeof(char));
|
||||
|
||||
write(dumpFile, "Version: ", strlen("Version: "));
|
||||
write(dumpFile, sysInfo.version, strlen(sysInfo.version));
|
||||
write(dumpFile, "\n", sizeof(char));
|
||||
|
||||
write(dumpFile, "Machine: ", strlen("Machine: "));
|
||||
write(dumpFile, sysInfo.machine, strlen(sysInfo.machine));
|
||||
write(dumpFile, "\n\n", sizeof(char)*2);
|
||||
|
||||
|
||||
write(dumpFile, "Dump caused by signal: ",
|
||||
strlen("Dump caused by signal: "));
|
||||
write(dumpFile, strsignal(sig), strlen(strsignal(sig)));
|
||||
write(dumpFile, "\n\n", sizeof(char)*2);
|
||||
|
||||
|
||||
backtrace_symbols_fd(btBuffer, btSize, dumpFile);
|
||||
|
||||
write(dumpFile, &btSize, sizeof(uint32_t));
|
||||
write(dumpFile, btBuffer, sizeOfVoidP*btSize);
|
||||
|
||||
fsync(dumpFile);
|
||||
close(dumpFile);
|
||||
|
@ -192,11 +210,9 @@ static void errorHandler(int sig)
|
|||
#endif // WIN32
|
||||
|
||||
|
||||
void setupExceptionHandler(char * programCommand_x, char * programVersion_x, char * compileDate_x)
|
||||
void setupExceptionHandler(char * programCommand_x)
|
||||
{
|
||||
programCommand = programCommand_x;
|
||||
programVersion = programVersion_x;
|
||||
compileDate = compileDate_x;
|
||||
|
||||
#ifdef WIN32
|
||||
SetUnhandledExceptionFilter(windowsExceptionHandler);
|
||||
|
|
|
@ -200,6 +200,6 @@ static inline void endian_fract(FRACT *fract) {
|
|||
# define endian_fract(x)
|
||||
#endif
|
||||
|
||||
void setupExceptionHandler(char * programCommand, char * programVersion, char * compileDate);
|
||||
void setupExceptionHandler(char * programCommand);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -401,7 +401,7 @@ int main(int argc, char *argv[])
|
|||
# endif //DEBUG
|
||||
#endif // WZ_CC_MSVC
|
||||
|
||||
setupExceptionHandler(argv[0], VERSION);
|
||||
setupExceptionHandler(argv[0]);
|
||||
|
||||
debug_init();
|
||||
atexit( debug_exit );
|
||||
|
|
Loading…
Reference in New Issue