[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>
This commit is contained in:
parent
0894e27e79
commit
92515da73a
1 changed files with 21 additions and 19 deletions
|
@ -87,7 +87,7 @@ int main(int argc, char **argv, char **envp)
|
||||||
{
|
{
|
||||||
char **new_argv;
|
char **new_argv;
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
int ret, i;
|
int ret, i, err;
|
||||||
|
|
||||||
/* Enable all signals except SIGIO - in some environments, we can
|
/* Enable all signals except SIGIO - in some environments, we can
|
||||||
* enter with some signals blocked
|
* enter with some signals blocked
|
||||||
|
@ -160,27 +160,29 @@ int main(int argc, char **argv, char **envp)
|
||||||
*/
|
*/
|
||||||
change_sig(SIGPROF, 0);
|
change_sig(SIGPROF, 0);
|
||||||
|
|
||||||
|
/* 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();
|
||||||
|
|
||||||
|
/* 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();
|
||||||
|
|
||||||
/* Reboot */
|
/* Reboot */
|
||||||
if(ret){
|
if(ret){
|
||||||
int err;
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* 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();
|
|
||||||
|
|
||||||
execvp(new_argv[0], new_argv);
|
execvp(new_argv[0], new_argv);
|
||||||
perror("Failed to exec kernel");
|
perror("Failed to exec kernel");
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
Loading…
Add table
Reference in a new issue