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
Günther Brammer 2013-09-07 00:38:39 +02:00
parent eed5836838
commit 604ced638b
1 changed files with 34 additions and 12 deletions

View File

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