summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2018-04-17 22:08:48 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2018-04-17 22:36:21 -0500
commit1316aae0c862240ff58b1cf38c92cd8cefd02a91 (patch)
tree234dead03e473b4c7809680ec17b64f6bf61d448
parent0979c50b831c67e0b4f4a560435b867b35cdac67 (diff)
downloadmusl-1316aae0c862240ff58b1cf38c92cd8cefd02a91.tar.gz
musl-1316aae0c862240ff58b1cf38c92cd8cefd02a91.tar.bz2
musl-1316aae0c862240ff58b1cf38c92cd8cefd02a91.tar.xz
musl-1316aae0c862240ff58b1cf38c92cd8cefd02a91.zip
abort: raise SIGABRT again if signal is ignored
POSIX requires that abort() gives the SIGABRT status to waitpid(3) and friends. If a signal handler is installed, and erroneously returns, then the status given to waitpid(3) is SIGSEGV instead of SIGABRT. This change gives another opportunity for the proper SIGABRT status to be given to any process monitoring this one's process, before we fall back to a_crash(), which should be sufficient.
-rw-r--r--src/exit/abort.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/exit/abort.c b/src/exit/abort.c
index ecc0f735..5e5a87c3 100644
--- a/src/exit/abort.c
+++ b/src/exit/abort.c
@@ -1,13 +1,31 @@
#include <stdlib.h>
#include <signal.h>
+#include <string.h>
#include "syscall.h"
#include "pthread_impl.h"
#include "atomic.h"
_Noreturn void abort(void)
{
+ struct sigaction abrtaction;
+ sigset_t abrtset;
+
raise(SIGABRT);
__block_all_sigs(0);
+
+ /* Unblock just SIGABRT, and set default handler */
+ sigemptyset(&abrtset);
+ sigaddset(&abrtset, SIGABRT);
+ sigprocmask(SIG_UNBLOCK, &abrtset, 0);
+
+ memset(&abrtaction, 0, sizeof(struct sigaction));
+ abrtaction.sa_handler = SIG_DFL;
+
+ sigaction(SIGABRT, &abrtaction, NULL);
+
+ raise(SIGABRT);
+
+ /* Ok, give up. */
a_crash();
raise(SIGKILL);
_Exit(127);