blob: 04b14e46648136994e2aabc336a592217eed6049 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
3/*--- Implementation of POSIX signals. ---*/
4/*--- vg_signals.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
njnc9539842002-10-02 13:26:35 +00008 This file is part of Valgrind, an extensible x86 protected-mode
9 emulator for monitoring program execution on x86-Unixes.
sewardjde4a1d02002-03-22 01:27:54 +000010
njn0e1b5142003-04-15 14:58:06 +000011 Copyright (C) 2000-2003 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000012 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000013
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
njn25e49d8e72002-09-23 09:36:25 +000029 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000030*/
31
jsgf855d93d2003-10-13 22:26:55 +000032/*
33 New signal handling.
34
35 Now that all threads have a ProxyLWP to deal with signals for them,
36 we can use the kernel to do a lot more work for us. The kernel
37 will deal with blocking signals, pending blocked signals, queues
38 and thread selection. We just need to deal with setting a signal
39 handler and signal delivery.
40
41 In order to match the proper kernel signal semantics, the proxy LWP
42 which recieves a signal goes through an exchange of messages with
43 the scheduler LWP. When the proxy first gets a signal, it
44 immediately blocks all signals and sends a message back to the
45 scheduler LWP. It then enters a SigACK state, in which requests to
46 run system calls are ignored, and all signals remain blocked. When
47 the scheduler gets the signal message, it sets up the thread to
48 enter its signal handler, and sends a SigACK message back to the
49 proxy, which includes the signal mask to be applied while running
50 the handler. On recieving SigACK, the proxy sets the new signal
51 mask and reverts to its normal mode of operation. (All this is
52 implemented in vg_syscalls.c)
53
54 This protocol allows the application thread to take delivery of the
55 signal at some arbitary time after the signal was sent to the
56 process, while still getting proper signal delivery semantics (most
57 notably, getting the signal block sets right while running the
58 signal handler, and not allowing recursion where there wouldn't
59 have been normally).
60
61 Important point: the main LWP *always* has all signals blocked
62 except for SIGSEGV, SIGBUS, SIGFPE and SIGILL (ie, signals which
63 are synchronously changed . If the kernel supports thread groups
64 with shared signal state (Linux 2.5+, RedHat's 2.4), then these are
65 the only signals it needs to handle.
66
67 If we get a synchronous signal, the details are placed into
68 VG_(unresumable_siginfo) and we longjmp back into the scheduler,
69 since we can't resume executing the client code. The scheduler
70 immediately starts signal delivery to the thread which generated
71 the signal.
72
73 On older kernels without thread-groups, we need to poll the pending
74 signal with sigtimedwait() and farm any signals off to the
75 appropriate proxy LWP.
76 */
sewardjde4a1d02002-03-22 01:27:54 +000077
78#include "vg_include.h"
jsgf855d93d2003-10-13 22:26:55 +000079#include <stddef.h> /* OK, no library dependencies */
sewardjde4a1d02002-03-22 01:27:54 +000080
sewardj018f7622002-05-15 21:13:39 +000081/* Define to give more sanity checking for signals. */
82#define DEBUG_SIGNALS
83
84
jsgf855d93d2003-10-13 22:26:55 +000085/*
sewardjfa356512002-05-24 00:00:59 +000086 - The following causes an infinite loop: start Hugs, Feb 2001
87 version, and do Control-C at the prompt. There is an infinite
88 series of sigints delivered (to the client); but also seemingly
89 to valgrind, which is very strange. I don't know why.
90
jsgf855d93d2003-10-13 22:26:55 +000091 [I haven't re-tested this, but this is likely fixed - JSGF]
sewardjfa356512002-05-24 00:00:59 +000092*/
93
94
sewardj018f7622002-05-15 21:13:39 +000095/* ---------------------------------------------------------------------
96 Forwards decls.
97 ------------------------------------------------------------------ */
98
jsgf855d93d2003-10-13 22:26:55 +000099static void vg_sync_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * );
100static void vg_async_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * );
101static void vg_babyeater ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * );
102static void proxy_sigvg_handler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * );
sewardj018f7622002-05-15 21:13:39 +0000103
jsgf855d93d2003-10-13 22:26:55 +0000104static Bool is_correct_sigmask(void);
105static const Char *signame(Int sigNo);
sewardj018f7622002-05-15 21:13:39 +0000106
107/* ---------------------------------------------------------------------
108 HIGH LEVEL STUFF TO DO WITH SIGNALS: POLICY (MOSTLY)
109 ------------------------------------------------------------------ */
110
jsgf855d93d2003-10-13 22:26:55 +0000111/* If set to true, the currently running kernel doesn't do the right
112 thing with signals and LWPs, so we need to do our own. */
113Bool VG_(do_signal_routing) = False;
114
fitzhardingee1c06d82003-10-30 07:21:44 +0000115/* Set of signal which are pending for the whole process. This is
116 only used when we're doing signal routing, and this is a place to
117 remember pending signals which we can't keep actually pending for
118 some reason. */
119static vki_ksigset_t proc_pending; /* process-wide pending signals */
120
jsgf855d93d2003-10-13 22:26:55 +0000121/* Since we use a couple of RT signals, we need to handle allocating
122 the rest for application use. */
123Int VG_(sig_rtmin) = VKI_SIGRTUSERMIN;
124Int VG_(sig_rtmax) = VKI_SIGRTMAX;
125
126Int VG_(sig_alloc_rtsig)(Int high)
127{
128 Int ret;
129
130 if (VG_(sig_rtmin) >= VG_(sig_rtmax))
131 ret = -1;
132 else
133 ret = high ? VG_(sig_rtmin)++ : VG_(sig_rtmax)--;
134
135 vg_assert(ret >= VKI_SIGRTUSERMIN);
136
137 return ret;
138}
139
sewardjde4a1d02002-03-22 01:27:54 +0000140/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000141 Signal state for this process.
142 ------------------------------------------------------------------ */
143
sewardj018f7622002-05-15 21:13:39 +0000144
sewardjb48e5002002-05-13 00:16:03 +0000145/* Base-ment of these arrays[VKI_KNSIG].
146
147 Valid signal numbers are 1 .. VKI_KNSIG inclusive.
148 Rather than subtracting 1 for indexing these arrays, which
149 is tedious and error-prone, they are simply dimensioned 1 larger,
150 and entry [0] is not used.
151 */
152
sewardjb48e5002002-05-13 00:16:03 +0000153
sewardj018f7622002-05-15 21:13:39 +0000154/* -----------------------------------------------------
155 Static client signal state (SCSS). This is the state
156 that the client thinks it has the kernel in.
157 SCSS records verbatim the client's settings. These
158 are mashed around only when SKSS is calculated from it.
159 -------------------------------------------------- */
sewardjb48e5002002-05-13 00:16:03 +0000160
sewardj018f7622002-05-15 21:13:39 +0000161typedef
162 struct {
163 void* scss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN or ptr to
164 client's handler */
165 UInt scss_flags;
166 vki_ksigset_t scss_mask;
167 void* scss_restorer; /* god knows; we ignore it. */
168 }
169 SCSS_Per_Signal;
sewardjb48e5002002-05-13 00:16:03 +0000170
sewardj018f7622002-05-15 21:13:39 +0000171typedef
172 struct {
sewardj2342c972002-05-22 23:34:20 +0000173 /* per-signal info */
sewardj018f7622002-05-15 21:13:39 +0000174 SCSS_Per_Signal scss_per_sig[1+VKI_KNSIG];
sewardj2342c972002-05-22 23:34:20 +0000175
176 /* Signal delivery stack, if any. */
177 vki_kstack_t altstack;
178
sewardj018f7622002-05-15 21:13:39 +0000179 /* Additional elements to SCSS not stored here:
180 - for each thread, the thread's blocking mask
181 - for each thread in WaitSIG, the set of waited-on sigs
182 */
183 }
184 SCSS;
sewardjb48e5002002-05-13 00:16:03 +0000185
sewardj018f7622002-05-15 21:13:39 +0000186static SCSS vg_scss;
187
188
189/* -----------------------------------------------------
190 Static kernel signal state (SKSS). This is the state
191 that we have the kernel in. It is computed from SCSS.
192 -------------------------------------------------- */
193
194/* Let's do:
195 sigprocmask assigns to all thread masks
196 so that at least everything is always consistent
197 Flags:
jsgf855d93d2003-10-13 22:26:55 +0000198 SA_SIGINFO -- we always set it, and honour it for the client
sewardj018f7622002-05-15 21:13:39 +0000199 SA_NOCLDSTOP -- passed to kernel
200 SA_ONESHOT or SA_RESETHAND -- required; abort if not set
jsgf855d93d2003-10-13 22:26:55 +0000201 SA_RESTART -- we observe this but set our handlers to always restart
202 SA_NOMASK or SA_NODEFER -- we observe this, but our handlers block everything
sewardj018f7622002-05-15 21:13:39 +0000203 SA_ONSTACK -- currently not supported; abort if set.
jsgf855d93d2003-10-13 22:26:55 +0000204 SA_NOCLDWAIT -- we observe this, but we never set it (doesn't quite
205 work if client is blocked in a wait4() syscall)
sewardjb48e5002002-05-13 00:16:03 +0000206*/
sewardjde4a1d02002-03-22 01:27:54 +0000207
sewardj77e466c2002-04-14 02:29:29 +0000208
sewardj018f7622002-05-15 21:13:39 +0000209typedef
210 struct {
211 void* skss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN
212 or ptr to our handler */
213 UInt skss_flags;
214 /* There is no skss_mask, since we know that we will always ask
jsgf855d93d2003-10-13 22:26:55 +0000215 for all signals to be blocked in our sighandlers. */
sewardj018f7622002-05-15 21:13:39 +0000216 /* Also there is no skss_restorer. */
217 }
218 SKSS_Per_Signal;
sewardjde4a1d02002-03-22 01:27:54 +0000219
sewardj018f7622002-05-15 21:13:39 +0000220typedef
221 struct {
222 SKSS_Per_Signal skss_per_sig[1+VKI_KNSIG];
sewardj018f7622002-05-15 21:13:39 +0000223 }
224 SKSS;
225
226static SKSS vg_skss;
sewardjde4a1d02002-03-22 01:27:54 +0000227
jsgf855d93d2003-10-13 22:26:55 +0000228Bool VG_(is_sig_ign)(Int sigNo)
229{
230 vg_assert(sigNo >= 1 && sigNo <= VKI_KNSIG);
sewardj2e93c502002-04-12 11:12:52 +0000231
jsgf855d93d2003-10-13 22:26:55 +0000232 return vg_scss.scss_per_sig[sigNo].scss_handler == VKI_SIG_IGN;
233}
sewardjb48e5002002-05-13 00:16:03 +0000234
sewardj018f7622002-05-15 21:13:39 +0000235/* ---------------------------------------------------------------------
236 Compute the SKSS required by the current SCSS.
237 ------------------------------------------------------------------ */
238
sewardj4f29ddf2002-05-03 22:29:04 +0000239static
sewardj018f7622002-05-15 21:13:39 +0000240void pp_SKSS ( void )
241{
242 Int sig;
243 VG_(printf)("\n\nSKSS:\n");
244 for (sig = 1; sig <= VKI_KNSIG; sig++) {
245 VG_(printf)("sig %d: handler 0x%x, flags 0x%x\n", sig,
246 vg_skss.skss_per_sig[sig].skss_handler,
247 vg_skss.skss_per_sig[sig].skss_flags );
sewardj77e466c2002-04-14 02:29:29 +0000248
sewardj018f7622002-05-15 21:13:39 +0000249 }
sewardj018f7622002-05-15 21:13:39 +0000250}
251
sewardj018f7622002-05-15 21:13:39 +0000252/* This is the core, clever bit. Computation is as follows:
253
254 For each signal
255 handler = if client has a handler, then our handler
jsgf855d93d2003-10-13 22:26:55 +0000256 else if client is DFL, then our handler as well
257 else (client must be IGN)
258 if (signal == SIGCHLD), then handler is vg_babyeater
259 else IGN
sewardj018f7622002-05-15 21:13:39 +0000260
jsgf855d93d2003-10-13 22:26:55 +0000261 We don't really bother with blocking signals here, because the we
262 rely on the proxyLWP having set it as part of its kernel state.
sewardj018f7622002-05-15 21:13:39 +0000263*/
264static
265void calculate_SKSS_from_SCSS ( SKSS* dst )
266{
267 Int sig;
sewardj018f7622002-05-15 21:13:39 +0000268 UInt scss_flags;
269 UInt skss_flags;
270
sewardj018f7622002-05-15 21:13:39 +0000271 for (sig = 1; sig <= VKI_KNSIG; sig++) {
jsgf855d93d2003-10-13 22:26:55 +0000272 void *skss_handler;
273 void *scss_handler;
274
sewardj018f7622002-05-15 21:13:39 +0000275 scss_handler = vg_scss.scss_per_sig[sig].scss_handler;
276 scss_flags = vg_scss.scss_per_sig[sig].scss_flags;
277
jsgf855d93d2003-10-13 22:26:55 +0000278 switch(sig) {
279 case VKI_SIGSEGV:
280 case VKI_SIGBUS:
281 case VKI_SIGFPE:
282 case VKI_SIGILL:
283 /* For these, we always want to catch them and report, even
284 if the client code doesn't. */
285 skss_handler = vg_sync_signalhandler;
286 break;
287
288 case VKI_SIGVGINT:
289 case VKI_SIGVGKILL:
290 skss_handler = proxy_sigvg_handler;
291 break;
292
293 case VKI_SIGCHLD:
294 if (scss_handler == VKI_SIG_IGN) {
295 skss_handler = vg_babyeater;
296 break;
297 }
298 /* FALLTHROUGH */
299 default:
300 if (scss_handler == VKI_SIG_IGN)
301 skss_handler = VKI_SIG_IGN;
302 else
303 skss_handler = vg_async_signalhandler;
304 break;
305 }
306
sewardj018f7622002-05-15 21:13:39 +0000307 /* Restorer */
308 /*
309 Doesn't seem like we can spin this one.
310 if (vg_scss.scss_per_sig[sig].scss_restorer != NULL)
311 VG_(unimplemented)
312 ("sigactions with non-NULL .sa_restorer field");
313 */
314
sewardj018f7622002-05-15 21:13:39 +0000315 /* Flags */
316
317 skss_flags = 0;
jsgf855d93d2003-10-13 22:26:55 +0000318
sewardj018f7622002-05-15 21:13:39 +0000319 /* SA_NOCLDSTOP: pass to kernel */
320 if (scss_flags & VKI_SA_NOCLDSTOP)
321 skss_flags |= VKI_SA_NOCLDSTOP;
jsgf855d93d2003-10-13 22:26:55 +0000322
323 /* SA_NOCLDWAIT - don't set */
324 /* XXX we could set this if we're not using wait() ourselves for
325 tracking proxyLWPs (ie, have_futex is true in
326 vg_syscalls.c. */
327
sewardj018f7622002-05-15 21:13:39 +0000328 /* SA_ONESHOT: ignore client setting */
329 /*
330 if (!(scss_flags & VKI_SA_ONESHOT))
331 VG_(unimplemented)
332 ("sigactions without SA_ONESHOT");
333 vg_assert(scss_flags & VKI_SA_ONESHOT);
334 skss_flags |= VKI_SA_ONESHOT;
335 */
jsgf855d93d2003-10-13 22:26:55 +0000336
337 /* SA_RESTART: ignore client setting and always set it for us
338 (even though we never rely on the kernel to restart a
339 syscall, we observe whether it wanted to restart the syscall
340 or not, which guides our actions) */
sewardj018f7622002-05-15 21:13:39 +0000341 skss_flags |= VKI_SA_RESTART;
jsgf855d93d2003-10-13 22:26:55 +0000342
343 /* SA_NOMASK: ignore it */
344
sewardj2342c972002-05-22 23:34:20 +0000345 /* SA_ONSTACK: client setting is irrelevant here */
346 /*
sewardj018f7622002-05-15 21:13:39 +0000347 if (scss_flags & VKI_SA_ONSTACK)
348 VG_(unimplemented)
349 ("signals on an alternative stack (SA_ONSTACK)");
350 vg_assert(!(scss_flags & VKI_SA_ONSTACK));
sewardj2342c972002-05-22 23:34:20 +0000351 */
sewardj018f7622002-05-15 21:13:39 +0000352 /* ... but WE ask for on-stack ourselves ... */
353 skss_flags |= VKI_SA_ONSTACK;
354
jsgf855d93d2003-10-13 22:26:55 +0000355 /* always ask for SA_SIGINFO */
356 skss_flags |= VKI_SA_SIGINFO;
sewardj018f7622002-05-15 21:13:39 +0000357
jsgf855d93d2003-10-13 22:26:55 +0000358 /* Create SKSS entry for this signal. */
sewardj018f7622002-05-15 21:13:39 +0000359
sewardj6a3c26e2002-05-23 17:09:43 +0000360 if (sig != VKI_SIGKILL && sig != VKI_SIGSTOP)
361 dst->skss_per_sig[sig].skss_handler = skss_handler;
362 else
363 dst->skss_per_sig[sig].skss_handler = VKI_SIG_DFL;
364
sewardj018f7622002-05-15 21:13:39 +0000365 dst->skss_per_sig[sig].skss_flags = skss_flags;
366 }
367
368 /* Sanity checks. */
369 vg_assert(dst->skss_per_sig[VKI_SIGKILL].skss_handler
370 == VKI_SIG_DFL);
371 vg_assert(dst->skss_per_sig[VKI_SIGSTOP].skss_handler
372 == VKI_SIG_DFL);
sewardj018f7622002-05-15 21:13:39 +0000373
374 if (0)
375 pp_SKSS();
376}
377
378
379/* ---------------------------------------------------------------------
380 After a possible SCSS change, update SKSS and the kernel itself.
381 ------------------------------------------------------------------ */
382
sewardj018f7622002-05-15 21:13:39 +0000383void VG_(handle_SCSS_change) ( Bool force_update )
384{
385 Int res, sig;
386 SKSS skss_old;
387 vki_ksigaction ksa, ksa_old;
388
jsgf855d93d2003-10-13 22:26:55 +0000389 vg_assert(is_correct_sigmask());
sewardj018f7622002-05-15 21:13:39 +0000390
391 /* Remember old SKSS and calculate new one. */
392 skss_old = vg_skss;
393 calculate_SKSS_from_SCSS ( &vg_skss );
394
395 /* Compare the new SKSS entries vs the old ones, and update kernel
396 where they differ. */
397 for (sig = 1; sig <= VKI_KNSIG; sig++) {
398
399 /* Trying to do anything with SIGKILL is pointless; just ignore
400 it. */
401 if (sig == VKI_SIGKILL || sig == VKI_SIGSTOP)
402 continue;
403
sewardj018f7622002-05-15 21:13:39 +0000404 if (!force_update) {
405 if ((skss_old.skss_per_sig[sig].skss_handler
406 == vg_skss.skss_per_sig[sig].skss_handler)
407 && (skss_old.skss_per_sig[sig].skss_flags
408 == vg_skss.skss_per_sig[sig].skss_flags))
409 /* no difference */
410 continue;
411 }
412
413 ksa.ksa_handler = vg_skss.skss_per_sig[sig].skss_handler;
414 ksa.ksa_flags = vg_skss.skss_per_sig[sig].skss_flags;
415 vg_assert(ksa.ksa_flags & VKI_SA_ONSTACK);
416 VG_(ksigfillset)( &ksa.ksa_mask );
417 VG_(ksigdelset)( &ksa.ksa_mask, VKI_SIGKILL );
418 VG_(ksigdelset)( &ksa.ksa_mask, VKI_SIGSTOP );
419 ksa.ksa_restorer = NULL;
420
421 if (VG_(clo_trace_signals))
422 VG_(message)(Vg_DebugMsg,
423 "setting ksig %d to: hdlr 0x%x, flags 0x%x, "
424 "mask(63..0) 0x%x 0x%x",
425 sig, ksa.ksa_handler,
426 ksa.ksa_flags,
427 ksa.ksa_mask.ws[1],
428 ksa.ksa_mask.ws[0]
429 );
430
431 res = VG_(ksigaction)( sig, &ksa, &ksa_old );
432 vg_assert(res == 0);
433
434 /* Since we got the old sigaction more or less for free, might
435 as well extract the maximum sanity-check value from it. */
436 if (!force_update) {
437 vg_assert(ksa_old.ksa_handler
438 == skss_old.skss_per_sig[sig].skss_handler);
439 vg_assert(ksa_old.ksa_flags
440 == skss_old.skss_per_sig[sig].skss_flags);
441 vg_assert(ksa_old.ksa_restorer
442 == NULL);
443 VG_(ksigaddset)( &ksa_old.ksa_mask, VKI_SIGKILL );
444 VG_(ksigaddset)( &ksa_old.ksa_mask, VKI_SIGSTOP );
445 vg_assert(VG_(kisfullsigset)( &ksa_old.ksa_mask ));
446 }
447 }
sewardj018f7622002-05-15 21:13:39 +0000448}
449
450
451/* ---------------------------------------------------------------------
452 Update/query SCSS in accordance with client requests.
453 ------------------------------------------------------------------ */
454
sewardj2342c972002-05-22 23:34:20 +0000455/* Logic for this alt-stack stuff copied directly from do_sigaltstack
456 in kernel/signal.[ch] */
457
458/* True if we are on the alternate signal stack. */
459static Int on_sig_stack ( Addr m_esp )
460{
461 return (m_esp - (Addr)vg_scss.altstack.ss_sp
462 < vg_scss.altstack.ss_size);
463}
464
465static Int sas_ss_flags ( Addr m_esp )
466{
467 return (vg_scss.altstack.ss_size == 0
468 ? VKI_SS_DISABLE
469 : on_sig_stack(m_esp) ? VKI_SS_ONSTACK : 0);
470}
471
472
473void VG_(do__NR_sigaltstack) ( ThreadId tid )
474{
475 vki_kstack_t* ss;
476 vki_kstack_t* oss;
477 Addr m_esp;
478
479 vg_assert(VG_(is_valid_tid)(tid));
480 ss = (vki_kstack_t*)(VG_(threads)[tid].m_ebx);
481 oss = (vki_kstack_t*)(VG_(threads)[tid].m_ecx);
482 m_esp = VG_(threads)[tid].m_esp;
483
484 if (VG_(clo_trace_signals))
485 VG_(message)(Vg_DebugExtraMsg,
486 "__NR_sigaltstack: tid %d, "
487 "ss 0x%x, oss 0x%x (current %%esp %p)",
488 tid, (UInt)ss, (UInt)oss, (UInt)m_esp );
489
490 if (oss != NULL) {
491 oss->ss_sp = vg_scss.altstack.ss_sp;
492 oss->ss_size = vg_scss.altstack.ss_size;
jsgf855d93d2003-10-13 22:26:55 +0000493 oss->ss_flags = vg_scss.altstack.ss_flags | sas_ss_flags(m_esp);
sewardj2342c972002-05-22 23:34:20 +0000494 }
495
496 if (ss != NULL) {
497 if (on_sig_stack(VG_(threads)[tid].m_esp)) {
njnd3040452003-05-19 15:04:06 +0000498 SET_SYSCALL_RETVAL(tid, -VKI_EPERM);
sewardj2342c972002-05-22 23:34:20 +0000499 return;
500 }
501 if (ss->ss_flags != VKI_SS_DISABLE
502 && ss->ss_flags != VKI_SS_ONSTACK
503 && ss->ss_flags != 0) {
njnd3040452003-05-19 15:04:06 +0000504 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
sewardj2342c972002-05-22 23:34:20 +0000505 return;
506 }
507 if (ss->ss_flags == VKI_SS_DISABLE) {
jsgf855d93d2003-10-13 22:26:55 +0000508 vg_scss.altstack.ss_flags = VKI_SS_DISABLE;
sewardj2342c972002-05-22 23:34:20 +0000509 } else {
510 if (ss->ss_size < VKI_MINSIGSTKSZ) {
njnd3040452003-05-19 15:04:06 +0000511 SET_SYSCALL_RETVAL(tid, -VKI_ENOMEM);
sewardj2342c972002-05-22 23:34:20 +0000512 return;
513 }
jsgf855d93d2003-10-13 22:26:55 +0000514
515 vg_scss.altstack.ss_sp = ss->ss_sp;
516 vg_scss.altstack.ss_size = ss->ss_size;
517 vg_scss.altstack.ss_flags = 0;
sewardj2342c972002-05-22 23:34:20 +0000518 }
sewardj2342c972002-05-22 23:34:20 +0000519 }
njnd3040452003-05-19 15:04:06 +0000520 SET_SYSCALL_RETVAL(tid, 0);
sewardj2342c972002-05-22 23:34:20 +0000521}
522
523
sewardj018f7622002-05-15 21:13:39 +0000524void VG_(do__NR_sigaction) ( ThreadId tid )
525{
526 Int signo;
527 vki_ksigaction* new_act;
528 vki_ksigaction* old_act;
jsgf855d93d2003-10-13 22:26:55 +0000529
530 vg_assert(is_correct_sigmask());
sewardj018f7622002-05-15 21:13:39 +0000531
532 vg_assert(VG_(is_valid_tid)(tid));
533 signo = VG_(threads)[tid].m_ebx; /* int sigNo */
534 new_act = (vki_ksigaction*)(VG_(threads)[tid].m_ecx);
535 old_act = (vki_ksigaction*)(VG_(threads)[tid].m_edx);
536
537 if (VG_(clo_trace_signals))
538 VG_(message)(Vg_DebugExtraMsg,
539 "__NR_sigaction: tid %d, sigNo %d, "
540 "new 0x%x, old 0x%x, new flags 0x%x",
541 tid, signo, (UInt)new_act, (UInt)old_act,
542 (UInt)(new_act ? new_act->ksa_flags : 0) );
543
544 /* Rule out various error conditions. The aim is to ensure that if
545 when the call is passed to the kernel it will definitely
546 succeed. */
547
548 /* Reject out-of-range signal numbers. */
549 if (signo < 1 || signo > VKI_KNSIG) goto bad_signo;
550
jsgf855d93d2003-10-13 22:26:55 +0000551 /* don't let them use our signals */
552 if ( (signo == VKI_SIGVGINT || signo == VKI_SIGVGKILL)
553 && new_act
554 && !(new_act->ksa_handler == VKI_SIG_DFL || new_act->ksa_handler == VKI_SIG_IGN) )
555 goto bad_signo;
556
sewardj018f7622002-05-15 21:13:39 +0000557 /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
558 if ( (signo == VKI_SIGKILL || signo == VKI_SIGSTOP)
559 && new_act
560 && new_act->ksa_handler != VKI_SIG_DFL)
561 goto bad_sigkill_or_sigstop;
562
563 /* If the client supplied non-NULL old_act, copy the relevant SCSS
564 entry into it. */
565 if (old_act) {
566 old_act->ksa_handler = vg_scss.scss_per_sig[signo].scss_handler;
567 old_act->ksa_flags = vg_scss.scss_per_sig[signo].scss_flags;
568 old_act->ksa_mask = vg_scss.scss_per_sig[signo].scss_mask;
569 old_act->ksa_restorer = vg_scss.scss_per_sig[signo].scss_restorer;
570 }
571
572 /* And now copy new SCSS entry from new_act. */
573 if (new_act) {
574 vg_scss.scss_per_sig[signo].scss_handler = new_act->ksa_handler;
575 vg_scss.scss_per_sig[signo].scss_flags = new_act->ksa_flags;
576 vg_scss.scss_per_sig[signo].scss_mask = new_act->ksa_mask;
577 vg_scss.scss_per_sig[signo].scss_restorer = new_act->ksa_restorer;
578 }
579
580 /* All happy bunnies ... */
581 if (new_act) {
sewardj018f7622002-05-15 21:13:39 +0000582 VG_(handle_SCSS_change)( False /* lazy update */ );
583 }
njnd3040452003-05-19 15:04:06 +0000584 SET_SYSCALL_RETVAL(tid, 0);
sewardj018f7622002-05-15 21:13:39 +0000585 return;
586
587 bad_signo:
sewardj37d06f22003-09-17 21:48:26 +0000588 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1)
njn25e49d8e72002-09-23 09:36:25 +0000589 VG_(message)(Vg_UserMsg,
590 "Warning: bad signal number %d in __NR_sigaction.",
591 signo);
njnd3040452003-05-19 15:04:06 +0000592 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
sewardj018f7622002-05-15 21:13:39 +0000593 return;
594
595 bad_sigkill_or_sigstop:
sewardj37d06f22003-09-17 21:48:26 +0000596 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1)
njn25e49d8e72002-09-23 09:36:25 +0000597 VG_(message)(Vg_UserMsg,
jsgf855d93d2003-10-13 22:26:55 +0000598 "Warning: attempt to set %s handler in __NR_sigaction.",
599 signame(signo));
sewardj018f7622002-05-15 21:13:39 +0000600
njnd3040452003-05-19 15:04:06 +0000601 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
sewardj018f7622002-05-15 21:13:39 +0000602 return;
603}
604
605
606static
607void do_sigprocmask_bitops ( Int vki_how,
608 vki_ksigset_t* orig_set,
609 vki_ksigset_t* modifier )
610{
611 switch (vki_how) {
612 case VKI_SIG_BLOCK:
613 VG_(ksigaddset_from_set)( orig_set, modifier );
614 break;
615 case VKI_SIG_UNBLOCK:
616 VG_(ksigdelset_from_set)( orig_set, modifier );
617 break;
618 case VKI_SIG_SETMASK:
619 *orig_set = *modifier;
620 break;
621 default:
njne427a662002-10-02 11:08:25 +0000622 VG_(core_panic)("do_sigprocmask_bitops");
sewardj018f7622002-05-15 21:13:39 +0000623 break;
624 }
625}
626
jsgf855d93d2003-10-13 22:26:55 +0000627/*
628 This updates the thread's signal mask. There's no such thing as a
629 process-wide signal mask.
sewardj018f7622002-05-15 21:13:39 +0000630
631 Note that the thread signal masks are an implicit part of SCSS,
632 which is why this routine is allowed to mess with them.
633*/
634static
635void do_setmask ( ThreadId tid,
636 Int how,
637 vki_ksigset_t* newset,
638 vki_ksigset_t* oldset )
639{
jsgf855d93d2003-10-13 22:26:55 +0000640 vg_assert(is_correct_sigmask());
sewardj018f7622002-05-15 21:13:39 +0000641
642 if (VG_(clo_trace_signals))
sewardja464e5c2002-05-23 17:34:49 +0000643 VG_(message)(Vg_DebugExtraMsg,
jsgf855d93d2003-10-13 22:26:55 +0000644 "do_setmask: tid = %d how = %d (%s), set = %p %08x%08x",
645 tid, how,
646 how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
647 how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
648 how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
649 newset, newset ? newset->ws[1] : 0, newset ? newset->ws[0] : 0
650 );
sewardj018f7622002-05-15 21:13:39 +0000651
jsgf855d93d2003-10-13 22:26:55 +0000652 /* Just do this thread. */
653 vg_assert(VG_(is_valid_tid)(tid));
654 if (oldset) {
655 *oldset = VG_(threads)[tid].eff_sig_mask;
656 if (VG_(clo_trace_signals))
657 VG_(message)(Vg_DebugExtraMsg,
658 "\toldset=%p %08x%08x",
659 oldset, oldset->ws[1], oldset->ws[0]);
sewardj018f7622002-05-15 21:13:39 +0000660 }
sewardj018f7622002-05-15 21:13:39 +0000661 if (newset) {
jsgf855d93d2003-10-13 22:26:55 +0000662 do_sigprocmask_bitops (how, &VG_(threads)[tid].sig_mask, newset );
663 VG_(ksigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGKILL);
664 VG_(ksigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGSTOP);
665 VG_(proxy_setsigmask)(tid);
sewardj018f7622002-05-15 21:13:39 +0000666 }
jsgf855d93d2003-10-13 22:26:55 +0000667
668 vg_assert(is_correct_sigmask());
sewardj018f7622002-05-15 21:13:39 +0000669}
670
671
672void VG_(do__NR_sigprocmask) ( ThreadId tid,
673 Int how,
674 vki_ksigset_t* set,
675 vki_ksigset_t* oldset )
676{
jsgf855d93d2003-10-13 22:26:55 +0000677 switch(how) {
678 case VKI_SIG_BLOCK:
679 case VKI_SIG_UNBLOCK:
680 case VKI_SIG_SETMASK:
sewardj018f7622002-05-15 21:13:39 +0000681 vg_assert(VG_(is_valid_tid)(tid));
jsgf855d93d2003-10-13 22:26:55 +0000682 /* Syscall returns 0 (success) to its thread. Set this up before
683 calling do_setmask() because we may get a signal as part of
684 setting the mask, which will confuse things.
685 */
njnd3040452003-05-19 15:04:06 +0000686 SET_SYSCALL_RETVAL(tid, 0);
jsgf855d93d2003-10-13 22:26:55 +0000687 do_setmask ( tid, how, set, oldset );
688
689 VG_(route_signals)(); /* if we're routing, do something before returning */
690 break;
691
692 default:
sewardj018f7622002-05-15 21:13:39 +0000693 VG_(message)(Vg_DebugMsg,
694 "sigprocmask: unknown `how' field %d", how);
njnd3040452003-05-19 15:04:06 +0000695 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
jsgf855d93d2003-10-13 22:26:55 +0000696 break;
sewardj018f7622002-05-15 21:13:39 +0000697 }
698}
699
700
701void VG_(do_pthread_sigmask_SCSS_upd) ( ThreadId tid,
702 Int how,
703 vki_ksigset_t* set,
704 vki_ksigset_t* oldset )
705{
706 /* Assume that how has been validated by caller. */
707 vg_assert(how == VKI_SIG_BLOCK || how == VKI_SIG_UNBLOCK
708 || how == VKI_SIG_SETMASK);
709 vg_assert(VG_(is_valid_tid)(tid));
710 do_setmask ( tid, how, set, oldset );
711 /* The request return code is set in do_pthread_sigmask */
712}
713
714
715void VG_(send_signal_to_thread) ( ThreadId thread, Int sig )
716{
jsgf855d93d2003-10-13 22:26:55 +0000717 ThreadState *tst;
718
sewardj018f7622002-05-15 21:13:39 +0000719 vg_assert(VG_(is_valid_tid)(thread));
720 vg_assert(sig >= 1 && sig <= VKI_KNSIG);
721
jsgf855d93d2003-10-13 22:26:55 +0000722 tst = VG_(get_ThreadState)(thread);
723 vg_assert(tst->proxy != NULL);
sewardj018f7622002-05-15 21:13:39 +0000724
jsgf855d93d2003-10-13 22:26:55 +0000725 VG_(proxy_sendsig)(thread, sig);
sewardjefbfcdf2002-06-19 17:35:45 +0000726}
727
728
sewardj018f7622002-05-15 21:13:39 +0000729/* ---------------------------------------------------------------------
730 LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
731 ------------------------------------------------------------------ */
sewardj77e466c2002-04-14 02:29:29 +0000732
sewardj2e93c502002-04-12 11:12:52 +0000733/* ---------------------------------------------------------------------
734 Handy utilities to block/restore all host signals.
735 ------------------------------------------------------------------ */
736
737/* Block all host signals, dumping the old mask in *saved_mask. */
738void VG_(block_all_host_signals) ( /* OUT */ vki_ksigset_t* saved_mask )
739{
740 Int ret;
741 vki_ksigset_t block_procmask;
742 VG_(ksigfillset)(&block_procmask);
743 ret = VG_(ksigprocmask)
744 (VKI_SIG_SETMASK, &block_procmask, saved_mask);
745 vg_assert(ret == 0);
746}
747
748/* Restore the blocking mask using the supplied saved one. */
sewardj018f7622002-05-15 21:13:39 +0000749void VG_(restore_all_host_signals) ( /* IN */ vki_ksigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +0000750{
751 Int ret;
752 ret = VG_(ksigprocmask)(VKI_SIG_SETMASK, saved_mask, NULL);
753 vg_assert(ret == 0);
754}
sewardjde4a1d02002-03-22 01:27:54 +0000755
jsgf855d93d2003-10-13 22:26:55 +0000756/* Sanity check - check the scheduler LWP has all the signals blocked
757 it is supposed to have blocked. */
758static Bool is_correct_sigmask(void)
759{
760 vki_ksigset_t mask;
761 Bool ret = True;
762
763 vg_assert(VG_(gettid)() == VG_(main_pid));
764
765#ifdef DEBUG_SIGNALS
766 VG_(ksigprocmask)(VKI_SIG_SETMASK, NULL, &mask);
767
768 /* unresumable signals */
769
770 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGSEGV);
771 VG_(ksigaddset)(&mask, VKI_SIGSEGV);
772
773 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGBUS);
774 VG_(ksigaddset)(&mask, VKI_SIGBUS);
775
776 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGFPE);
777 VG_(ksigaddset)(&mask, VKI_SIGFPE);
778
779 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGILL);
780 VG_(ksigaddset)(&mask, VKI_SIGILL);
781
782 /* unblockable signals (doesn't really matter if these are
783 already present) */
784 VG_(ksigaddset)(&mask, VKI_SIGSTOP);
785 VG_(ksigaddset)(&mask, VKI_SIGKILL);
786
787 ret = ret && VG_(kisfullsigset)(&mask);
788#endif /* DEBUG_SIGNALS */
789
790 return ret;
791}
792
793/* Set the signal mask for the scheduer LWP; this should be set once
794 and left that way - all async signal handling is done in the proxy
795 LWPs. */
796static void set_main_sigmask(void)
797{
798 vki_ksigset_t mask;
799
800 VG_(ksigfillset)(&mask);
801 VG_(ksigdelset)(&mask, VKI_SIGSEGV);
802 VG_(ksigdelset)(&mask, VKI_SIGBUS);
803 VG_(ksigdelset)(&mask, VKI_SIGFPE);
804 VG_(ksigdelset)(&mask, VKI_SIGILL);
805
806 VG_(ksigprocmask)(VKI_SIG_SETMASK, &mask, NULL);
807
808 vg_assert(is_correct_sigmask());
809}
sewardjde4a1d02002-03-22 01:27:54 +0000810
811/* ---------------------------------------------------------------------
812 The signal simulation proper. A simplified version of what the
813 Linux kernel does.
814 ------------------------------------------------------------------ */
815
816/* A structure in which to save the application's registers
817 during the execution of signal handlers. */
818
819typedef
820 struct {
jsgf855d93d2003-10-13 22:26:55 +0000821 /* There are two different stack frame formats, depending on
822 whether the client set the SA_SIGINFO flag for the handler.
823 This structure is put onto the client's stack as part of
824 signal delivery, and therefore appears as the signal
825 handler's arguments.
826
827 The first two words are common for both frame formats -
828 they're the return address and the signal number. */
sewardjf247eae2002-09-27 00:46:59 +0000829
830 /* Sig handler's (bogus) return address */
831 Addr retaddr;
832 /* The arg to the sig handler. We need to inspect this after
833 the handler returns, but it's unreasonable to assume that the
834 handler won't change it. So we keep a second copy of it in
835 sigNo_private. */
836 Int sigNo;
jsgf855d93d2003-10-13 22:26:55 +0000837
838 /* This is where the two frames start differing. */
839 union {
840 struct { /* set SA_SIGINFO */
841 /* ptr to siginfo_t. */
842 Addr psigInfo;
843
844 /* ptr to ucontext */
845 Addr puContext;
846 } sigInfo;
847 struct vki_sigcontext sigContext; /* did not set SA_SIGINFO */
848 } handlerArgs;
sewardjf247eae2002-09-27 00:46:59 +0000849
850 /* The rest are private fields which the handler is unaware of. */
851
sewardj2e93c502002-04-12 11:12:52 +0000852 /* Sanity check word. */
sewardjde4a1d02002-03-22 01:27:54 +0000853 UInt magicPI;
jsgf855d93d2003-10-13 22:26:55 +0000854 /* pointed to by psigInfo */
855 vki_ksiginfo_t sigInfo;
856 /* pointed to by puContext */
857 struct vki_ucontext uContext;
858
sewardjf247eae2002-09-27 00:46:59 +0000859 /* Safely-saved version of sigNo, as described above. */
860 Int sigNo_private;
sewardj2e93c502002-04-12 11:12:52 +0000861 /* Saved processor state. */
njnd3040452003-05-19 15:04:06 +0000862 UInt m_sse[VG_SIZE_OF_SSESTATE_W];
863
864 UInt m_eax;
865 UInt m_ecx;
866 UInt m_edx;
867 UInt m_ebx;
868 UInt m_ebp;
869 UInt m_esp;
870 UInt m_esi;
871 UInt m_edi;
872 UInt m_eflags;
873 Addr m_eip;
874
875 UInt sh_eax;
876 UInt sh_ebx;
877 UInt sh_ecx;
878 UInt sh_edx;
879 UInt sh_esi;
880 UInt sh_edi;
881 UInt sh_ebp;
882 UInt sh_esp;
883 UInt sh_eflags;
884
jsgf855d93d2003-10-13 22:26:55 +0000885 /* saved signal mask to be restored when handler returns */
886 vki_ksigset_t mask;
887
sewardj2e93c502002-04-12 11:12:52 +0000888 /* Scheduler-private stuff: what was the thread's status prior to
889 delivering this signal? */
890 ThreadStatus status;
891 /* Sanity check word. Is the highest-addressed word; do not
892 move!*/
sewardjde4a1d02002-03-22 01:27:54 +0000893 UInt magicE;
894 }
sewardj2e93c502002-04-12 11:12:52 +0000895 VgSigFrame;
sewardjde4a1d02002-03-22 01:27:54 +0000896
897
jsgf855d93d2003-10-13 22:26:55 +0000898/* Make up a plausible-looking thread state from the thread's current state */
899static void synth_ucontext(ThreadId tid, const vki_ksiginfo_t *si,
900 const vki_ksigset_t *set, struct vki_ucontext *uc)
901{
902 ThreadState *tst = VG_(get_ThreadState)(tid);
903 struct vki_sigcontext *sc = &uc->uc_mcontext;
904
905 VG_(memset)(uc, 0, sizeof(*uc));
906
907 uc->uc_flags = 0;
908 uc->uc_link = 0;
909 uc->uc_sigmask = *set;
910 uc->uc_stack = vg_scss.altstack;
911
912#define SC(reg) sc->reg = tst->m_##reg
913 SC(gs);
914 SC(fs);
915 SC(es);
916 SC(ds);
917
918 SC(edi);
919 SC(esi);
920 SC(ebp);
921 SC(esp);
922 SC(ebx);
923 SC(edx);
924 SC(ecx);
925 SC(eax);
926
927 SC(eip);
928 SC(cs);
929 SC(eflags);
930 SC(ss);
931 /* XXX esp_at_signal */
932 /* XXX trapno */
933 /* XXX err */
934#undef SC
935
936 sc->cr2 = (UInt)si->_sifields._sigfault._addr;
937}
sewardjde4a1d02002-03-22 01:27:54 +0000938
sewardjde4a1d02002-03-22 01:27:54 +0000939/* Set up a stack frame (VgSigContext) for the client's signal
940 handler. This includes the signal number and a bogus return
941 address. */
942static
jsgf855d93d2003-10-13 22:26:55 +0000943void vg_push_signal_frame ( ThreadId tid, const vki_ksiginfo_t *siginfo )
sewardjde4a1d02002-03-22 01:27:54 +0000944{
945 Int i;
sewardj2342c972002-05-22 23:34:20 +0000946 Addr esp, esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +0000947 VgSigFrame* frame;
948 ThreadState* tst;
jsgf855d93d2003-10-13 22:26:55 +0000949 Int sigNo = siginfo->si_signo;
sewardj2e93c502002-04-12 11:12:52 +0000950
sewardj2342c972002-05-22 23:34:20 +0000951 vg_assert(sigNo >= 1 && sigNo <= VKI_KNSIG);
sewardj018f7622002-05-15 21:13:39 +0000952 vg_assert(VG_(is_valid_tid)(tid));
953 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +0000954
jsgf855d93d2003-10-13 22:26:55 +0000955 if (VG_(clo_trace_signals))
956 VG_(message)(Vg_DebugMsg,
957 "vg_push_signal_frame (thread %d): signal %d", tid, sigNo);
958
sewardj2342c972002-05-22 23:34:20 +0000959 if (/* this signal asked to run on an alt stack */
jsgf855d93d2003-10-13 22:26:55 +0000960 (vg_scss.scss_per_sig[sigNo].scss_flags & VKI_SA_ONSTACK )
sewardj2342c972002-05-22 23:34:20 +0000961 && /* there is a defined and enabled alt stack, which we're not
962 already using. Logic from get_sigframe in
963 arch/i386/kernel/signal.c. */
964 sas_ss_flags(tst->m_esp) == 0
965 ) {
966 esp_top_of_frame
967 = (Addr)(vg_scss.altstack.ss_sp) + vg_scss.altstack.ss_size;
968 if (VG_(clo_trace_signals))
969 VG_(message)(Vg_DebugMsg,
jsgf855d93d2003-10-13 22:26:55 +0000970 "delivering signal %d (%s) to thread %d: on ALT STACK",
971 sigNo, signame(sigNo), tid );
njnfdc28af2003-02-24 10:36:48 +0000972
973 /* Signal delivery to skins */
974 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
975
sewardj2342c972002-05-22 23:34:20 +0000976 } else {
977 esp_top_of_frame = tst->m_esp;
njnfdc28af2003-02-24 10:36:48 +0000978
979 /* Signal delivery to skins */
980 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
sewardj2342c972002-05-22 23:34:20 +0000981 }
982
983 esp = esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +0000984 esp -= sizeof(VgSigFrame);
985 frame = (VgSigFrame*)esp;
njn25e49d8e72002-09-23 09:36:25 +0000986
987 /* For tracking memory events, indicate the entire frame has been
988 * allocated, but pretend that only the first four words are written */
989 VG_TRACK( new_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) );
990
sewardj2e93c502002-04-12 11:12:52 +0000991 /* Assert that the frame is placed correctly. */
992 vg_assert( (sizeof(VgSigFrame) & 0x3) == 0 );
993 vg_assert( ((Char*)(&frame->magicE)) + sizeof(UInt)
sewardj2342c972002-05-22 23:34:20 +0000994 == ((Char*)(esp_top_of_frame)) );
sewardj2e93c502002-04-12 11:12:52 +0000995
njn25e49d8e72002-09-23 09:36:25 +0000996 /* retaddr, sigNo, psigInfo, puContext fields are to be written */
njn72718642003-07-24 08:45:32 +0000997 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame",
jsgf855d93d2003-10-13 22:26:55 +0000998 (Addr)frame, offsetof(VgSigFrame, handlerArgs) );
sewardj2e93c502002-04-12 11:12:52 +0000999 frame->retaddr = (UInt)(&VG_(signalreturn_bogusRA));
1000 frame->sigNo = sigNo;
sewardjf247eae2002-09-27 00:46:59 +00001001 frame->sigNo_private = sigNo;
jsgf855d93d2003-10-13 22:26:55 +00001002 VG_TRACK( post_mem_write, (Addr)frame, offsetof(VgSigFrame, handlerArgs) );
1003
1004 if (vg_scss.scss_per_sig[sigNo].scss_flags & VKI_SA_SIGINFO) {
1005 /* if the client asked for a siginfo delivery, then build the stack that way */
1006 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)",
1007 (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
1008 frame->handlerArgs.sigInfo.psigInfo = (Addr)&frame->sigInfo;
1009 frame->handlerArgs.sigInfo.puContext = (Addr)&frame->uContext;
1010 VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
1011
1012 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)",
1013 (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
1014 VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_ksiginfo_t));
1015 VG_TRACK( post_mem_write, (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
1016
1017 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)",
1018 (Addr)&frame->uContext, sizeof(frame->uContext) );
1019 synth_ucontext(tid, siginfo, &vg_scss.scss_per_sig[sigNo].scss_mask, &frame->uContext);
1020 VG_TRACK( post_mem_write, (Addr)&frame->uContext, sizeof(frame->uContext) );
1021 } else {
1022 struct vki_ucontext uc;
1023
1024 /* otherwise just put the sigcontext there */
1025
1026 synth_ucontext(tid, siginfo, &vg_scss.scss_per_sig[sigNo].scss_mask, &uc);
1027
1028 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (sigcontext)",
1029 (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigContext) );
1030 VG_(memcpy)(&frame->handlerArgs.sigContext, &uc.uc_mcontext,
1031 sizeof(struct vki_sigcontext));
1032 VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs,
1033 sizeof(frame->handlerArgs.sigContext) );
1034
1035 frame->handlerArgs.sigContext.oldmask = tst->sig_mask.ws[0];
1036 }
1037
sewardj2e93c502002-04-12 11:12:52 +00001038 frame->magicPI = 0x31415927;
1039
sewardjb91ae7f2003-04-29 23:50:00 +00001040 for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
njnd3040452003-05-19 15:04:06 +00001041 frame->m_sse[i] = tst->m_sse[i];
sewardjde4a1d02002-03-22 01:27:54 +00001042
njnd3040452003-05-19 15:04:06 +00001043 frame->m_eax = tst->m_eax;
1044 frame->m_ecx = tst->m_ecx;
1045 frame->m_edx = tst->m_edx;
1046 frame->m_ebx = tst->m_ebx;
1047 frame->m_ebp = tst->m_ebp;
1048 frame->m_esp = tst->m_esp;
1049 frame->m_esi = tst->m_esi;
1050 frame->m_edi = tst->m_edi;
1051 frame->m_eflags = tst->m_eflags;
1052 frame->m_eip = tst->m_eip;
1053
1054 if (VG_(needs).shadow_regs) {
1055 frame->sh_eax = tst->sh_eax;
1056 frame->sh_ecx = tst->sh_ecx;
1057 frame->sh_edx = tst->sh_edx;
1058 frame->sh_ebx = tst->sh_ebx;
1059 frame->sh_ebp = tst->sh_ebp;
1060 frame->sh_esp = tst->sh_esp;
1061 frame->sh_esi = tst->sh_esi;
1062 frame->sh_edi = tst->sh_edi;
1063 frame->sh_eflags = tst->sh_eflags;
1064 }
sewardjde4a1d02002-03-22 01:27:54 +00001065
jsgf855d93d2003-10-13 22:26:55 +00001066 frame->mask = tst->sig_mask;
1067
1068 /* If the thread is currently blocked in a syscall, we want it to
1069 resume as runnable. */
1070 if (tst->status == VgTs_WaitSys)
1071 frame->status = VgTs_Runnable;
1072 else
1073 frame->status = tst->status;
sewardjde4a1d02002-03-22 01:27:54 +00001074
sewardj2e93c502002-04-12 11:12:52 +00001075 frame->magicE = 0x27182818;
1076
njnd3040452003-05-19 15:04:06 +00001077 /* Ensure 'tid' and 'tst' correspond */
1078 vg_assert(& VG_(threads)[tid] == tst);
sewardj2e93c502002-04-12 11:12:52 +00001079 /* Set the thread so it will next run the handler. */
njnd3040452003-05-19 15:04:06 +00001080 /* tst->m_esp = esp; */
1081 SET_SIGNAL_ESP(tid, esp);
1082
sewardj018f7622002-05-15 21:13:39 +00001083 tst->m_eip = (Addr)vg_scss.scss_per_sig[sigNo].scss_handler;
sewardj2e93c502002-04-12 11:12:52 +00001084 /* This thread needs to be marked runnable, but we leave that the
1085 caller to do. */
sewardjde4a1d02002-03-22 01:27:54 +00001086
jsgf855d93d2003-10-13 22:26:55 +00001087 if (0)
1088 VG_(printf)("pushed signal frame; %%ESP now = %p, next %%EBP = %p, status=%d\n",
1089 esp, tst->m_eip, tst->status);
sewardjde4a1d02002-03-22 01:27:54 +00001090}
1091
sewardjde4a1d02002-03-22 01:27:54 +00001092/* Clear the signal frame created by vg_push_signal_frame, restore the
1093 simulated machine state, and return the signal number that the
1094 frame was for. */
1095static
sewardj2e93c502002-04-12 11:12:52 +00001096Int vg_pop_signal_frame ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +00001097{
sewardj2e93c502002-04-12 11:12:52 +00001098 Addr esp;
sewardjde4a1d02002-03-22 01:27:54 +00001099 Int sigNo, i;
sewardj2e93c502002-04-12 11:12:52 +00001100 VgSigFrame* frame;
1101 ThreadState* tst;
sewardjde4a1d02002-03-22 01:27:54 +00001102
sewardj018f7622002-05-15 21:13:39 +00001103 vg_assert(VG_(is_valid_tid)(tid));
1104 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +00001105
sewardj54cacf02002-04-12 23:24:59 +00001106 /* Correctly reestablish the frame base address. */
sewardj2e93c502002-04-12 11:12:52 +00001107 esp = tst->m_esp;
sewardj54cacf02002-04-12 23:24:59 +00001108 frame = (VgSigFrame*)
1109 (esp -4 /* because the handler's RET pops the RA */
1110 +20 /* because signalreturn_bogusRA pushes 5 words */);
sewardj2e93c502002-04-12 11:12:52 +00001111
1112 vg_assert(frame->magicPI == 0x31415927);
1113 vg_assert(frame->magicE == 0x27182818);
sewardjde4a1d02002-03-22 01:27:54 +00001114 if (VG_(clo_trace_signals))
sewardjb48e5002002-05-13 00:16:03 +00001115 VG_(message)(Vg_DebugMsg,
jsgf855d93d2003-10-13 22:26:55 +00001116 "vg_pop_signal_frame (thread %d): valid magic; EIP=%p", tid, frame->m_eip);
sewardjde4a1d02002-03-22 01:27:54 +00001117
sewardj2342c972002-05-22 23:34:20 +00001118 /* Mark the frame structure as nonaccessible. */
njn25e49d8e72002-09-23 09:36:25 +00001119 VG_TRACK( die_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) );
sewardjde4a1d02002-03-22 01:27:54 +00001120
njnd3040452003-05-19 15:04:06 +00001121 /* restore machine state */
1122 for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
1123 tst->m_sse[i] = frame->m_sse[i];
sewardjf247eae2002-09-27 00:46:59 +00001124
njnd3040452003-05-19 15:04:06 +00001125 tst->m_eax = frame->m_eax;
1126 tst->m_ecx = frame->m_ecx;
1127 tst->m_edx = frame->m_edx;
1128 tst->m_ebx = frame->m_ebx;
1129 tst->m_ebp = frame->m_ebp;
1130 tst->m_esp = frame->m_esp;
1131 tst->m_esi = frame->m_esi;
1132 tst->m_edi = frame->m_edi;
1133 tst->m_eflags = frame->m_eflags;
1134 tst->m_eip = frame->m_eip;
1135
1136 if (VG_(needs).shadow_regs) {
1137 tst->sh_eax = frame->sh_eax;
1138 tst->sh_ecx = frame->sh_ecx;
1139 tst->sh_edx = frame->sh_edx;
1140 tst->sh_ebx = frame->sh_ebx;
1141 tst->sh_ebp = frame->sh_ebp;
1142 tst->sh_esp = frame->sh_esp;
1143 tst->sh_esi = frame->sh_esi;
1144 tst->sh_edi = frame->sh_edi;
1145 tst->sh_eflags = frame->sh_eflags;
1146 }
1147
sewardjf247eae2002-09-27 00:46:59 +00001148 /* don't use the copy exposed to the handler; it might have changed
1149 it. */
1150 sigNo = frame->sigNo_private;
sewardj2e93c502002-04-12 11:12:52 +00001151
1152 /* And restore the thread's status to what it was before the signal
1153 was delivered. */
1154 tst->status = frame->status;
1155
jsgf855d93d2003-10-13 22:26:55 +00001156 tst->sig_mask = frame->mask;
1157 VG_(proxy_setsigmask)(tid);
1158
njnfdc28af2003-02-24 10:36:48 +00001159 /* Notify skins */
1160 VG_TRACK( post_deliver_signal, tid, sigNo );
1161
sewardjde4a1d02002-03-22 01:27:54 +00001162 return sigNo;
1163}
1164
1165
1166/* A handler is returning. Restore the machine state from the stacked
1167 VgSigContext and continue with whatever was going on before the
sewardj77e466c2002-04-14 02:29:29 +00001168 handler ran. Returns the SA_RESTART syscall-restartability-status
1169 of the delivered signal. */
sewardjde4a1d02002-03-22 01:27:54 +00001170
sewardj77e466c2002-04-14 02:29:29 +00001171Bool VG_(signal_returns) ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +00001172{
sewardj2e93c502002-04-12 11:12:52 +00001173 Int sigNo;
sewardjde4a1d02002-03-22 01:27:54 +00001174
sewardj2e93c502002-04-12 11:12:52 +00001175 /* Pop the signal frame and restore tid's status to what it was
1176 before the signal was delivered. */
1177 sigNo = vg_pop_signal_frame(tid);
sewardjde4a1d02002-03-22 01:27:54 +00001178
sewardjb48e5002002-05-13 00:16:03 +00001179 vg_assert(sigNo >= 1 && sigNo <= VKI_KNSIG);
sewardjde4a1d02002-03-22 01:27:54 +00001180
sewardj77e466c2002-04-14 02:29:29 +00001181 /* Scheduler now can resume this thread, or perhaps some other.
1182 Tell the scheduler whether or not any syscall interrupted by
jsgf855d93d2003-10-13 22:26:55 +00001183 this signal should be restarted, if possible, or no. This is
1184 only used for nanosleep; all other blocking syscalls are handled
1185 in VG_(deliver_signal)().
1186 */
sewardj018f7622002-05-15 21:13:39 +00001187 return
1188 (vg_scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART)
1189 ? True
1190 : False;
sewardjde4a1d02002-03-22 01:27:54 +00001191}
1192
jsgf855d93d2003-10-13 22:26:55 +00001193static const Char *signame(Int sigNo)
sewardjde4a1d02002-03-22 01:27:54 +00001194{
jsgf855d93d2003-10-13 22:26:55 +00001195 static Char buf[10];
sewardjb48e5002002-05-13 00:16:03 +00001196
jsgf855d93d2003-10-13 22:26:55 +00001197 switch(sigNo) {
1198#define S(x) case VKI_##x: return #x
1199 S(SIGHUP);
1200 S(SIGINT);
1201 S(SIGQUIT);
1202 S(SIGILL);
1203 S(SIGTRAP);
1204 S(SIGABRT);
1205 S(SIGBUS);
1206 S(SIGFPE);
1207 S(SIGKILL);
1208 S(SIGUSR1);
1209 S(SIGUSR2);
1210 S(SIGSEGV);
1211 S(SIGPIPE);
1212 S(SIGALRM);
1213 S(SIGTERM);
1214 S(SIGSTKFLT);
1215 S(SIGCHLD);
1216 S(SIGCONT);
1217 S(SIGSTOP);
1218 S(SIGTSTP);
1219 S(SIGTTIN);
1220 S(SIGTTOU);
1221 S(SIGURG);
1222 S(SIGXCPU);
1223 S(SIGXFSZ);
1224 S(SIGVTALRM);
1225 S(SIGPROF);
1226 S(SIGWINCH);
1227 S(SIGIO);
1228 S(SIGPWR);
1229 S(SIGUNUSED);
1230#undef S
sewardjde4a1d02002-03-22 01:27:54 +00001231
jsgf855d93d2003-10-13 22:26:55 +00001232 case VKI_SIGRTMIN ... VKI_SIGRTMAX:
1233 VG_(sprintf)(buf, "SIGRT%d", sigNo);
1234 return buf;
sewardjde4a1d02002-03-22 01:27:54 +00001235
jsgf855d93d2003-10-13 22:26:55 +00001236 default:
1237 VG_(sprintf)(buf, "SIG%d", sigNo);
1238 return buf;
1239 }
1240}
sewardjde4a1d02002-03-22 01:27:54 +00001241
jsgf855d93d2003-10-13 22:26:55 +00001242/* Hit ourselves with a signal using the default handler */
1243void VG_(kill_self)(Int sigNo)
1244{
1245 vki_ksigset_t mask, origmask;
1246 vki_ksigaction sa, origsa;
sewardj018f7622002-05-15 21:13:39 +00001247
jsgf855d93d2003-10-13 22:26:55 +00001248 sa.ksa_handler = VKI_SIG_DFL;
1249 sa.ksa_flags = 0;
1250 sa.ksa_restorer = 0;
1251 VG_(ksigemptyset)(&sa.ksa_mask);
sewardj2e93c502002-04-12 11:12:52 +00001252
jsgf855d93d2003-10-13 22:26:55 +00001253 VG_(ksigaction)(sigNo, &sa, &origsa);
sewardj018f7622002-05-15 21:13:39 +00001254
jsgf855d93d2003-10-13 22:26:55 +00001255 VG_(ksigfillset)(&mask);
1256 VG_(ksigdelset)(&mask, sigNo);
1257 VG_(ksigprocmask)(VKI_SIG_SETMASK, &mask, &origmask);
1258
1259 VG_(ktkill)(VG_(getpid)(), sigNo);
1260
1261 VG_(ksigaction)(sigNo, &origsa, NULL);
1262 VG_(ksigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
1263}
1264
1265/*
1266 Perform the default action of a signal. Returns if the default
1267 action isn't fatal.
1268
1269 If we're not being quiet, then print out some more detail about
1270 fatal signals (esp. core dumping signals).
1271 */
1272static void vg_default_action(const vki_ksiginfo_t *info, ThreadId tid)
1273{
1274 Int sigNo = info->si_signo;
1275 Bool terminate = False;
1276 Bool core = False;
1277
1278 switch(sigNo) {
1279 case VKI_SIGQUIT: /* core */
1280 case VKI_SIGILL: /* core */
1281 case VKI_SIGABRT: /* core */
1282 case VKI_SIGFPE: /* core */
1283 case VKI_SIGSEGV: /* core */
1284 case VKI_SIGBUS: /* core */
1285 case VKI_SIGTRAP: /* core */
1286 case VKI_SIGXCPU: /* core */
1287 case VKI_SIGXFSZ: /* core */
1288 terminate = True;
1289 core = True;
1290 break;
1291
1292 case VKI_SIGHUP: /* term */
1293 case VKI_SIGINT: /* term */
1294 case VKI_SIGKILL: /* term - we won't see this */
1295 case VKI_SIGPIPE: /* term */
1296 case VKI_SIGALRM: /* term */
1297 case VKI_SIGTERM: /* term */
1298 case VKI_SIGUSR1: /* term */
1299 case VKI_SIGUSR2: /* term */
1300 case VKI_SIGIO: /* term */
1301 case VKI_SIGPWR: /* term */
1302 case VKI_SIGSYS: /* term */
1303 case VKI_SIGPROF: /* term */
1304 case VKI_SIGVTALRM: /* term */
1305 case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
1306 terminate = True;
1307 break;
1308 }
1309
1310 vg_assert(!core || (core && terminate));
1311
1312 if (terminate) {
1313 if (VG_(clo_verbosity) != 0 && (core || VG_(clo_verbosity) > 1)) {
1314 VG_(message)(Vg_UserMsg, "");
1315 VG_(message)(Vg_UserMsg, "Process terminating with default action of signal %d (%s)%s",
1316 sigNo, signame(sigNo), core ? ": dumping core" : "");
1317
1318 /* Be helpful - decode some more details about this fault */
1319 if (info->si_code > VKI_SI_USER) {
1320 const Char *event = NULL;
1321
1322 switch(sigNo) {
1323 case VKI_SIGSEGV:
1324 switch(info->si_code) {
nethercote3b390c72003-11-13 17:53:43 +00001325 case 1: event = "Address not mapped to object"; break;
1326 case 2: event = "Invalid permissions for mapped object"; break;
jsgf855d93d2003-10-13 22:26:55 +00001327 }
1328 break;
1329
1330 case VKI_SIGILL:
1331 switch(info->si_code) {
nethercote3b390c72003-11-13 17:53:43 +00001332 case 1: event = "Illegal opcode"; break;
1333 case 2: event = "Illegal operand"; break;
1334 case 3: event = "Illegal addressing mode"; break;
1335 case 4: event = "Illegal trap"; break;
1336 case 5: event = "Privileged opcode"; break;
1337 case 6: event = "Privileged register"; break;
1338 case 7: event = "Coprocessor error"; break;
1339 case 8: event = "Internal stack error"; break;
jsgf855d93d2003-10-13 22:26:55 +00001340 }
1341 break;
1342
1343 case VKI_SIGFPE:
1344 switch (info->si_code) {
nethercote3b390c72003-11-13 17:53:43 +00001345 case 1: event = "Integer divide by zero"; break;
1346 case 2: event = "Integer overflow"; break;
jsgf855d93d2003-10-13 22:26:55 +00001347 case 3: event = "FP divide by zero"; break;
1348 case 4: event = "FP overflow"; break;
1349 case 5: event = "FP underflow"; break;
1350 case 6: event = "FP inexact"; break;
1351 case 7: event = "FP invalid operation"; break;
1352 case 8: event = "FP subscript out of range"; break;
1353 }
1354 break;
1355
1356 case VKI_SIGBUS:
1357 switch (info->si_code) {
nethercote3b390c72003-11-13 17:53:43 +00001358 case 1: event = "Invalid address alignment"; break;
1359 case 2: event = "Non-existent physical address"; break;
1360 case 3: event = "Hardware error"; break;
jsgf855d93d2003-10-13 22:26:55 +00001361 }
1362 break;
1363 }
1364
1365 if (event != NULL)
nethercote3b390c72003-11-13 17:53:43 +00001366 VG_(message)(Vg_UserMsg, " %s at address %p",
jsgf855d93d2003-10-13 22:26:55 +00001367 event, info->_sifields._sigfault._addr);
1368 }
1369
1370 if (tid != VG_INVALID_THREADID) {
1371 ExeContext *ec = VG_(get_ExeContext)(tid);
1372 VG_(pp_ExeContext)(ec);
1373 }
1374 }
1375
1376 if (VG_(fatal_signal_set)) {
1377 VG_(fatal_sigNo) = sigNo;
1378 __builtin_longjmp(VG_(fatal_signal_jmpbuf), 1);
sewardj018f7622002-05-15 21:13:39 +00001379 }
sewardjde4a1d02002-03-22 01:27:54 +00001380 }
1381
jsgf855d93d2003-10-13 22:26:55 +00001382 VG_(kill_self)(sigNo);
sewardj018f7622002-05-15 21:13:39 +00001383
jsgf855d93d2003-10-13 22:26:55 +00001384 vg_assert(!terminate);
sewardjb48e5002002-05-13 00:16:03 +00001385}
1386
1387
jsgf855d93d2003-10-13 22:26:55 +00001388void VG_(deliver_signal) ( ThreadId tid, const vki_ksiginfo_t *info, Bool async )
sewardjde4a1d02002-03-22 01:27:54 +00001389{
jsgf855d93d2003-10-13 22:26:55 +00001390 Int sigNo = info->si_signo;
1391 vki_ksigset_t handlermask;
jsgf855d93d2003-10-13 22:26:55 +00001392 SCSS_Per_Signal *handler = &vg_scss.scss_per_sig[sigNo];
1393 ThreadState *tst = VG_(get_ThreadState)(tid);
1394
1395 if (VG_(clo_trace_signals))
1396 VG_(message)(Vg_DebugMsg,"delivering signal %d (%s) to thread %d",
1397 sigNo, signame(sigNo), tid );
1398
1399 if (sigNo == VKI_SIGVGINT) {
1400 /* If this is a SIGVGINT, then we just ACK the signal and carry
1401 on; the application need never know about it (except for any
1402 effect on its syscalls). */
1403 vg_assert(async);
1404
1405 if (tst->status == VgTs_WaitSys) {
1406 /* blocked in a syscall; we assume it should be interrupted */
1407 if (tst->m_eax == -VKI_ERESTARTSYS)
1408 tst->m_eax = -VKI_EINTR;
1409 }
1410
1411 VG_(proxy_sigack)(tid, &tst->sig_mask);
1412 return;
1413 }
1414
1415 /* If thread is currently blocked in a syscall, then resume as
1416 runnable. If the syscall needs restarting, tweak the machine
1417 state to make it happen. */
1418 if (tst->status == VgTs_WaitSys) {
1419 vg_assert(tst->syscallno != -1);
1420
fitzhardingea09a1b52003-11-07 23:09:48 +00001421 /* OK, the thread was waiting for a syscall to complete. This
1422 means that the proxy has either not yet processed the
1423 RunSyscall request, or was processing it when the signal
1424 came. Either way, it is going to give us some syscall
1425 results right now, so wait for them to appear. This makes
1426 the thread runnable again, so we're in the right state to run
1427 the handler, and resume the syscall when we're done. */
1428 VG_(proxy_wait_sys)(tid);
1429
jsgf855d93d2003-10-13 22:26:55 +00001430 if (0)
1431 VG_(printf)("signal %d interrupting syscall %d\n",
1432 sigNo, tst->syscallno);
1433
1434 if (tst->m_eax == -VKI_ERESTARTSYS) {
1435 if (handler->scss_flags & VKI_SA_RESTART) {
fitzhardingee1c06d82003-10-30 07:21:44 +00001436 VG_(restart_syscall)(tid);
jsgf855d93d2003-10-13 22:26:55 +00001437 } else
1438 tst->m_eax = -VKI_EINTR;
1439 } else {
1440 /* return value is already in eax - either EINTR or the
1441 normal return value */
1442 }
1443 }
1444
1445 vg_assert(handler->scss_handler != VKI_SIG_IGN);
1446
1447 if (sigNo == VKI_SIGCHLD && (handler->scss_flags & VKI_SA_NOCLDWAIT)) {
1448 //VG_(printf)("sigNo==SIGCHLD and app asked for NOCLDWAIT\n");
1449 vg_babyeater(sigNo, NULL, NULL);
1450 }
1451
1452 if (handler->scss_handler == VKI_SIG_DFL) {
1453 handlermask = tst->sig_mask; /* no change to signal mask */
1454 vg_default_action(info, tid);
1455 } else {
1456 /* Create a signal delivery frame, and set the client's %ESP and
1457 %EIP so that when execution continues, we will enter the
1458 signal handler with the frame on top of the client's stack,
1459 as it expects. */
1460 vg_assert(VG_(is_valid_tid)(tid));
1461 vg_push_signal_frame ( tid, info );
1462
1463 if (handler->scss_flags & VKI_SA_ONESHOT) {
1464 /* Do the ONESHOT thing. */
1465 handler->scss_handler = VKI_SIG_DFL;
1466
1467 VG_(handle_SCSS_change)( False /* lazy update */ );
1468 }
1469
fitzhardingea09a1b52003-11-07 23:09:48 +00001470 switch(tst->status) {
jsgf855d93d2003-10-13 22:26:55 +00001471 case VgTs_Runnable:
1472 break;
1473
1474 case VgTs_WaitSys:
jsgf855d93d2003-10-13 22:26:55 +00001475 case VgTs_WaitJoiner:
1476 case VgTs_WaitJoinee:
1477 case VgTs_WaitMX:
1478 case VgTs_WaitCV:
1479 case VgTs_Sleeping:
fitzhardingea09a1b52003-11-07 23:09:48 +00001480 tst->status = VgTs_Runnable;
jsgf855d93d2003-10-13 22:26:55 +00001481 break;
1482
1483 case VgTs_Empty:
1484 VG_(core_panic)("unexpected thread state");
1485 break;
1486 }
1487
jsgf855d93d2003-10-13 22:26:55 +00001488 /* handler gets the union of the signal's mask and the thread's
1489 mask */
1490 handlermask = handler->scss_mask;
1491 VG_(ksigaddset_from_set)(&handlermask, &VG_(threads)[tid].sig_mask);
1492
1493 /* also mask this signal, unless they ask us not to */
1494 if (!(handler->scss_flags & VKI_SA_NOMASK))
1495 VG_(ksigaddset)(&handlermask, sigNo);
1496 }
1497
1498 /* tell proxy we're about to start running the handler */
1499 if (async)
1500 VG_(proxy_sigack)(tid, &handlermask);
1501}
1502
1503
1504/*
1505 If the client set the handler for SIGCHLD to SIG_IGN, then we need
1506 to automatically dezombie any dead children. Also used if the
1507 client set the SA_NOCLDWAIT on their SIGCHLD handler.
1508 */
1509static
1510void vg_babyeater ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext *uc )
1511{
1512 Int status;
1513 Int pid;
1514
1515 vg_assert(sigNo == VKI_SIGCHLD);
1516
1517 while((pid = VG_(waitpid)(-1, &status, VKI_WNOHANG)) > 0) {
1518 if (VG_(clo_trace_signals))
1519 VG_(message)(Vg_DebugMsg, "babyeater reaped %d", pid);
1520 }
1521}
1522
1523/*
1524 Receive an async signal from the host.
1525
1526 It being called in the context of a proxy LWP, and therefore is an
1527 async signal aimed at one of our threads. In this case, we pass
1528 the signal info to the main thread with VG_(proxy_handlesig)().
1529
1530 This should *never* be in the context of the main LWP, because
1531 all signals for which this is the handler should be blocked there.
1532*/
1533static
1534void vg_async_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext *uc )
1535{
1536 if (VG_(gettid)() == VG_(main_pid)) {
1537 VG_(printf)("got signal %d in LWP %d (%d)\n",
1538 sigNo, VG_(gettid)(), VG_(gettid)(), VG_(main_pid));
1539 vg_assert(VG_(ksigismember)(&uc->uc_sigmask, sigNo));
1540 }
1541
1542 vg_assert(VG_(gettid)() != VG_(main_pid));
1543
1544 VG_(proxy_handlesig)(info, &uc->uc_mcontext);
1545}
1546
1547/*
1548 Recieve a sync signal from the host.
1549
1550 This should always be called from the main thread, though it may be
1551 called in a proxy LWP if someone sends an async version of one of
1552 the sync signals.
1553*/
1554static
1555void vg_sync_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext *uc )
1556{
sewardj2e93c502002-04-12 11:12:52 +00001557 Int dummy_local;
jsgf855d93d2003-10-13 22:26:55 +00001558
1559 vg_assert(info != NULL);
1560 vg_assert(info->si_signo == sigNo);
1561 vg_assert(sigNo == VKI_SIGSEGV ||
1562 sigNo == VKI_SIGBUS ||
1563 sigNo == VKI_SIGFPE ||
1564 sigNo == VKI_SIGILL);
1565
1566 if (VG_(gettid)() != VG_(main_pid)) {
1567 /* We were sent one of our sync signals in an async way (or the
1568 proxy LWP code has a bug) */
1569 vg_assert(info->si_code <= VKI_SI_USER);
1570
1571 VG_(proxy_handlesig)(info, &uc->uc_mcontext);
1572 return;
1573 }
1574
sewardjde4a1d02002-03-22 01:27:54 +00001575
sewardj7a61d912002-04-25 01:27:35 +00001576 /*
1577 if (sigNo == VKI_SIGUSR1) {
1578 VG_(printf)("YOWZA! SIGUSR1\n\n");
1579 VG_(clo_trace_pthread_level) = 2;
1580 VG_(clo_trace_sched) = True;
1581 VG_(clo_trace_syscalls) = True;
1582 VG_(clo_trace_signals) = True;
1583 return;
1584 }
1585 */
1586
sewardjde4a1d02002-03-22 01:27:54 +00001587 if (VG_(clo_trace_signals)) {
1588 VG_(start_msg)(Vg_DebugMsg);
1589 VG_(add_to_msg)("signal %d arrived ... ", sigNo );
1590 }
sewardjb48e5002002-05-13 00:16:03 +00001591 vg_assert(sigNo >= 1 && sigNo <= VKI_KNSIG);
sewardjde4a1d02002-03-22 01:27:54 +00001592
1593 /* Sanity check. Ensure we're really running on the signal stack
1594 we asked for. */
njn6eba4ef2003-05-01 08:06:41 +00001595 if (!(
1596 ((Char*)(&(VG_(sigstack)[0])) <= (Char*)(&dummy_local))
1597 &&
1598 ((Char*)(&dummy_local) < (Char*)(&(VG_(sigstack)[VG_SIGSTACK_SIZE_W])))
sewardjde4a1d02002-03-22 01:27:54 +00001599 )
njn6eba4ef2003-05-01 08:06:41 +00001600 ) {
sewardj2e93c502002-04-12 11:12:52 +00001601 VG_(message)(Vg_DebugMsg,
1602 "FATAL: signal delivered on the wrong stack?!");
1603 VG_(message)(Vg_DebugMsg,
1604 "A possible workaround follows. Please tell me");
1605 VG_(message)(Vg_DebugMsg,
1606 "(jseward@acm.org) if the suggested workaround doesn't help.");
sewardjde4a1d02002-03-22 01:27:54 +00001607 VG_(unimplemented)
sewardj2e93c502002-04-12 11:12:52 +00001608 ("support for progs compiled with -p/-pg; "
1609 "rebuild your prog without -p/-pg");
sewardjde4a1d02002-03-22 01:27:54 +00001610 }
1611
sewardj2e93c502002-04-12 11:12:52 +00001612 vg_assert((Char*)(&(VG_(sigstack)[0])) <= (Char*)(&dummy_local));
njn6eba4ef2003-05-01 08:06:41 +00001613 vg_assert((Char*)(&dummy_local) < (Char*)(&(VG_(sigstack)[VG_SIGSTACK_SIZE_W])));
sewardjde4a1d02002-03-22 01:27:54 +00001614
jsgf855d93d2003-10-13 22:26:55 +00001615 if (VG_(scheduler_jmpbuf_valid)) {
sewardj2e93c502002-04-12 11:12:52 +00001616 /* Can't continue; must longjmp back to the scheduler and thus
1617 enter the sighandler immediately. */
jsgf855d93d2003-10-13 22:26:55 +00001618 VG_(memcpy)(&VG_(unresumable_siginfo), info, sizeof(vki_ksiginfo_t));
1619
sewardjde4a1d02002-03-22 01:27:54 +00001620 VG_(longjmpd_on_signal) = sigNo;
sewardj2e93c502002-04-12 11:12:52 +00001621 __builtin_longjmp(VG_(scheduler_jmpbuf),1);
sewardjde4a1d02002-03-22 01:27:54 +00001622 }
sewardj872051c2002-07-13 12:12:56 +00001623
jsgf855d93d2003-10-13 22:26:55 +00001624 if (info->si_code <= VKI_SI_USER) {
1625 /*
1626 OK, one of sync signals was sent from user-mode, so try to
fitzhardingee1c06d82003-10-30 07:21:44 +00001627 deliver it to someone who cares. Just add it to the
1628 process-wide pending signal set - signal routing will deliver
1629 it to someone eventually.
jsgf855d93d2003-10-13 22:26:55 +00001630
fitzhardingee1c06d82003-10-30 07:21:44 +00001631 The only other place which touches proc_pending is
1632 VG_(route_signals), and it has signals blocked while doing
1633 so, so there's no race.
1634 */
1635 VG_(message)(Vg_DebugMsg,
1636 "adding signal %d to pending set", sigNo);
1637 VG_(ksigaddset)(&proc_pending, sigNo);
jsgf855d93d2003-10-13 22:26:55 +00001638 } else {
1639 /*
1640 A bad signal came from the kernel (indicating an instruction
1641 generated it), but there was no jumpbuf set up. This means
1642 it was actually generated by Valgrind internally.
1643 */
1644 struct vki_sigcontext *sc = &uc->uc_mcontext;
1645
1646 VG_(message)(Vg_DebugMsg,
1647 "INTERNAL ERROR: Valgrind received a signal %d (%s) - exiting",
1648 sigNo, signame(sigNo));
1649 VG_(message)(Vg_DebugMsg,
1650 "si_code=%x Fault EIP: %p; Faulting address: %p",
1651 info->si_code, sc->eip, info->_sifields._sigfault._addr);
1652
1653 if (0)
1654 VG_(kill_self)(sigNo); /* generate a core dump */
1655 VG_(core_panic)("Killed by fatal signal");
1656 }
1657}
1658
1659
1660/*
1661 This signal handler exists only so that the scheduler thread can
1662 poke the LWP to make it fall out of whatever syscall it is in.
1663 Used for thread termination and cancellation.
1664 */
1665static void proxy_sigvg_handler(int signo, vki_ksiginfo_t *si, struct vki_ucontext *uc)
1666{
1667 vg_assert(signo == VKI_SIGVGINT || signo == VKI_SIGVGKILL);
1668 vg_assert(si->si_signo == signo);
1669
1670 /* only pay attention to it if it came from the scheduler */
1671 if (si->si_code == VKI_SI_TKILL &&
1672 si->_sifields._kill._pid == VG_(main_pid)) {
1673 vg_assert(si->si_code == VKI_SI_TKILL);
1674 vg_assert(si->_sifields._kill._pid == VG_(main_pid));
1675
1676 VG_(proxy_handlesig)(si, &uc->uc_mcontext);
sewardj872051c2002-07-13 12:12:56 +00001677 }
sewardjde4a1d02002-03-22 01:27:54 +00001678}
1679
1680
1681/* The outer insn loop calls here to reenable a host signal if
1682 vg_oursighandler longjmp'd.
1683*/
1684void VG_(unblock_host_signal) ( Int sigNo )
1685{
jsgf855d93d2003-10-13 22:26:55 +00001686 vg_assert(sigNo == VKI_SIGSEGV ||
1687 sigNo == VKI_SIGBUS ||
1688 sigNo == VKI_SIGILL ||
1689 sigNo == VKI_SIGFPE);
1690 set_main_sigmask();
sewardjde4a1d02002-03-22 01:27:54 +00001691}
1692
1693
1694static __attribute((unused))
1695void pp_vg_ksigaction ( vki_ksigaction* sa )
1696{
1697 Int i;
1698 VG_(printf)("vg_ksigaction: handler %p, flags 0x%x, restorer %p\n",
sewardj9a199dc2002-04-14 13:01:38 +00001699 sa->ksa_handler, (UInt)sa->ksa_flags, sa->ksa_restorer);
sewardjde4a1d02002-03-22 01:27:54 +00001700 VG_(printf)("vg_ksigaction: { ");
sewardjb48e5002002-05-13 00:16:03 +00001701 for (i = 1; i <= VKI_KNSIG; i++)
sewardjde4a1d02002-03-22 01:27:54 +00001702 if (VG_(ksigismember(&(sa->ksa_mask),i)))
1703 VG_(printf)("%d ", i);
1704 VG_(printf)("}\n");
1705}
1706
jsgf855d93d2003-10-13 22:26:55 +00001707/*
1708 In pre-2.6 kernels, the kernel didn't distribute signals to threads
1709 in a thread-group properly, so we need to do it here.
1710 */
1711void VG_(route_signals)(void)
1712{
1713 static const struct vki_timespec zero = { 0, 0 };
1714 static ThreadId start_tid = 1; /* tid to start scanning from */
1715 vki_ksigset_t set;
jsgf855d93d2003-10-13 22:26:55 +00001716 vki_ksiginfo_t si;
1717 Int sigNo;
1718
1719 vg_assert(VG_(gettid)() == VG_(main_pid));
1720 vg_assert(is_correct_sigmask());
1721
1722 if (!VG_(do_signal_routing))
1723 return;
1724
jsgf855d93d2003-10-13 22:26:55 +00001725 /* get the scheduler LWP's signal mask, and use it as the set of
fitzhardingee1c06d82003-10-30 07:21:44 +00001726 signals we're polling for - also block all signals to prevent
1727 races */
1728 VG_(block_all_host_signals) ( &set );
jsgf855d93d2003-10-13 22:26:55 +00001729
fitzhardingee1c06d82003-10-30 07:21:44 +00001730 /* grab any pending signals and add them to the pending signal set */
1731 while(VG_(ksigtimedwait)(&set, &si, &zero) > 0)
1732 VG_(ksigaddset)(&proc_pending, si.si_signo);
1733
1734 /* transfer signals from the process pending set to a particular
1735 thread which has it unblocked */
1736 for(sigNo = 0; sigNo < VKI_KNSIG; sigNo++) {
jsgf855d93d2003-10-13 22:26:55 +00001737 ThreadId tid;
1738 ThreadId end_tid;
1739 Int target = -1;
1740
fitzhardingee1c06d82003-10-30 07:21:44 +00001741 if (!VG_(ksigismember)(&proc_pending, sigNo))
1742 continue;
1743
jsgf855d93d2003-10-13 22:26:55 +00001744 end_tid = start_tid - 1;
1745 if (end_tid < 0 || end_tid >= VG_N_THREADS)
1746 end_tid = VG_N_THREADS-1;
1747
jsgf855d93d2003-10-13 22:26:55 +00001748 /* look for a suitable thread to deliver it to */
1749 for(tid = start_tid;
1750 tid != end_tid;
1751 tid = (tid + 1) % VG_N_THREADS) {
1752 ThreadState *tst = &VG_(threads)[tid];
1753
1754 if (tst->status == VgTs_Empty)
1755 continue;
1756
1757 if (!VG_(ksigismember)(&tst->sig_mask, sigNo)) {
1758 vg_assert(tst->proxy != NULL);
1759 target = tid;
1760 start_tid = tid;
1761 break;
1762 }
1763 }
1764
fitzhardingee1c06d82003-10-30 07:21:44 +00001765 /* found one - deliver it and be done */
jsgf855d93d2003-10-13 22:26:55 +00001766 if (target != -1) {
1767 if (VG_(clo_trace_signals))
1768 VG_(message)(Vg_DebugMsg, "Routing signal %d to tid %d",
1769 sigNo, tid);
fitzhardingee1c06d82003-10-30 07:21:44 +00001770 VG_(proxy_sendsig)(target, sigNo);
1771 VG_(ksigdelset)(&proc_pending, sigNo);
jsgf855d93d2003-10-13 22:26:55 +00001772 }
1773 }
1774
fitzhardingee1c06d82003-10-30 07:21:44 +00001775 /* restore signal mask */
1776 VG_(restore_all_host_signals) (&set);
jsgf855d93d2003-10-13 22:26:55 +00001777}
sewardjde4a1d02002-03-22 01:27:54 +00001778
sewardj018f7622002-05-15 21:13:39 +00001779/* At startup, copy the process' real signal state to the SCSS.
1780 Whilst doing this, block all real signals. Then calculate SKSS and
1781 set the kernel to that. Also initialise DCSS.
sewardjde4a1d02002-03-22 01:27:54 +00001782*/
1783void VG_(sigstartup_actions) ( void )
1784{
1785 Int i, ret;
sewardjde4a1d02002-03-22 01:27:54 +00001786 vki_ksigset_t saved_procmask;
1787 vki_kstack_t altstack_info;
1788 vki_ksigaction sa;
1789
sewardj2e93c502002-04-12 11:12:52 +00001790 /* VG_(printf)("SIGSTARTUP\n"); */
jsgf855d93d2003-10-13 22:26:55 +00001791 /* Block all signals. saved_procmask remembers the previous mask,
1792 which the first thread inherits.
1793 */
sewardj2e93c502002-04-12 11:12:52 +00001794 VG_(block_all_host_signals)( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00001795
fitzhardingee1c06d82003-10-30 07:21:44 +00001796 /* clear process-wide pending signal set */
1797 VG_(ksigemptyset)(&proc_pending);
1798
jsgf855d93d2003-10-13 22:26:55 +00001799 /* Set the signal mask which the scheduler LWP should maintain from
1800 now on. */
1801 set_main_sigmask();
1802
sewardj018f7622002-05-15 21:13:39 +00001803 /* Copy per-signal settings to SCSS. */
1804 for (i = 1; i <= VKI_KNSIG; i++) {
1805
1806 /* Get the old host action */
1807 ret = VG_(ksigaction)(i, NULL, &sa);
1808 vg_assert(ret == 0);
1809
1810 if (VG_(clo_trace_signals))
1811 VG_(printf)("snaffling handler 0x%x for signal %d\n",
1812 (Addr)(sa.ksa_handler), i );
1813
1814 vg_scss.scss_per_sig[i].scss_handler = sa.ksa_handler;
1815 vg_scss.scss_per_sig[i].scss_flags = sa.ksa_flags;
1816 vg_scss.scss_per_sig[i].scss_mask = sa.ksa_mask;
1817 vg_scss.scss_per_sig[i].scss_restorer = sa.ksa_restorer;
1818 }
1819
jsgf855d93d2003-10-13 22:26:55 +00001820 /* Our private internal signals are treated as ignored */
1821 vg_scss.scss_per_sig[VKI_SIGVGINT].scss_handler = VKI_SIG_IGN;
1822 vg_scss.scss_per_sig[VKI_SIGVGINT].scss_flags = VKI_SA_SIGINFO;
1823 VG_(ksigfillset)(&vg_scss.scss_per_sig[VKI_SIGVGINT].scss_mask);
1824 vg_scss.scss_per_sig[VKI_SIGVGKILL].scss_handler = VKI_SIG_IGN;
1825 vg_scss.scss_per_sig[VKI_SIGVGKILL].scss_flags = VKI_SA_SIGINFO;
1826 VG_(ksigfillset)(&vg_scss.scss_per_sig[VKI_SIGVGKILL].scss_mask);
1827
sewardj2342c972002-05-22 23:34:20 +00001828 /* Copy the alt stack, if any. */
1829 ret = VG_(ksigaltstack)(NULL, &vg_scss.altstack);
1830 vg_assert(ret == 0);
1831
sewardj018f7622002-05-15 21:13:39 +00001832 /* Copy the process' signal mask into the root thread. */
1833 vg_assert(VG_(threads)[1].status == VgTs_Runnable);
1834 VG_(threads)[1].sig_mask = saved_procmask;
jsgf855d93d2003-10-13 22:26:55 +00001835 VG_(proxy_setsigmask)(1);
sewardj018f7622002-05-15 21:13:39 +00001836
njn12a57142003-04-30 20:49:10 +00001837 /* Register an alternative stack for our own signal handler to run on. */
sewardjde4a1d02002-03-22 01:27:54 +00001838 altstack_info.ss_sp = &(VG_(sigstack)[0]);
njn6eba4ef2003-05-01 08:06:41 +00001839 altstack_info.ss_size = VG_SIGSTACK_SIZE_W * sizeof(UInt);
sewardjde4a1d02002-03-22 01:27:54 +00001840 altstack_info.ss_flags = 0;
1841 ret = VG_(ksigaltstack)(&altstack_info, NULL);
1842 if (ret != 0) {
njne427a662002-10-02 11:08:25 +00001843 VG_(core_panic)(
sewardjde4a1d02002-03-22 01:27:54 +00001844 "vg_sigstartup_actions: couldn't install alternative sigstack");
1845 }
1846 if (VG_(clo_trace_signals)) {
1847 VG_(message)(Vg_DebugExtraMsg,
1848 "vg_sigstartup_actions: sigstack installed ok");
1849 }
1850
sewardj7a61d912002-04-25 01:27:35 +00001851 /* DEBUGGING HACK */
1852 /* VG_(ksignal)(VKI_SIGUSR1, &VG_(oursignalhandler)); */
1853
sewardj018f7622002-05-15 21:13:39 +00001854 /* Calculate SKSS and apply it. This also sets the initial kernel
1855 mask we need to run with. */
1856 VG_(handle_SCSS_change)( True /* forced update */ );
jsgf855d93d2003-10-13 22:26:55 +00001857
sewardjde4a1d02002-03-22 01:27:54 +00001858}
1859
1860
1861/* Copy the process' sim signal state to the real state,
1862 for when we transfer from the simulated to real CPU.
1863 PROBLEM: what if we're running a signal handler when we
1864 get here? Hmm.
1865 I guess we wind up in vg_signalreturn_bogusRA, *or* the
1866 handler has done/will do a longjmp, in which case we're ok.
sewardjde4a1d02002-03-22 01:27:54 +00001867*/
1868void VG_(sigshutdown_actions) ( void )
1869{
1870 Int i, ret;
1871
sewardjde4a1d02002-03-22 01:27:54 +00001872 vki_ksigset_t saved_procmask;
1873 vki_ksigaction sa;
1874
sewardj2e93c502002-04-12 11:12:52 +00001875 VG_(block_all_host_signals)( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00001876
sewardj018f7622002-05-15 21:13:39 +00001877 /* Copy per-signal settings from SCSS. */
sewardjb48e5002002-05-13 00:16:03 +00001878 for (i = 1; i <= VKI_KNSIG; i++) {
sewardj018f7622002-05-15 21:13:39 +00001879
1880 sa.ksa_handler = vg_scss.scss_per_sig[i].scss_handler;
1881 sa.ksa_flags = vg_scss.scss_per_sig[i].scss_flags;
1882 sa.ksa_mask = vg_scss.scss_per_sig[i].scss_mask;
1883 sa.ksa_restorer = vg_scss.scss_per_sig[i].scss_restorer;
1884
1885 if (VG_(clo_trace_signals))
1886 VG_(printf)("restoring handler 0x%x for signal %d\n",
1887 (Addr)(sa.ksa_handler), i );
1888
sewardje8fb72e2002-06-28 02:08:28 +00001889 /* Set the old host action */
sewardj018f7622002-05-15 21:13:39 +00001890 ret = VG_(ksigaction)(i, &sa, NULL);
sewardje8fb72e2002-06-28 02:08:28 +00001891 if (i != VKI_SIGKILL && i != VKI_SIGSTOP)
1892 vg_assert(ret == 0);
sewardjde4a1d02002-03-22 01:27:54 +00001893 }
1894
sewardj2342c972002-05-22 23:34:20 +00001895 /* Restore the sig alt stack. */
1896 ret = VG_(ksigaltstack)(&vg_scss.altstack, NULL);
1897 vg_assert(ret == 0);
1898
sewardj018f7622002-05-15 21:13:39 +00001899 /* A bit of a kludge -- set the sigmask to that of the root
1900 thread. */
1901 vg_assert(VG_(threads)[1].status != VgTs_Empty);
1902 VG_(restore_all_host_signals)( &VG_(threads)[1].sig_mask );
sewardjde4a1d02002-03-22 01:27:54 +00001903}
1904
1905
sewardjde4a1d02002-03-22 01:27:54 +00001906/*--------------------------------------------------------------------*/
1907/*--- end vg_signals.c ---*/
1908/*--------------------------------------------------------------------*/