summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2016-07-03 17:42:05 -0400
committerRich Felker <dalias@aerifal.cx>2016-07-03 18:01:07 -0400
commit0c8bc102f287d3993751d80ba2dffb01e0c8bc7f (patch)
treedbf09a7d278e1468eb83429eed9e178f1f05d951 /src
parentee3f0c551669ca1c61abac0888f93a27b0b17856 (diff)
downloadmusl-0c8bc102f287d3993751d80ba2dffb01e0c8bc7f.tar.gz
musl-0c8bc102f287d3993751d80ba2dffb01e0c8bc7f.tar.bz2
musl-0c8bc102f287d3993751d80ba2dffb01e0c8bc7f.tar.xz
musl-0c8bc102f287d3993751d80ba2dffb01e0c8bc7f.zip
improve abort fallback behavior when raising SIGABRT fails to terminate
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.
Diffstat (limited to 'src')
-rw-r--r--src/exit/abort.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/src/exit/abort.c b/src/exit/abort.c
index 203dd35c..ecc0f735 100644
--- a/src/exit/abort.c
+++ b/src/exit/abort.c
@@ -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);
}