From 92515da73a5df50db45111b8659ac463b4800236 Mon Sep 17 00:00:00 2001
From: Jeff Dike <jdike@addtoit.com>
Date: Sat, 28 May 2005 15:51:56 -0700
Subject: [PATCH] uml: fix segfault on exit with CONFIG_GCOV

We need to disable signals on exit in all cases, not just when rebooting.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
---
 arch/um/kernel/main.c | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

(limited to 'arch/um/kernel')

diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c
index 939e3b70867..e42e6364ca1 100644
--- a/arch/um/kernel/main.c
+++ b/arch/um/kernel/main.c
@@ -87,7 +87,7 @@ int main(int argc, char **argv, char **envp)
 {
 	char **new_argv;
 	sigset_t mask;
-	int ret, i;
+	int ret, i, err;
 
 	/* Enable all signals except SIGIO - in some environments, we can
 	 * enter with some signals blocked
@@ -160,27 +160,29 @@ int main(int argc, char **argv, char **envp)
 	 */
 	change_sig(SIGPROF, 0);
 
-	/* Reboot */
-	if(ret){
-		int err;
-
-		printf("\n");
+        /* This signal stuff used to be in the reboot case.  However,
+         * sometimes a SIGVTALRM can come in when we're halting (reproducably
+         * when writing out gcov information, presumably because that takes
+         * some time) and cause a segfault.
+         */
 
-		/* stop timers and set SIG*ALRM to be ignored */
-		disable_timer();
+        /* stop timers and set SIG*ALRM to be ignored */
+        disable_timer();
 
-		/* disable SIGIO for the fds and set SIGIO to be ignored */
-		err = deactivate_all_fds();
-		if(err)
-			printf("deactivate_all_fds failed, errno = %d\n",
-			       -err);
+        /* disable SIGIO for the fds and set SIGIO to be ignored */
+        err = deactivate_all_fds();
+        if(err)
+                printf("deactivate_all_fds failed, errno = %d\n", -err);
 
-		/* Let any pending signals fire now.  This ensures
-		 * that they won't be delivered after the exec, when
-		 * they are definitely not expected.
-		 */
-		unblock_signals();
+        /* Let any pending signals fire now.  This ensures
+         * that they won't be delivered after the exec, when
+         * they are definitely not expected.
+         */
+        unblock_signals();
 
+	/* Reboot */
+	if(ret){
+		printf("\n");
 		execvp(new_argv[0], new_argv);
 		perror("Failed to exec kernel");
 		ret = 1;
-- 
cgit v1.2.3-70-g09d2