forked from Mirrors/openclonk
linux: Crash-handler prints the address that caused the signal if applicable
To do that, switch from the deprecated signal() to sigaction(). Instead of reinstalling the signal handler, only use SA_RESETHAND for the signals generated by a bug. Also stop interfering with the coredump functionality of SIGQUIT, but handle SIGHUP like SIGTERM and SIGINT.heavy-resources
parent
eed5836838
commit
604ced638b
|
@ -125,7 +125,7 @@ int main()
|
|||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
static void crash_handler(int signo)
|
||||
static void crash_handler(int signo, siginfo_t * si, void *)
|
||||
{
|
||||
static unsigned signal_count = 0;
|
||||
++signal_count;
|
||||
|
@ -134,8 +134,6 @@ static void crash_handler(int signo)
|
|||
case SIGINT: case SIGTERM: case SIGHUP:
|
||||
if (signal_count < 2) {
|
||||
Application.Quit();
|
||||
// reinstall handler
|
||||
signal(signo, crash_handler);
|
||||
break;
|
||||
} // else/fallthrough
|
||||
default:
|
||||
|
@ -151,10 +149,28 @@ static void crash_handler(int signo)
|
|||
case SIGSEGV: write(logfd, "SIGSEGV", sizeof ("SIGSEGV") - 1); break;
|
||||
case SIGABRT: write(logfd, "SIGABRT", sizeof ("SIGABRT") - 1); break;
|
||||
case SIGINT: write(logfd, "SIGINT", sizeof ("SIGINT") - 1); break;
|
||||
case SIGQUIT: write(logfd, "SIGQUIT", sizeof ("SIGQUIT") - 1); break;
|
||||
case SIGHUP: write(logfd, "SIGHUP", sizeof ("SIGHUP") - 1); break;
|
||||
case SIGFPE: write(logfd, "SIGFPE", sizeof ("SIGFPE") - 1); break;
|
||||
case SIGTERM: write(logfd, "SIGTERM", sizeof ("SIGTERM") - 1); break;
|
||||
}
|
||||
char hex[sizeof(void *) * 2];
|
||||
int i; intptr_t x = reinterpret_cast<intptr_t>(si->si_addr);
|
||||
switch (signo)
|
||||
{
|
||||
case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGTRAP:
|
||||
write(logfd, " (0x", sizeof (" (0x") - 1);
|
||||
for (int i = sizeof(void *) * 2 - 1; i >= 0; --i)
|
||||
{
|
||||
if ((x & 0xf) > 9)
|
||||
hex[i] = 'a' + (x & 0xf) - 9;
|
||||
else
|
||||
hex[i] = '0' + (x & 0xf);
|
||||
x >>= 4;
|
||||
}
|
||||
write(logfd, hex, sizeof (hex));
|
||||
write(logfd, ")", sizeof (")") - 1);
|
||||
break;
|
||||
}
|
||||
write(logfd, "\n", sizeof ("\n") - 1);
|
||||
if (logfd == STDERR_FILENO) logfd = GetLogFD();
|
||||
else break;
|
||||
|
@ -194,15 +210,21 @@ int main (int argc, char * argv[])
|
|||
return C4XRV_Failure;
|
||||
}
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
struct sigaction sa;
|
||||
sa.sa_sigaction = crash_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
// Quit the program when asked
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
// Set up debugging facilities
|
||||
signal(SIGBUS, crash_handler);
|
||||
signal(SIGILL, crash_handler);
|
||||
signal(SIGSEGV, crash_handler);
|
||||
signal(SIGABRT, crash_handler);
|
||||
signal(SIGINT, crash_handler);
|
||||
signal(SIGQUIT, crash_handler);
|
||||
signal(SIGFPE, crash_handler);
|
||||
signal(SIGTERM, crash_handler);
|
||||
sa.sa_flags |= SA_RESETHAND;
|
||||
sigaction(SIGBUS, &sa, NULL);
|
||||
sigaction(SIGILL, &sa, NULL);
|
||||
sigaction(SIGSEGV, &sa, NULL);
|
||||
sigaction(SIGABRT, &sa, NULL);
|
||||
sigaction(SIGFPE, &sa, NULL);
|
||||
#endif
|
||||
|
||||
// Init application
|
||||
|
|
Loading…
Reference in New Issue