1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
From 1316aae0c862240ff58b1cf38c92cd8cefd02a91 Mon Sep 17 00:00:00 2001
From: "A. Wilcox" <AWilcox@Wilcox-Tech.com>
Date: Tue, 17 Apr 2018 22:08:48 -0500
Subject: [PATCH 7/7] 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.
---
src/exit/abort.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
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);
--
2.15.0
|