diff options
author | Jeff Dike <jdike@addtoit.com> | 2005-05-28 18:51:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-28 19:46:12 -0400 |
commit | 92515da73a5df50db45111b8659ac463b4800236 (patch) | |
tree | 48b809f504e1c4fd7660507909e1553d40412b98 /arch/um | |
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')
-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 939e3b708670..e42e6364ca13 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) | |||
87 | { | 87 | { |
88 | char **new_argv; | 88 | char **new_argv; |
89 | sigset_t mask; | 89 | sigset_t mask; |
90 | int ret, i; | 90 | int ret, i, err; |
91 | 91 | ||
92 | /* Enable all signals except SIGIO - in some environments, we can | 92 | /* Enable all signals except SIGIO - in some environments, we can |
93 | * enter with some signals blocked | 93 | * enter with some signals blocked |
@@ -160,27 +160,29 @@ int main(int argc, char **argv, char **envp) | |||
160 | */ | 160 | */ |
161 | change_sig(SIGPROF, 0); | 161 | change_sig(SIGPROF, 0); |
162 | 162 | ||
163 | /* Reboot */ | 163 | /* This signal stuff used to be in the reboot case. However, |
164 | if(ret){ | 164 | * sometimes a SIGVTALRM can come in when we're halting (reproducably |
165 | int err; | 165 | * when writing out gcov information, presumably because that takes |
166 | 166 | * some time) and cause a segfault. | |
167 | printf("\n"); | 167 | */ |
168 | 168 | ||
169 | /* stop timers and set SIG*ALRM to be ignored */ | 169 | /* stop timers and set SIG*ALRM to be ignored */ |
170 | disable_timer(); | 170 | disable_timer(); |
171 | 171 | ||
172 | /* disable SIGIO for the fds and set SIGIO to be ignored */ | 172 | /* disable SIGIO for the fds and set SIGIO to be ignored */ |
173 | err = deactivate_all_fds(); | 173 | err = deactivate_all_fds(); |
174 | if(err) | 174 | if(err) |
175 | printf("deactivate_all_fds failed, errno = %d\n", | 175 | printf("deactivate_all_fds failed, errno = %d\n", -err); |
176 | -err); | ||
177 | 176 | ||
178 | /* Let any pending signals fire now. This ensures | 177 | /* Let any pending signals fire now. This ensures |
179 | * that they won't be delivered after the exec, when | 178 | * that they won't be delivered after the exec, when |
180 | * they are definitely not expected. | 179 | * they are definitely not expected. |
181 | */ | 180 | */ |
182 | unblock_signals(); | 181 | unblock_signals(); |
183 | 182 | ||
183 | /* Reboot */ | ||
184 | if(ret){ | ||
185 | printf("\n"); | ||
184 | execvp(new_argv[0], new_argv); | 186 | execvp(new_argv[0], new_argv); |
185 | perror("Failed to exec kernel"); | 187 | perror("Failed to exec kernel"); |
186 | ret = 1; | 188 | ret = 1; |