diff options
author | Jeff Dike <jdike@addtoit.com> | 2005-05-28 15:51:56 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-28 16:46:12 -0700 |
commit | 92515da73a5df50db45111b8659ac463b4800236 (patch) | |
tree | 48b809f504e1c4fd7660507909e1553d40412b98 /arch/um/kernel/main.c | |
parent | 0894e27e7999bdbad2e65734caa1d5de65e7d890 (diff) |
[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>
Diffstat (limited to 'arch/um/kernel/main.c')
-rw-r--r-- | arch/um/kernel/main.c | 38 |
1 files changed, 20 insertions, 18 deletions
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; |