aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/util.c')
-rw-r--r--arch/um/os-Linux/util.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 6ea77979531c..42827cafa6af 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -5,6 +5,7 @@
5 5
6#include <stdio.h> 6#include <stdio.h>
7#include <stdlib.h> 7#include <stdlib.h>
8#include <unistd.h>
8#include <errno.h> 9#include <errno.h>
9#include <signal.h> 10#include <signal.h>
10#include <string.h> 11#include <string.h>
@@ -75,6 +76,26 @@ void setup_hostinfo(char *buf, int len)
75 host.release, host.version, host.machine); 76 host.release, host.version, host.machine);
76} 77}
77 78
79/*
80 * We cannot use glibc's abort(). It makes use of tgkill() which
81 * has no effect within UML's kernel threads.
82 * After that glibc would execute an invalid instruction to kill
83 * the calling process and UML crashes with SIGSEGV.
84 */
85static inline void __attribute__ ((noreturn)) uml_abort(void)
86{
87 sigset_t sig;
88
89 fflush(NULL);
90
91 if (!sigemptyset(&sig) && !sigaddset(&sig, SIGABRT))
92 sigprocmask(SIG_UNBLOCK, &sig, 0);
93
94 for (;;)
95 if (kill(getpid(), SIGABRT) < 0)
96 exit(127);
97}
98
78void os_dump_core(void) 99void os_dump_core(void)
79{ 100{
80 int pid; 101 int pid;
@@ -116,5 +137,5 @@ void os_dump_core(void)
116 while ((pid = waitpid(-1, NULL, WNOHANG | __WALL)) > 0) 137 while ((pid = waitpid(-1, NULL, WNOHANG | __WALL)) > 0)
117 os_kill_ptraced_process(pid, 0); 138 os_kill_ptraced_process(pid, 0);
118 139
119 abort(); 140 uml_abort();
120} 141}