diff options
Diffstat (limited to 'arch/um/os-Linux/util.c')
| -rw-r--r-- | arch/um/os-Linux/util.c | 23 | 
1 files changed, 22 insertions, 1 deletions
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 6ea77979531..42827cafa6a 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -5,6 +5,7 @@  #include <stdio.h>  #include <stdlib.h> +#include <unistd.h>  #include <errno.h>  #include <signal.h>  #include <string.h> @@ -75,6 +76,26 @@ void setup_hostinfo(char *buf, int len)  		 host.release, host.version, host.machine);  } +/* + * We cannot use glibc's abort(). It makes use of tgkill() which + * has no effect within UML's kernel threads. + * After that glibc would execute an invalid instruction to kill + * the calling process and UML crashes with SIGSEGV. + */ +static inline void __attribute__ ((noreturn)) uml_abort(void) +{ +	sigset_t sig; + +	fflush(NULL); + +	if (!sigemptyset(&sig) && !sigaddset(&sig, SIGABRT)) +		sigprocmask(SIG_UNBLOCK, &sig, 0); + +	for (;;) +		if (kill(getpid(), SIGABRT) < 0) +			exit(127); +} +  void os_dump_core(void)  {  	int pid; @@ -116,5 +137,5 @@ void os_dump_core(void)  	while ((pid = waitpid(-1, NULL, WNOHANG | __WALL)) > 0)  		os_kill_ptraced_process(pid, 0); -	abort(); +	uml_abort();  }  |