+static bool dump_core = true;
+
+_noreturn static void freeze(void) {
+ for (;;)
+ pause();
+}
+
+_noreturn static void crash(int sig) {
+
+ if (!dump_core)
+ log_error("Caught <%s>, not dumping core.", strsignal(sig));
+ else {
+ pid_t pid;
+
+ log_warning("Caugh <%s>, dumping core.", strsignal(sig));
+
+ if ((pid = fork()) < 0)
+ log_error("Caught <%s>, cannot dump core: %s", strsignal(sig), strerror(errno));
+
+ else if (pid == 0) {
+ struct sigaction sa;
+ struct rlimit rl;
+
+ /* Enable default signal handler for core dump */
+ zero(sa);
+ sa.sa_handler = SIG_DFL;
+ assert_se(sigaction(sig, &sa, NULL) == 0);
+
+ /* Don't limit the core dump size */
+ zero(rl);
+ rl.rlim_cur = RLIM_INFINITY;
+ rl.rlim_max = RLIM_INFINITY;
+ setrlimit(RLIMIT_CORE, &rl);
+
+ /* Just to be sure... */
+ assert_se(chdir("/") == 0);
+
+ /* Raise the signal again */
+ raise(sig);
+
+ assert_not_reached("We shouldn't be here...");
+ _exit(1);
+ }
+ }
+
+ log_error("Freezing execution.");
+ freeze();
+}
+
+static void install_crash_handler(void) {
+ struct sigaction sa;
+
+ zero(sa);
+
+ sa.sa_handler = crash;
+ sa.sa_flags = SA_NODEFER;
+
+ assert_se(sigaction(SIGSEGV, &sa, NULL) == 0);
+ assert_se(sigaction(SIGABRT, &sa, NULL) == 0);
+}