improve abort fallback behavior when raising SIGABRT fails to terminate
authorRich Felker <dalias@aerifal.cx>
Sun, 3 Jul 2016 21:42:05 +0000 (17:42 -0400)
committerRich Felker <dalias@aerifal.cx>
Sun, 3 Jul 2016 22:01:07 +0000 (18:01 -0400)
these changes still do not yield a fully-conforming abort, but they
fix two known issues:

- per POSIX, termination via SIGKILL is not "abnormal", but both ISO C
  and POSIX require abort to yield abnormal termination.

- raising SIGKILL fails to do anything to pid 1 in some containers.

now, the trapping instruction produced by a_crash() is expected to
produce abnormal termination, without the risk of invoking a signal
handler since SIGILL and SIGSEGV are blocked, and _Exit, which
contains an infinite loop analogous to the one being removed from
abort itself, is used as a last resort.

this implementation still fails to produce an exit status as if the
process terminated via SIGABRT in cases where SIGABRT is blocked or
ignored, but fixing that is not easy; the obvious pseudo-solutions all
have subtle race conditions where a concurrent fork or exec can expose
incorrect signal state.

src/exit/abort.c

index 203dd35..ecc0f73 100644 (file)
@@ -1,10 +1,14 @@
 #include <stdlib.h>
 #include <signal.h>
 #include "syscall.h"
+#include "pthread_impl.h"
+#include "atomic.h"
 
 _Noreturn void abort(void)
 {
        raise(SIGABRT);
+       __block_all_sigs(0);
+       a_crash();
        raise(SIGKILL);
-       for (;;);
+       _Exit(127);
 }