blob: 1984c23dea9eb0354ad8f4c386318070ad25e712 [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) )
nethercote9c42a0f2003-11-17 10:37:19 +0000555 goto bad_signo_reserved;
jsgf855d93d2003-10-13 22:26:55 +0000556
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,
nethercote9c42a0f2003-11-17 10:37:19 +0000590 "Warning: bad signal number %d in sigaction()",
njn25e49d8e72002-09-23 09:36:25 +0000591 signo);
njnd3040452003-05-19 15:04:06 +0000592 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
sewardj018f7622002-05-15 21:13:39 +0000593 return;
594
nethercote9c42a0f2003-11-17 10:37:19 +0000595 bad_signo_reserved:
fitzhardingebf459872003-11-18 16:55:33 +0000596 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1) {
nethercote9c42a0f2003-11-17 10:37:19 +0000597 VG_(message)(Vg_UserMsg,
598 "Warning: ignored attempt to set %s handler in sigaction();",
599 signame(signo));
600 VG_(message)(Vg_UserMsg,
601 " the %s signal is used internally by Valgrind",
602 signame(signo));
fitzhardingebf459872003-11-18 16:55:33 +0000603 }
nethercote9c42a0f2003-11-17 10:37:19 +0000604 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
605 return;
606
sewardj018f7622002-05-15 21:13:39 +0000607 bad_sigkill_or_sigstop:
sewardj37d06f22003-09-17 21:48:26 +0000608 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1)
njn25e49d8e72002-09-23 09:36:25 +0000609 VG_(message)(Vg_UserMsg,
nethercote9c42a0f2003-11-17 10:37:19 +0000610 "Warning: ignored attempt to set %s handler in sigaction();",
jsgf855d93d2003-10-13 22:26:55 +0000611 signame(signo));
nethercote9c42a0f2003-11-17 10:37:19 +0000612 VG_(message)(Vg_UserMsg,
613 " the %s signal is uncatchable",
614 signame(signo));
njnd3040452003-05-19 15:04:06 +0000615 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
sewardj018f7622002-05-15 21:13:39 +0000616 return;
617}
618
619
620static
621void do_sigprocmask_bitops ( Int vki_how,
622 vki_ksigset_t* orig_set,
623 vki_ksigset_t* modifier )
624{
625 switch (vki_how) {
626 case VKI_SIG_BLOCK:
627 VG_(ksigaddset_from_set)( orig_set, modifier );
628 break;
629 case VKI_SIG_UNBLOCK:
630 VG_(ksigdelset_from_set)( orig_set, modifier );
631 break;
632 case VKI_SIG_SETMASK:
633 *orig_set = *modifier;
634 break;
635 default:
njne427a662002-10-02 11:08:25 +0000636 VG_(core_panic)("do_sigprocmask_bitops");
sewardj018f7622002-05-15 21:13:39 +0000637 break;
638 }
639}
640
jsgf855d93d2003-10-13 22:26:55 +0000641/*
642 This updates the thread's signal mask. There's no such thing as a
643 process-wide signal mask.
sewardj018f7622002-05-15 21:13:39 +0000644
645 Note that the thread signal masks are an implicit part of SCSS,
646 which is why this routine is allowed to mess with them.
647*/
648static
649void do_setmask ( ThreadId tid,
650 Int how,
651 vki_ksigset_t* newset,
652 vki_ksigset_t* oldset )
653{
jsgf855d93d2003-10-13 22:26:55 +0000654 vg_assert(is_correct_sigmask());
sewardj018f7622002-05-15 21:13:39 +0000655
656 if (VG_(clo_trace_signals))
sewardja464e5c2002-05-23 17:34:49 +0000657 VG_(message)(Vg_DebugExtraMsg,
jsgf855d93d2003-10-13 22:26:55 +0000658 "do_setmask: tid = %d how = %d (%s), set = %p %08x%08x",
659 tid, how,
660 how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
661 how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
662 how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
663 newset, newset ? newset->ws[1] : 0, newset ? newset->ws[0] : 0
664 );
sewardj018f7622002-05-15 21:13:39 +0000665
jsgf855d93d2003-10-13 22:26:55 +0000666 /* Just do this thread. */
667 vg_assert(VG_(is_valid_tid)(tid));
668 if (oldset) {
669 *oldset = VG_(threads)[tid].eff_sig_mask;
670 if (VG_(clo_trace_signals))
671 VG_(message)(Vg_DebugExtraMsg,
672 "\toldset=%p %08x%08x",
673 oldset, oldset->ws[1], oldset->ws[0]);
sewardj018f7622002-05-15 21:13:39 +0000674 }
sewardj018f7622002-05-15 21:13:39 +0000675 if (newset) {
jsgf855d93d2003-10-13 22:26:55 +0000676 do_sigprocmask_bitops (how, &VG_(threads)[tid].sig_mask, newset );
677 VG_(ksigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGKILL);
678 VG_(ksigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGSTOP);
679 VG_(proxy_setsigmask)(tid);
sewardj018f7622002-05-15 21:13:39 +0000680 }
jsgf855d93d2003-10-13 22:26:55 +0000681
682 vg_assert(is_correct_sigmask());
sewardj018f7622002-05-15 21:13:39 +0000683}
684
685
686void VG_(do__NR_sigprocmask) ( ThreadId tid,
687 Int how,
688 vki_ksigset_t* set,
689 vki_ksigset_t* oldset )
690{
jsgf855d93d2003-10-13 22:26:55 +0000691 switch(how) {
692 case VKI_SIG_BLOCK:
693 case VKI_SIG_UNBLOCK:
694 case VKI_SIG_SETMASK:
sewardj018f7622002-05-15 21:13:39 +0000695 vg_assert(VG_(is_valid_tid)(tid));
jsgf855d93d2003-10-13 22:26:55 +0000696 /* Syscall returns 0 (success) to its thread. Set this up before
697 calling do_setmask() because we may get a signal as part of
698 setting the mask, which will confuse things.
699 */
njnd3040452003-05-19 15:04:06 +0000700 SET_SYSCALL_RETVAL(tid, 0);
jsgf855d93d2003-10-13 22:26:55 +0000701 do_setmask ( tid, how, set, oldset );
702
703 VG_(route_signals)(); /* if we're routing, do something before returning */
704 break;
705
706 default:
sewardj018f7622002-05-15 21:13:39 +0000707 VG_(message)(Vg_DebugMsg,
708 "sigprocmask: unknown `how' field %d", how);
njnd3040452003-05-19 15:04:06 +0000709 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
jsgf855d93d2003-10-13 22:26:55 +0000710 break;
sewardj018f7622002-05-15 21:13:39 +0000711 }
712}
713
714
715void VG_(do_pthread_sigmask_SCSS_upd) ( ThreadId tid,
716 Int how,
717 vki_ksigset_t* set,
718 vki_ksigset_t* oldset )
719{
720 /* Assume that how has been validated by caller. */
721 vg_assert(how == VKI_SIG_BLOCK || how == VKI_SIG_UNBLOCK
722 || how == VKI_SIG_SETMASK);
723 vg_assert(VG_(is_valid_tid)(tid));
724 do_setmask ( tid, how, set, oldset );
725 /* The request return code is set in do_pthread_sigmask */
726}
727
728
729void VG_(send_signal_to_thread) ( ThreadId thread, Int sig )
730{
jsgf855d93d2003-10-13 22:26:55 +0000731 ThreadState *tst;
732
sewardj018f7622002-05-15 21:13:39 +0000733 vg_assert(VG_(is_valid_tid)(thread));
734 vg_assert(sig >= 1 && sig <= VKI_KNSIG);
735
jsgf855d93d2003-10-13 22:26:55 +0000736 tst = VG_(get_ThreadState)(thread);
737 vg_assert(tst->proxy != NULL);
sewardj018f7622002-05-15 21:13:39 +0000738
jsgf855d93d2003-10-13 22:26:55 +0000739 VG_(proxy_sendsig)(thread, sig);
sewardjefbfcdf2002-06-19 17:35:45 +0000740}
741
742
sewardj018f7622002-05-15 21:13:39 +0000743/* ---------------------------------------------------------------------
744 LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
745 ------------------------------------------------------------------ */
sewardj77e466c2002-04-14 02:29:29 +0000746
sewardj2e93c502002-04-12 11:12:52 +0000747/* ---------------------------------------------------------------------
748 Handy utilities to block/restore all host signals.
749 ------------------------------------------------------------------ */
750
751/* Block all host signals, dumping the old mask in *saved_mask. */
752void VG_(block_all_host_signals) ( /* OUT */ vki_ksigset_t* saved_mask )
753{
754 Int ret;
755 vki_ksigset_t block_procmask;
756 VG_(ksigfillset)(&block_procmask);
757 ret = VG_(ksigprocmask)
758 (VKI_SIG_SETMASK, &block_procmask, saved_mask);
759 vg_assert(ret == 0);
760}
761
762/* Restore the blocking mask using the supplied saved one. */
sewardj018f7622002-05-15 21:13:39 +0000763void VG_(restore_all_host_signals) ( /* IN */ vki_ksigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +0000764{
765 Int ret;
766 ret = VG_(ksigprocmask)(VKI_SIG_SETMASK, saved_mask, NULL);
767 vg_assert(ret == 0);
768}
sewardjde4a1d02002-03-22 01:27:54 +0000769
jsgf855d93d2003-10-13 22:26:55 +0000770/* Sanity check - check the scheduler LWP has all the signals blocked
771 it is supposed to have blocked. */
772static Bool is_correct_sigmask(void)
773{
774 vki_ksigset_t mask;
775 Bool ret = True;
776
777 vg_assert(VG_(gettid)() == VG_(main_pid));
778
779#ifdef DEBUG_SIGNALS
780 VG_(ksigprocmask)(VKI_SIG_SETMASK, NULL, &mask);
781
782 /* unresumable signals */
783
784 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGSEGV);
785 VG_(ksigaddset)(&mask, VKI_SIGSEGV);
786
787 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGBUS);
788 VG_(ksigaddset)(&mask, VKI_SIGBUS);
789
790 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGFPE);
791 VG_(ksigaddset)(&mask, VKI_SIGFPE);
792
793 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGILL);
794 VG_(ksigaddset)(&mask, VKI_SIGILL);
795
796 /* unblockable signals (doesn't really matter if these are
797 already present) */
798 VG_(ksigaddset)(&mask, VKI_SIGSTOP);
799 VG_(ksigaddset)(&mask, VKI_SIGKILL);
800
801 ret = ret && VG_(kisfullsigset)(&mask);
802#endif /* DEBUG_SIGNALS */
803
804 return ret;
805}
806
807/* Set the signal mask for the scheduer LWP; this should be set once
808 and left that way - all async signal handling is done in the proxy
809 LWPs. */
810static void set_main_sigmask(void)
811{
812 vki_ksigset_t mask;
813
814 VG_(ksigfillset)(&mask);
815 VG_(ksigdelset)(&mask, VKI_SIGSEGV);
816 VG_(ksigdelset)(&mask, VKI_SIGBUS);
817 VG_(ksigdelset)(&mask, VKI_SIGFPE);
818 VG_(ksigdelset)(&mask, VKI_SIGILL);
819
820 VG_(ksigprocmask)(VKI_SIG_SETMASK, &mask, NULL);
821
822 vg_assert(is_correct_sigmask());
823}
sewardjde4a1d02002-03-22 01:27:54 +0000824
825/* ---------------------------------------------------------------------
826 The signal simulation proper. A simplified version of what the
827 Linux kernel does.
828 ------------------------------------------------------------------ */
829
830/* A structure in which to save the application's registers
831 during the execution of signal handlers. */
832
833typedef
834 struct {
jsgf855d93d2003-10-13 22:26:55 +0000835 /* There are two different stack frame formats, depending on
836 whether the client set the SA_SIGINFO flag for the handler.
837 This structure is put onto the client's stack as part of
838 signal delivery, and therefore appears as the signal
839 handler's arguments.
840
841 The first two words are common for both frame formats -
842 they're the return address and the signal number. */
sewardjf247eae2002-09-27 00:46:59 +0000843
844 /* Sig handler's (bogus) return address */
845 Addr retaddr;
846 /* The arg to the sig handler. We need to inspect this after
847 the handler returns, but it's unreasonable to assume that the
848 handler won't change it. So we keep a second copy of it in
849 sigNo_private. */
850 Int sigNo;
jsgf855d93d2003-10-13 22:26:55 +0000851
852 /* This is where the two frames start differing. */
853 union {
854 struct { /* set SA_SIGINFO */
855 /* ptr to siginfo_t. */
856 Addr psigInfo;
857
858 /* ptr to ucontext */
859 Addr puContext;
860 } sigInfo;
861 struct vki_sigcontext sigContext; /* did not set SA_SIGINFO */
862 } handlerArgs;
sewardjf247eae2002-09-27 00:46:59 +0000863
864 /* The rest are private fields which the handler is unaware of. */
865
sewardj2e93c502002-04-12 11:12:52 +0000866 /* Sanity check word. */
sewardjde4a1d02002-03-22 01:27:54 +0000867 UInt magicPI;
jsgf855d93d2003-10-13 22:26:55 +0000868 /* pointed to by psigInfo */
869 vki_ksiginfo_t sigInfo;
870 /* pointed to by puContext */
871 struct vki_ucontext uContext;
872
sewardjf247eae2002-09-27 00:46:59 +0000873 /* Safely-saved version of sigNo, as described above. */
874 Int sigNo_private;
sewardj2e93c502002-04-12 11:12:52 +0000875 /* Saved processor state. */
njnd3040452003-05-19 15:04:06 +0000876 UInt m_sse[VG_SIZE_OF_SSESTATE_W];
877
878 UInt m_eax;
879 UInt m_ecx;
880 UInt m_edx;
881 UInt m_ebx;
882 UInt m_ebp;
883 UInt m_esp;
884 UInt m_esi;
885 UInt m_edi;
886 UInt m_eflags;
887 Addr m_eip;
888
889 UInt sh_eax;
890 UInt sh_ebx;
891 UInt sh_ecx;
892 UInt sh_edx;
893 UInt sh_esi;
894 UInt sh_edi;
895 UInt sh_ebp;
896 UInt sh_esp;
897 UInt sh_eflags;
898
jsgf855d93d2003-10-13 22:26:55 +0000899 /* saved signal mask to be restored when handler returns */
900 vki_ksigset_t mask;
901
sewardj2e93c502002-04-12 11:12:52 +0000902 /* Scheduler-private stuff: what was the thread's status prior to
903 delivering this signal? */
904 ThreadStatus status;
905 /* Sanity check word. Is the highest-addressed word; do not
906 move!*/
sewardjde4a1d02002-03-22 01:27:54 +0000907 UInt magicE;
908 }
sewardj2e93c502002-04-12 11:12:52 +0000909 VgSigFrame;
sewardjde4a1d02002-03-22 01:27:54 +0000910
911
jsgf855d93d2003-10-13 22:26:55 +0000912/* Make up a plausible-looking thread state from the thread's current state */
913static void synth_ucontext(ThreadId tid, const vki_ksiginfo_t *si,
914 const vki_ksigset_t *set, struct vki_ucontext *uc)
915{
916 ThreadState *tst = VG_(get_ThreadState)(tid);
917 struct vki_sigcontext *sc = &uc->uc_mcontext;
918
919 VG_(memset)(uc, 0, sizeof(*uc));
920
921 uc->uc_flags = 0;
922 uc->uc_link = 0;
923 uc->uc_sigmask = *set;
924 uc->uc_stack = vg_scss.altstack;
925
926#define SC(reg) sc->reg = tst->m_##reg
927 SC(gs);
928 SC(fs);
929 SC(es);
930 SC(ds);
931
932 SC(edi);
933 SC(esi);
934 SC(ebp);
935 SC(esp);
936 SC(ebx);
937 SC(edx);
938 SC(ecx);
939 SC(eax);
940
941 SC(eip);
942 SC(cs);
943 SC(eflags);
944 SC(ss);
945 /* XXX esp_at_signal */
946 /* XXX trapno */
947 /* XXX err */
948#undef SC
949
950 sc->cr2 = (UInt)si->_sifields._sigfault._addr;
951}
sewardjde4a1d02002-03-22 01:27:54 +0000952
sewardjde4a1d02002-03-22 01:27:54 +0000953/* Set up a stack frame (VgSigContext) for the client's signal
954 handler. This includes the signal number and a bogus return
955 address. */
956static
jsgf855d93d2003-10-13 22:26:55 +0000957void vg_push_signal_frame ( ThreadId tid, const vki_ksiginfo_t *siginfo )
sewardjde4a1d02002-03-22 01:27:54 +0000958{
959 Int i;
sewardj2342c972002-05-22 23:34:20 +0000960 Addr esp, esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +0000961 VgSigFrame* frame;
962 ThreadState* tst;
jsgf855d93d2003-10-13 22:26:55 +0000963 Int sigNo = siginfo->si_signo;
sewardj2e93c502002-04-12 11:12:52 +0000964
sewardj2342c972002-05-22 23:34:20 +0000965 vg_assert(sigNo >= 1 && sigNo <= VKI_KNSIG);
sewardj018f7622002-05-15 21:13:39 +0000966 vg_assert(VG_(is_valid_tid)(tid));
967 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +0000968
jsgf855d93d2003-10-13 22:26:55 +0000969 if (VG_(clo_trace_signals))
970 VG_(message)(Vg_DebugMsg,
971 "vg_push_signal_frame (thread %d): signal %d", tid, sigNo);
972
sewardj2342c972002-05-22 23:34:20 +0000973 if (/* this signal asked to run on an alt stack */
jsgf855d93d2003-10-13 22:26:55 +0000974 (vg_scss.scss_per_sig[sigNo].scss_flags & VKI_SA_ONSTACK )
sewardj2342c972002-05-22 23:34:20 +0000975 && /* there is a defined and enabled alt stack, which we're not
976 already using. Logic from get_sigframe in
977 arch/i386/kernel/signal.c. */
978 sas_ss_flags(tst->m_esp) == 0
979 ) {
980 esp_top_of_frame
981 = (Addr)(vg_scss.altstack.ss_sp) + vg_scss.altstack.ss_size;
982 if (VG_(clo_trace_signals))
983 VG_(message)(Vg_DebugMsg,
jsgf855d93d2003-10-13 22:26:55 +0000984 "delivering signal %d (%s) to thread %d: on ALT STACK",
985 sigNo, signame(sigNo), tid );
njnfdc28af2003-02-24 10:36:48 +0000986
987 /* Signal delivery to skins */
988 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
989
sewardj2342c972002-05-22 23:34:20 +0000990 } else {
991 esp_top_of_frame = tst->m_esp;
njnfdc28af2003-02-24 10:36:48 +0000992
993 /* Signal delivery to skins */
994 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
sewardj2342c972002-05-22 23:34:20 +0000995 }
996
997 esp = esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +0000998 esp -= sizeof(VgSigFrame);
999 frame = (VgSigFrame*)esp;
njn25e49d8e72002-09-23 09:36:25 +00001000
1001 /* For tracking memory events, indicate the entire frame has been
1002 * allocated, but pretend that only the first four words are written */
1003 VG_TRACK( new_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) );
1004
sewardj2e93c502002-04-12 11:12:52 +00001005 /* Assert that the frame is placed correctly. */
1006 vg_assert( (sizeof(VgSigFrame) & 0x3) == 0 );
1007 vg_assert( ((Char*)(&frame->magicE)) + sizeof(UInt)
sewardj2342c972002-05-22 23:34:20 +00001008 == ((Char*)(esp_top_of_frame)) );
sewardj2e93c502002-04-12 11:12:52 +00001009
njn25e49d8e72002-09-23 09:36:25 +00001010 /* retaddr, sigNo, psigInfo, puContext fields are to be written */
njn72718642003-07-24 08:45:32 +00001011 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame",
jsgf855d93d2003-10-13 22:26:55 +00001012 (Addr)frame, offsetof(VgSigFrame, handlerArgs) );
sewardj2e93c502002-04-12 11:12:52 +00001013 frame->retaddr = (UInt)(&VG_(signalreturn_bogusRA));
1014 frame->sigNo = sigNo;
sewardjf247eae2002-09-27 00:46:59 +00001015 frame->sigNo_private = sigNo;
jsgf855d93d2003-10-13 22:26:55 +00001016 VG_TRACK( post_mem_write, (Addr)frame, offsetof(VgSigFrame, handlerArgs) );
1017
1018 if (vg_scss.scss_per_sig[sigNo].scss_flags & VKI_SA_SIGINFO) {
1019 /* if the client asked for a siginfo delivery, then build the stack that way */
1020 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)",
1021 (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
1022 frame->handlerArgs.sigInfo.psigInfo = (Addr)&frame->sigInfo;
1023 frame->handlerArgs.sigInfo.puContext = (Addr)&frame->uContext;
1024 VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
1025
1026 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)",
1027 (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
1028 VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_ksiginfo_t));
1029 VG_TRACK( post_mem_write, (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
1030
1031 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)",
1032 (Addr)&frame->uContext, sizeof(frame->uContext) );
1033 synth_ucontext(tid, siginfo, &vg_scss.scss_per_sig[sigNo].scss_mask, &frame->uContext);
1034 VG_TRACK( post_mem_write, (Addr)&frame->uContext, sizeof(frame->uContext) );
1035 } else {
1036 struct vki_ucontext uc;
1037
1038 /* otherwise just put the sigcontext there */
1039
1040 synth_ucontext(tid, siginfo, &vg_scss.scss_per_sig[sigNo].scss_mask, &uc);
1041
1042 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (sigcontext)",
1043 (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigContext) );
1044 VG_(memcpy)(&frame->handlerArgs.sigContext, &uc.uc_mcontext,
1045 sizeof(struct vki_sigcontext));
1046 VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs,
1047 sizeof(frame->handlerArgs.sigContext) );
1048
1049 frame->handlerArgs.sigContext.oldmask = tst->sig_mask.ws[0];
1050 }
1051
sewardj2e93c502002-04-12 11:12:52 +00001052 frame->magicPI = 0x31415927;
1053
sewardjb91ae7f2003-04-29 23:50:00 +00001054 for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
njnd3040452003-05-19 15:04:06 +00001055 frame->m_sse[i] = tst->m_sse[i];
sewardjde4a1d02002-03-22 01:27:54 +00001056
njnd3040452003-05-19 15:04:06 +00001057 frame->m_eax = tst->m_eax;
1058 frame->m_ecx = tst->m_ecx;
1059 frame->m_edx = tst->m_edx;
1060 frame->m_ebx = tst->m_ebx;
1061 frame->m_ebp = tst->m_ebp;
1062 frame->m_esp = tst->m_esp;
1063 frame->m_esi = tst->m_esi;
1064 frame->m_edi = tst->m_edi;
1065 frame->m_eflags = tst->m_eflags;
1066 frame->m_eip = tst->m_eip;
1067
1068 if (VG_(needs).shadow_regs) {
1069 frame->sh_eax = tst->sh_eax;
1070 frame->sh_ecx = tst->sh_ecx;
1071 frame->sh_edx = tst->sh_edx;
1072 frame->sh_ebx = tst->sh_ebx;
1073 frame->sh_ebp = tst->sh_ebp;
1074 frame->sh_esp = tst->sh_esp;
1075 frame->sh_esi = tst->sh_esi;
1076 frame->sh_edi = tst->sh_edi;
1077 frame->sh_eflags = tst->sh_eflags;
1078 }
sewardjde4a1d02002-03-22 01:27:54 +00001079
jsgf855d93d2003-10-13 22:26:55 +00001080 frame->mask = tst->sig_mask;
1081
1082 /* If the thread is currently blocked in a syscall, we want it to
1083 resume as runnable. */
1084 if (tst->status == VgTs_WaitSys)
1085 frame->status = VgTs_Runnable;
1086 else
1087 frame->status = tst->status;
sewardjde4a1d02002-03-22 01:27:54 +00001088
sewardj2e93c502002-04-12 11:12:52 +00001089 frame->magicE = 0x27182818;
1090
njnd3040452003-05-19 15:04:06 +00001091 /* Ensure 'tid' and 'tst' correspond */
1092 vg_assert(& VG_(threads)[tid] == tst);
sewardj2e93c502002-04-12 11:12:52 +00001093 /* Set the thread so it will next run the handler. */
njnd3040452003-05-19 15:04:06 +00001094 /* tst->m_esp = esp; */
1095 SET_SIGNAL_ESP(tid, esp);
1096
sewardj018f7622002-05-15 21:13:39 +00001097 tst->m_eip = (Addr)vg_scss.scss_per_sig[sigNo].scss_handler;
sewardj2e93c502002-04-12 11:12:52 +00001098 /* This thread needs to be marked runnable, but we leave that the
1099 caller to do. */
sewardjde4a1d02002-03-22 01:27:54 +00001100
jsgf855d93d2003-10-13 22:26:55 +00001101 if (0)
1102 VG_(printf)("pushed signal frame; %%ESP now = %p, next %%EBP = %p, status=%d\n",
1103 esp, tst->m_eip, tst->status);
sewardjde4a1d02002-03-22 01:27:54 +00001104}
1105
sewardjde4a1d02002-03-22 01:27:54 +00001106/* Clear the signal frame created by vg_push_signal_frame, restore the
1107 simulated machine state, and return the signal number that the
1108 frame was for. */
1109static
sewardj2e93c502002-04-12 11:12:52 +00001110Int vg_pop_signal_frame ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +00001111{
sewardj2e93c502002-04-12 11:12:52 +00001112 Addr esp;
sewardjde4a1d02002-03-22 01:27:54 +00001113 Int sigNo, i;
sewardj2e93c502002-04-12 11:12:52 +00001114 VgSigFrame* frame;
1115 ThreadState* tst;
sewardjde4a1d02002-03-22 01:27:54 +00001116
sewardj018f7622002-05-15 21:13:39 +00001117 vg_assert(VG_(is_valid_tid)(tid));
1118 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +00001119
sewardj54cacf02002-04-12 23:24:59 +00001120 /* Correctly reestablish the frame base address. */
sewardj2e93c502002-04-12 11:12:52 +00001121 esp = tst->m_esp;
sewardj54cacf02002-04-12 23:24:59 +00001122 frame = (VgSigFrame*)
1123 (esp -4 /* because the handler's RET pops the RA */
1124 +20 /* because signalreturn_bogusRA pushes 5 words */);
sewardj2e93c502002-04-12 11:12:52 +00001125
1126 vg_assert(frame->magicPI == 0x31415927);
1127 vg_assert(frame->magicE == 0x27182818);
sewardjde4a1d02002-03-22 01:27:54 +00001128 if (VG_(clo_trace_signals))
sewardjb48e5002002-05-13 00:16:03 +00001129 VG_(message)(Vg_DebugMsg,
jsgf855d93d2003-10-13 22:26:55 +00001130 "vg_pop_signal_frame (thread %d): valid magic; EIP=%p", tid, frame->m_eip);
sewardjde4a1d02002-03-22 01:27:54 +00001131
sewardj2342c972002-05-22 23:34:20 +00001132 /* Mark the frame structure as nonaccessible. */
njn25e49d8e72002-09-23 09:36:25 +00001133 VG_TRACK( die_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) );
sewardjde4a1d02002-03-22 01:27:54 +00001134
njnd3040452003-05-19 15:04:06 +00001135 /* restore machine state */
1136 for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
1137 tst->m_sse[i] = frame->m_sse[i];
sewardjf247eae2002-09-27 00:46:59 +00001138
njnd3040452003-05-19 15:04:06 +00001139 tst->m_eax = frame->m_eax;
1140 tst->m_ecx = frame->m_ecx;
1141 tst->m_edx = frame->m_edx;
1142 tst->m_ebx = frame->m_ebx;
1143 tst->m_ebp = frame->m_ebp;
1144 tst->m_esp = frame->m_esp;
1145 tst->m_esi = frame->m_esi;
1146 tst->m_edi = frame->m_edi;
1147 tst->m_eflags = frame->m_eflags;
1148 tst->m_eip = frame->m_eip;
1149
1150 if (VG_(needs).shadow_regs) {
1151 tst->sh_eax = frame->sh_eax;
1152 tst->sh_ecx = frame->sh_ecx;
1153 tst->sh_edx = frame->sh_edx;
1154 tst->sh_ebx = frame->sh_ebx;
1155 tst->sh_ebp = frame->sh_ebp;
1156 tst->sh_esp = frame->sh_esp;
1157 tst->sh_esi = frame->sh_esi;
1158 tst->sh_edi = frame->sh_edi;
1159 tst->sh_eflags = frame->sh_eflags;
1160 }
1161
sewardjf247eae2002-09-27 00:46:59 +00001162 /* don't use the copy exposed to the handler; it might have changed
1163 it. */
1164 sigNo = frame->sigNo_private;
sewardj2e93c502002-04-12 11:12:52 +00001165
1166 /* And restore the thread's status to what it was before the signal
1167 was delivered. */
1168 tst->status = frame->status;
1169
jsgf855d93d2003-10-13 22:26:55 +00001170 tst->sig_mask = frame->mask;
1171 VG_(proxy_setsigmask)(tid);
1172
njnfdc28af2003-02-24 10:36:48 +00001173 /* Notify skins */
1174 VG_TRACK( post_deliver_signal, tid, sigNo );
1175
sewardjde4a1d02002-03-22 01:27:54 +00001176 return sigNo;
1177}
1178
1179
1180/* A handler is returning. Restore the machine state from the stacked
1181 VgSigContext and continue with whatever was going on before the
sewardj77e466c2002-04-14 02:29:29 +00001182 handler ran. Returns the SA_RESTART syscall-restartability-status
1183 of the delivered signal. */
sewardjde4a1d02002-03-22 01:27:54 +00001184
sewardj77e466c2002-04-14 02:29:29 +00001185Bool VG_(signal_returns) ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +00001186{
sewardj2e93c502002-04-12 11:12:52 +00001187 Int sigNo;
sewardjde4a1d02002-03-22 01:27:54 +00001188
sewardj2e93c502002-04-12 11:12:52 +00001189 /* Pop the signal frame and restore tid's status to what it was
1190 before the signal was delivered. */
1191 sigNo = vg_pop_signal_frame(tid);
sewardjde4a1d02002-03-22 01:27:54 +00001192
sewardjb48e5002002-05-13 00:16:03 +00001193 vg_assert(sigNo >= 1 && sigNo <= VKI_KNSIG);
sewardjde4a1d02002-03-22 01:27:54 +00001194
sewardj77e466c2002-04-14 02:29:29 +00001195 /* Scheduler now can resume this thread, or perhaps some other.
1196 Tell the scheduler whether or not any syscall interrupted by
jsgf855d93d2003-10-13 22:26:55 +00001197 this signal should be restarted, if possible, or no. This is
1198 only used for nanosleep; all other blocking syscalls are handled
1199 in VG_(deliver_signal)().
1200 */
sewardj018f7622002-05-15 21:13:39 +00001201 return
1202 (vg_scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART)
1203 ? True
1204 : False;
sewardjde4a1d02002-03-22 01:27:54 +00001205}
1206
jsgf855d93d2003-10-13 22:26:55 +00001207static const Char *signame(Int sigNo)
sewardjde4a1d02002-03-22 01:27:54 +00001208{
jsgf855d93d2003-10-13 22:26:55 +00001209 static Char buf[10];
sewardjb48e5002002-05-13 00:16:03 +00001210
jsgf855d93d2003-10-13 22:26:55 +00001211 switch(sigNo) {
1212#define S(x) case VKI_##x: return #x
1213 S(SIGHUP);
1214 S(SIGINT);
1215 S(SIGQUIT);
1216 S(SIGILL);
1217 S(SIGTRAP);
1218 S(SIGABRT);
1219 S(SIGBUS);
1220 S(SIGFPE);
1221 S(SIGKILL);
1222 S(SIGUSR1);
1223 S(SIGUSR2);
1224 S(SIGSEGV);
1225 S(SIGPIPE);
1226 S(SIGALRM);
1227 S(SIGTERM);
1228 S(SIGSTKFLT);
1229 S(SIGCHLD);
1230 S(SIGCONT);
1231 S(SIGSTOP);
1232 S(SIGTSTP);
1233 S(SIGTTIN);
1234 S(SIGTTOU);
1235 S(SIGURG);
1236 S(SIGXCPU);
1237 S(SIGXFSZ);
1238 S(SIGVTALRM);
1239 S(SIGPROF);
1240 S(SIGWINCH);
1241 S(SIGIO);
1242 S(SIGPWR);
1243 S(SIGUNUSED);
1244#undef S
sewardjde4a1d02002-03-22 01:27:54 +00001245
jsgf855d93d2003-10-13 22:26:55 +00001246 case VKI_SIGRTMIN ... VKI_SIGRTMAX:
1247 VG_(sprintf)(buf, "SIGRT%d", sigNo);
1248 return buf;
sewardjde4a1d02002-03-22 01:27:54 +00001249
jsgf855d93d2003-10-13 22:26:55 +00001250 default:
1251 VG_(sprintf)(buf, "SIG%d", sigNo);
1252 return buf;
1253 }
1254}
sewardjde4a1d02002-03-22 01:27:54 +00001255
jsgf855d93d2003-10-13 22:26:55 +00001256/* Hit ourselves with a signal using the default handler */
1257void VG_(kill_self)(Int sigNo)
1258{
1259 vki_ksigset_t mask, origmask;
1260 vki_ksigaction sa, origsa;
sewardj018f7622002-05-15 21:13:39 +00001261
jsgf855d93d2003-10-13 22:26:55 +00001262 sa.ksa_handler = VKI_SIG_DFL;
1263 sa.ksa_flags = 0;
1264 sa.ksa_restorer = 0;
1265 VG_(ksigemptyset)(&sa.ksa_mask);
sewardj2e93c502002-04-12 11:12:52 +00001266
jsgf855d93d2003-10-13 22:26:55 +00001267 VG_(ksigaction)(sigNo, &sa, &origsa);
sewardj018f7622002-05-15 21:13:39 +00001268
jsgf855d93d2003-10-13 22:26:55 +00001269 VG_(ksigfillset)(&mask);
1270 VG_(ksigdelset)(&mask, sigNo);
1271 VG_(ksigprocmask)(VKI_SIG_SETMASK, &mask, &origmask);
1272
1273 VG_(ktkill)(VG_(getpid)(), sigNo);
1274
1275 VG_(ksigaction)(sigNo, &origsa, NULL);
1276 VG_(ksigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
1277}
1278
1279/*
1280 Perform the default action of a signal. Returns if the default
1281 action isn't fatal.
1282
1283 If we're not being quiet, then print out some more detail about
1284 fatal signals (esp. core dumping signals).
1285 */
1286static void vg_default_action(const vki_ksiginfo_t *info, ThreadId tid)
1287{
1288 Int sigNo = info->si_signo;
1289 Bool terminate = False;
1290 Bool core = False;
1291
1292 switch(sigNo) {
1293 case VKI_SIGQUIT: /* core */
1294 case VKI_SIGILL: /* core */
1295 case VKI_SIGABRT: /* core */
1296 case VKI_SIGFPE: /* core */
1297 case VKI_SIGSEGV: /* core */
1298 case VKI_SIGBUS: /* core */
1299 case VKI_SIGTRAP: /* core */
1300 case VKI_SIGXCPU: /* core */
1301 case VKI_SIGXFSZ: /* core */
1302 terminate = True;
1303 core = True;
1304 break;
1305
1306 case VKI_SIGHUP: /* term */
1307 case VKI_SIGINT: /* term */
1308 case VKI_SIGKILL: /* term - we won't see this */
1309 case VKI_SIGPIPE: /* term */
1310 case VKI_SIGALRM: /* term */
1311 case VKI_SIGTERM: /* term */
1312 case VKI_SIGUSR1: /* term */
1313 case VKI_SIGUSR2: /* term */
1314 case VKI_SIGIO: /* term */
1315 case VKI_SIGPWR: /* term */
1316 case VKI_SIGSYS: /* term */
1317 case VKI_SIGPROF: /* term */
1318 case VKI_SIGVTALRM: /* term */
1319 case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
1320 terminate = True;
1321 break;
1322 }
1323
1324 vg_assert(!core || (core && terminate));
1325
1326 if (terminate) {
1327 if (VG_(clo_verbosity) != 0 && (core || VG_(clo_verbosity) > 1)) {
1328 VG_(message)(Vg_UserMsg, "");
1329 VG_(message)(Vg_UserMsg, "Process terminating with default action of signal %d (%s)%s",
1330 sigNo, signame(sigNo), core ? ": dumping core" : "");
1331
1332 /* Be helpful - decode some more details about this fault */
1333 if (info->si_code > VKI_SI_USER) {
1334 const Char *event = NULL;
1335
1336 switch(sigNo) {
1337 case VKI_SIGSEGV:
1338 switch(info->si_code) {
nethercote3b390c72003-11-13 17:53:43 +00001339 case 1: event = "Address not mapped to object"; break;
1340 case 2: event = "Invalid permissions for mapped object"; break;
jsgf855d93d2003-10-13 22:26:55 +00001341 }
1342 break;
1343
1344 case VKI_SIGILL:
1345 switch(info->si_code) {
nethercote3b390c72003-11-13 17:53:43 +00001346 case 1: event = "Illegal opcode"; break;
1347 case 2: event = "Illegal operand"; break;
1348 case 3: event = "Illegal addressing mode"; break;
1349 case 4: event = "Illegal trap"; break;
1350 case 5: event = "Privileged opcode"; break;
1351 case 6: event = "Privileged register"; break;
1352 case 7: event = "Coprocessor error"; break;
1353 case 8: event = "Internal stack error"; break;
jsgf855d93d2003-10-13 22:26:55 +00001354 }
1355 break;
1356
1357 case VKI_SIGFPE:
1358 switch (info->si_code) {
nethercote3b390c72003-11-13 17:53:43 +00001359 case 1: event = "Integer divide by zero"; break;
1360 case 2: event = "Integer overflow"; break;
jsgf855d93d2003-10-13 22:26:55 +00001361 case 3: event = "FP divide by zero"; break;
1362 case 4: event = "FP overflow"; break;
1363 case 5: event = "FP underflow"; break;
1364 case 6: event = "FP inexact"; break;
1365 case 7: event = "FP invalid operation"; break;
1366 case 8: event = "FP subscript out of range"; break;
1367 }
1368 break;
1369
1370 case VKI_SIGBUS:
1371 switch (info->si_code) {
nethercote3b390c72003-11-13 17:53:43 +00001372 case 1: event = "Invalid address alignment"; break;
1373 case 2: event = "Non-existent physical address"; break;
1374 case 3: event = "Hardware error"; break;
jsgf855d93d2003-10-13 22:26:55 +00001375 }
1376 break;
1377 }
1378
1379 if (event != NULL)
nethercote3b390c72003-11-13 17:53:43 +00001380 VG_(message)(Vg_UserMsg, " %s at address %p",
jsgf855d93d2003-10-13 22:26:55 +00001381 event, info->_sifields._sigfault._addr);
1382 }
1383
1384 if (tid != VG_INVALID_THREADID) {
1385 ExeContext *ec = VG_(get_ExeContext)(tid);
1386 VG_(pp_ExeContext)(ec);
1387 }
1388 }
1389
1390 if (VG_(fatal_signal_set)) {
1391 VG_(fatal_sigNo) = sigNo;
1392 __builtin_longjmp(VG_(fatal_signal_jmpbuf), 1);
sewardj018f7622002-05-15 21:13:39 +00001393 }
sewardjde4a1d02002-03-22 01:27:54 +00001394 }
1395
jsgf855d93d2003-10-13 22:26:55 +00001396 VG_(kill_self)(sigNo);
sewardj018f7622002-05-15 21:13:39 +00001397
jsgf855d93d2003-10-13 22:26:55 +00001398 vg_assert(!terminate);
sewardjb48e5002002-05-13 00:16:03 +00001399}
1400
1401
jsgf855d93d2003-10-13 22:26:55 +00001402void VG_(deliver_signal) ( ThreadId tid, const vki_ksiginfo_t *info, Bool async )
sewardjde4a1d02002-03-22 01:27:54 +00001403{
jsgf855d93d2003-10-13 22:26:55 +00001404 Int sigNo = info->si_signo;
1405 vki_ksigset_t handlermask;
jsgf855d93d2003-10-13 22:26:55 +00001406 SCSS_Per_Signal *handler = &vg_scss.scss_per_sig[sigNo];
1407 ThreadState *tst = VG_(get_ThreadState)(tid);
1408
1409 if (VG_(clo_trace_signals))
1410 VG_(message)(Vg_DebugMsg,"delivering signal %d (%s) to thread %d",
1411 sigNo, signame(sigNo), tid );
1412
1413 if (sigNo == VKI_SIGVGINT) {
1414 /* If this is a SIGVGINT, then we just ACK the signal and carry
1415 on; the application need never know about it (except for any
1416 effect on its syscalls). */
1417 vg_assert(async);
1418
1419 if (tst->status == VgTs_WaitSys) {
1420 /* blocked in a syscall; we assume it should be interrupted */
1421 if (tst->m_eax == -VKI_ERESTARTSYS)
1422 tst->m_eax = -VKI_EINTR;
1423 }
1424
1425 VG_(proxy_sigack)(tid, &tst->sig_mask);
1426 return;
1427 }
1428
1429 /* If thread is currently blocked in a syscall, then resume as
1430 runnable. If the syscall needs restarting, tweak the machine
1431 state to make it happen. */
1432 if (tst->status == VgTs_WaitSys) {
1433 vg_assert(tst->syscallno != -1);
1434
fitzhardingea09a1b52003-11-07 23:09:48 +00001435 /* OK, the thread was waiting for a syscall to complete. This
1436 means that the proxy has either not yet processed the
1437 RunSyscall request, or was processing it when the signal
1438 came. Either way, it is going to give us some syscall
1439 results right now, so wait for them to appear. This makes
1440 the thread runnable again, so we're in the right state to run
1441 the handler, and resume the syscall when we're done. */
1442 VG_(proxy_wait_sys)(tid);
1443
jsgf855d93d2003-10-13 22:26:55 +00001444 if (0)
1445 VG_(printf)("signal %d interrupting syscall %d\n",
1446 sigNo, tst->syscallno);
1447
1448 if (tst->m_eax == -VKI_ERESTARTSYS) {
1449 if (handler->scss_flags & VKI_SA_RESTART) {
fitzhardingee1c06d82003-10-30 07:21:44 +00001450 VG_(restart_syscall)(tid);
jsgf855d93d2003-10-13 22:26:55 +00001451 } else
1452 tst->m_eax = -VKI_EINTR;
1453 } else {
1454 /* return value is already in eax - either EINTR or the
1455 normal return value */
1456 }
1457 }
1458
1459 vg_assert(handler->scss_handler != VKI_SIG_IGN);
1460
1461 if (sigNo == VKI_SIGCHLD && (handler->scss_flags & VKI_SA_NOCLDWAIT)) {
1462 //VG_(printf)("sigNo==SIGCHLD and app asked for NOCLDWAIT\n");
1463 vg_babyeater(sigNo, NULL, NULL);
1464 }
1465
1466 if (handler->scss_handler == VKI_SIG_DFL) {
1467 handlermask = tst->sig_mask; /* no change to signal mask */
1468 vg_default_action(info, tid);
1469 } else {
1470 /* Create a signal delivery frame, and set the client's %ESP and
1471 %EIP so that when execution continues, we will enter the
1472 signal handler with the frame on top of the client's stack,
1473 as it expects. */
1474 vg_assert(VG_(is_valid_tid)(tid));
1475 vg_push_signal_frame ( tid, info );
1476
1477 if (handler->scss_flags & VKI_SA_ONESHOT) {
1478 /* Do the ONESHOT thing. */
1479 handler->scss_handler = VKI_SIG_DFL;
1480
1481 VG_(handle_SCSS_change)( False /* lazy update */ );
1482 }
1483
fitzhardingea09a1b52003-11-07 23:09:48 +00001484 switch(tst->status) {
jsgf855d93d2003-10-13 22:26:55 +00001485 case VgTs_Runnable:
1486 break;
1487
1488 case VgTs_WaitSys:
jsgf855d93d2003-10-13 22:26:55 +00001489 case VgTs_WaitJoiner:
1490 case VgTs_WaitJoinee:
1491 case VgTs_WaitMX:
1492 case VgTs_WaitCV:
1493 case VgTs_Sleeping:
fitzhardingea09a1b52003-11-07 23:09:48 +00001494 tst->status = VgTs_Runnable;
jsgf855d93d2003-10-13 22:26:55 +00001495 break;
1496
1497 case VgTs_Empty:
1498 VG_(core_panic)("unexpected thread state");
1499 break;
1500 }
1501
jsgf855d93d2003-10-13 22:26:55 +00001502 /* handler gets the union of the signal's mask and the thread's
1503 mask */
1504 handlermask = handler->scss_mask;
1505 VG_(ksigaddset_from_set)(&handlermask, &VG_(threads)[tid].sig_mask);
1506
1507 /* also mask this signal, unless they ask us not to */
1508 if (!(handler->scss_flags & VKI_SA_NOMASK))
1509 VG_(ksigaddset)(&handlermask, sigNo);
1510 }
1511
1512 /* tell proxy we're about to start running the handler */
1513 if (async)
1514 VG_(proxy_sigack)(tid, &handlermask);
1515}
1516
1517
1518/*
1519 If the client set the handler for SIGCHLD to SIG_IGN, then we need
1520 to automatically dezombie any dead children. Also used if the
1521 client set the SA_NOCLDWAIT on their SIGCHLD handler.
1522 */
1523static
1524void vg_babyeater ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext *uc )
1525{
1526 Int status;
1527 Int pid;
1528
1529 vg_assert(sigNo == VKI_SIGCHLD);
1530
1531 while((pid = VG_(waitpid)(-1, &status, VKI_WNOHANG)) > 0) {
1532 if (VG_(clo_trace_signals))
1533 VG_(message)(Vg_DebugMsg, "babyeater reaped %d", pid);
1534 }
1535}
1536
1537/*
1538 Receive an async signal from the host.
1539
1540 It being called in the context of a proxy LWP, and therefore is an
1541 async signal aimed at one of our threads. In this case, we pass
1542 the signal info to the main thread with VG_(proxy_handlesig)().
1543
1544 This should *never* be in the context of the main LWP, because
1545 all signals for which this is the handler should be blocked there.
1546*/
1547static
1548void vg_async_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext *uc )
1549{
1550 if (VG_(gettid)() == VG_(main_pid)) {
1551 VG_(printf)("got signal %d in LWP %d (%d)\n",
1552 sigNo, VG_(gettid)(), VG_(gettid)(), VG_(main_pid));
1553 vg_assert(VG_(ksigismember)(&uc->uc_sigmask, sigNo));
1554 }
1555
1556 vg_assert(VG_(gettid)() != VG_(main_pid));
1557
1558 VG_(proxy_handlesig)(info, &uc->uc_mcontext);
1559}
1560
1561/*
1562 Recieve a sync signal from the host.
1563
1564 This should always be called from the main thread, though it may be
1565 called in a proxy LWP if someone sends an async version of one of
1566 the sync signals.
1567*/
1568static
1569void vg_sync_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext *uc )
1570{
sewardj2e93c502002-04-12 11:12:52 +00001571 Int dummy_local;
jsgf855d93d2003-10-13 22:26:55 +00001572
1573 vg_assert(info != NULL);
1574 vg_assert(info->si_signo == sigNo);
1575 vg_assert(sigNo == VKI_SIGSEGV ||
1576 sigNo == VKI_SIGBUS ||
1577 sigNo == VKI_SIGFPE ||
1578 sigNo == VKI_SIGILL);
1579
1580 if (VG_(gettid)() != VG_(main_pid)) {
1581 /* We were sent one of our sync signals in an async way (or the
1582 proxy LWP code has a bug) */
1583 vg_assert(info->si_code <= VKI_SI_USER);
1584
1585 VG_(proxy_handlesig)(info, &uc->uc_mcontext);
1586 return;
1587 }
1588
sewardjde4a1d02002-03-22 01:27:54 +00001589
sewardj7a61d912002-04-25 01:27:35 +00001590 /*
1591 if (sigNo == VKI_SIGUSR1) {
1592 VG_(printf)("YOWZA! SIGUSR1\n\n");
1593 VG_(clo_trace_pthread_level) = 2;
1594 VG_(clo_trace_sched) = True;
1595 VG_(clo_trace_syscalls) = True;
1596 VG_(clo_trace_signals) = True;
1597 return;
1598 }
1599 */
1600
sewardjde4a1d02002-03-22 01:27:54 +00001601 if (VG_(clo_trace_signals)) {
1602 VG_(start_msg)(Vg_DebugMsg);
1603 VG_(add_to_msg)("signal %d arrived ... ", sigNo );
1604 }
sewardjb48e5002002-05-13 00:16:03 +00001605 vg_assert(sigNo >= 1 && sigNo <= VKI_KNSIG);
sewardjde4a1d02002-03-22 01:27:54 +00001606
1607 /* Sanity check. Ensure we're really running on the signal stack
1608 we asked for. */
njn6eba4ef2003-05-01 08:06:41 +00001609 if (!(
1610 ((Char*)(&(VG_(sigstack)[0])) <= (Char*)(&dummy_local))
1611 &&
1612 ((Char*)(&dummy_local) < (Char*)(&(VG_(sigstack)[VG_SIGSTACK_SIZE_W])))
sewardjde4a1d02002-03-22 01:27:54 +00001613 )
njn6eba4ef2003-05-01 08:06:41 +00001614 ) {
sewardj2e93c502002-04-12 11:12:52 +00001615 VG_(message)(Vg_DebugMsg,
1616 "FATAL: signal delivered on the wrong stack?!");
1617 VG_(message)(Vg_DebugMsg,
1618 "A possible workaround follows. Please tell me");
1619 VG_(message)(Vg_DebugMsg,
1620 "(jseward@acm.org) if the suggested workaround doesn't help.");
sewardjde4a1d02002-03-22 01:27:54 +00001621 VG_(unimplemented)
sewardj2e93c502002-04-12 11:12:52 +00001622 ("support for progs compiled with -p/-pg; "
1623 "rebuild your prog without -p/-pg");
sewardjde4a1d02002-03-22 01:27:54 +00001624 }
1625
sewardj2e93c502002-04-12 11:12:52 +00001626 vg_assert((Char*)(&(VG_(sigstack)[0])) <= (Char*)(&dummy_local));
njn6eba4ef2003-05-01 08:06:41 +00001627 vg_assert((Char*)(&dummy_local) < (Char*)(&(VG_(sigstack)[VG_SIGSTACK_SIZE_W])));
sewardjde4a1d02002-03-22 01:27:54 +00001628
jsgf855d93d2003-10-13 22:26:55 +00001629 if (VG_(scheduler_jmpbuf_valid)) {
sewardj2e93c502002-04-12 11:12:52 +00001630 /* Can't continue; must longjmp back to the scheduler and thus
1631 enter the sighandler immediately. */
jsgf855d93d2003-10-13 22:26:55 +00001632 VG_(memcpy)(&VG_(unresumable_siginfo), info, sizeof(vki_ksiginfo_t));
1633
sewardjde4a1d02002-03-22 01:27:54 +00001634 VG_(longjmpd_on_signal) = sigNo;
sewardj2e93c502002-04-12 11:12:52 +00001635 __builtin_longjmp(VG_(scheduler_jmpbuf),1);
sewardjde4a1d02002-03-22 01:27:54 +00001636 }
sewardj872051c2002-07-13 12:12:56 +00001637
jsgf855d93d2003-10-13 22:26:55 +00001638 if (info->si_code <= VKI_SI_USER) {
1639 /*
1640 OK, one of sync signals was sent from user-mode, so try to
fitzhardingee1c06d82003-10-30 07:21:44 +00001641 deliver it to someone who cares. Just add it to the
1642 process-wide pending signal set - signal routing will deliver
1643 it to someone eventually.
jsgf855d93d2003-10-13 22:26:55 +00001644
fitzhardingee1c06d82003-10-30 07:21:44 +00001645 The only other place which touches proc_pending is
1646 VG_(route_signals), and it has signals blocked while doing
1647 so, so there's no race.
1648 */
1649 VG_(message)(Vg_DebugMsg,
1650 "adding signal %d to pending set", sigNo);
1651 VG_(ksigaddset)(&proc_pending, sigNo);
jsgf855d93d2003-10-13 22:26:55 +00001652 } else {
1653 /*
1654 A bad signal came from the kernel (indicating an instruction
1655 generated it), but there was no jumpbuf set up. This means
1656 it was actually generated by Valgrind internally.
1657 */
1658 struct vki_sigcontext *sc = &uc->uc_mcontext;
1659
1660 VG_(message)(Vg_DebugMsg,
1661 "INTERNAL ERROR: Valgrind received a signal %d (%s) - exiting",
1662 sigNo, signame(sigNo));
1663 VG_(message)(Vg_DebugMsg,
1664 "si_code=%x Fault EIP: %p; Faulting address: %p",
1665 info->si_code, sc->eip, info->_sifields._sigfault._addr);
1666
1667 if (0)
1668 VG_(kill_self)(sigNo); /* generate a core dump */
1669 VG_(core_panic)("Killed by fatal signal");
1670 }
1671}
1672
1673
1674/*
1675 This signal handler exists only so that the scheduler thread can
1676 poke the LWP to make it fall out of whatever syscall it is in.
1677 Used for thread termination and cancellation.
1678 */
1679static void proxy_sigvg_handler(int signo, vki_ksiginfo_t *si, struct vki_ucontext *uc)
1680{
1681 vg_assert(signo == VKI_SIGVGINT || signo == VKI_SIGVGKILL);
1682 vg_assert(si->si_signo == signo);
1683
1684 /* only pay attention to it if it came from the scheduler */
1685 if (si->si_code == VKI_SI_TKILL &&
1686 si->_sifields._kill._pid == VG_(main_pid)) {
1687 vg_assert(si->si_code == VKI_SI_TKILL);
1688 vg_assert(si->_sifields._kill._pid == VG_(main_pid));
1689
1690 VG_(proxy_handlesig)(si, &uc->uc_mcontext);
sewardj872051c2002-07-13 12:12:56 +00001691 }
sewardjde4a1d02002-03-22 01:27:54 +00001692}
1693
1694
1695/* The outer insn loop calls here to reenable a host signal if
1696 vg_oursighandler longjmp'd.
1697*/
1698void VG_(unblock_host_signal) ( Int sigNo )
1699{
jsgf855d93d2003-10-13 22:26:55 +00001700 vg_assert(sigNo == VKI_SIGSEGV ||
1701 sigNo == VKI_SIGBUS ||
1702 sigNo == VKI_SIGILL ||
1703 sigNo == VKI_SIGFPE);
1704 set_main_sigmask();
sewardjde4a1d02002-03-22 01:27:54 +00001705}
1706
1707
1708static __attribute((unused))
1709void pp_vg_ksigaction ( vki_ksigaction* sa )
1710{
1711 Int i;
1712 VG_(printf)("vg_ksigaction: handler %p, flags 0x%x, restorer %p\n",
sewardj9a199dc2002-04-14 13:01:38 +00001713 sa->ksa_handler, (UInt)sa->ksa_flags, sa->ksa_restorer);
sewardjde4a1d02002-03-22 01:27:54 +00001714 VG_(printf)("vg_ksigaction: { ");
sewardjb48e5002002-05-13 00:16:03 +00001715 for (i = 1; i <= VKI_KNSIG; i++)
sewardjde4a1d02002-03-22 01:27:54 +00001716 if (VG_(ksigismember(&(sa->ksa_mask),i)))
1717 VG_(printf)("%d ", i);
1718 VG_(printf)("}\n");
1719}
1720
jsgf855d93d2003-10-13 22:26:55 +00001721/*
1722 In pre-2.6 kernels, the kernel didn't distribute signals to threads
1723 in a thread-group properly, so we need to do it here.
1724 */
1725void VG_(route_signals)(void)
1726{
1727 static const struct vki_timespec zero = { 0, 0 };
1728 static ThreadId start_tid = 1; /* tid to start scanning from */
1729 vki_ksigset_t set;
jsgf855d93d2003-10-13 22:26:55 +00001730 vki_ksiginfo_t si;
1731 Int sigNo;
1732
1733 vg_assert(VG_(gettid)() == VG_(main_pid));
1734 vg_assert(is_correct_sigmask());
1735
1736 if (!VG_(do_signal_routing))
1737 return;
1738
jsgf855d93d2003-10-13 22:26:55 +00001739 /* get the scheduler LWP's signal mask, and use it as the set of
fitzhardingee1c06d82003-10-30 07:21:44 +00001740 signals we're polling for - also block all signals to prevent
1741 races */
1742 VG_(block_all_host_signals) ( &set );
jsgf855d93d2003-10-13 22:26:55 +00001743
fitzhardingee1c06d82003-10-30 07:21:44 +00001744 /* grab any pending signals and add them to the pending signal set */
1745 while(VG_(ksigtimedwait)(&set, &si, &zero) > 0)
1746 VG_(ksigaddset)(&proc_pending, si.si_signo);
1747
1748 /* transfer signals from the process pending set to a particular
1749 thread which has it unblocked */
1750 for(sigNo = 0; sigNo < VKI_KNSIG; sigNo++) {
jsgf855d93d2003-10-13 22:26:55 +00001751 ThreadId tid;
1752 ThreadId end_tid;
1753 Int target = -1;
1754
fitzhardingee1c06d82003-10-30 07:21:44 +00001755 if (!VG_(ksigismember)(&proc_pending, sigNo))
1756 continue;
1757
jsgf855d93d2003-10-13 22:26:55 +00001758 end_tid = start_tid - 1;
1759 if (end_tid < 0 || end_tid >= VG_N_THREADS)
1760 end_tid = VG_N_THREADS-1;
1761
jsgf855d93d2003-10-13 22:26:55 +00001762 /* look for a suitable thread to deliver it to */
1763 for(tid = start_tid;
1764 tid != end_tid;
1765 tid = (tid + 1) % VG_N_THREADS) {
1766 ThreadState *tst = &VG_(threads)[tid];
1767
1768 if (tst->status == VgTs_Empty)
1769 continue;
1770
1771 if (!VG_(ksigismember)(&tst->sig_mask, sigNo)) {
1772 vg_assert(tst->proxy != NULL);
1773 target = tid;
1774 start_tid = tid;
1775 break;
1776 }
1777 }
1778
fitzhardingee1c06d82003-10-30 07:21:44 +00001779 /* found one - deliver it and be done */
jsgf855d93d2003-10-13 22:26:55 +00001780 if (target != -1) {
1781 if (VG_(clo_trace_signals))
1782 VG_(message)(Vg_DebugMsg, "Routing signal %d to tid %d",
1783 sigNo, tid);
fitzhardingee1c06d82003-10-30 07:21:44 +00001784 VG_(proxy_sendsig)(target, sigNo);
1785 VG_(ksigdelset)(&proc_pending, sigNo);
jsgf855d93d2003-10-13 22:26:55 +00001786 }
1787 }
1788
fitzhardingee1c06d82003-10-30 07:21:44 +00001789 /* restore signal mask */
1790 VG_(restore_all_host_signals) (&set);
jsgf855d93d2003-10-13 22:26:55 +00001791}
sewardjde4a1d02002-03-22 01:27:54 +00001792
sewardj018f7622002-05-15 21:13:39 +00001793/* At startup, copy the process' real signal state to the SCSS.
1794 Whilst doing this, block all real signals. Then calculate SKSS and
1795 set the kernel to that. Also initialise DCSS.
sewardjde4a1d02002-03-22 01:27:54 +00001796*/
1797void VG_(sigstartup_actions) ( void )
1798{
1799 Int i, ret;
sewardjde4a1d02002-03-22 01:27:54 +00001800 vki_ksigset_t saved_procmask;
1801 vki_kstack_t altstack_info;
1802 vki_ksigaction sa;
1803
sewardj2e93c502002-04-12 11:12:52 +00001804 /* VG_(printf)("SIGSTARTUP\n"); */
jsgf855d93d2003-10-13 22:26:55 +00001805 /* Block all signals. saved_procmask remembers the previous mask,
1806 which the first thread inherits.
1807 */
sewardj2e93c502002-04-12 11:12:52 +00001808 VG_(block_all_host_signals)( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00001809
fitzhardingee1c06d82003-10-30 07:21:44 +00001810 /* clear process-wide pending signal set */
1811 VG_(ksigemptyset)(&proc_pending);
1812
jsgf855d93d2003-10-13 22:26:55 +00001813 /* Set the signal mask which the scheduler LWP should maintain from
1814 now on. */
1815 set_main_sigmask();
1816
sewardj018f7622002-05-15 21:13:39 +00001817 /* Copy per-signal settings to SCSS. */
1818 for (i = 1; i <= VKI_KNSIG; i++) {
1819
1820 /* Get the old host action */
1821 ret = VG_(ksigaction)(i, NULL, &sa);
1822 vg_assert(ret == 0);
1823
1824 if (VG_(clo_trace_signals))
1825 VG_(printf)("snaffling handler 0x%x for signal %d\n",
1826 (Addr)(sa.ksa_handler), i );
1827
1828 vg_scss.scss_per_sig[i].scss_handler = sa.ksa_handler;
1829 vg_scss.scss_per_sig[i].scss_flags = sa.ksa_flags;
1830 vg_scss.scss_per_sig[i].scss_mask = sa.ksa_mask;
1831 vg_scss.scss_per_sig[i].scss_restorer = sa.ksa_restorer;
1832 }
1833
jsgf855d93d2003-10-13 22:26:55 +00001834 /* Our private internal signals are treated as ignored */
1835 vg_scss.scss_per_sig[VKI_SIGVGINT].scss_handler = VKI_SIG_IGN;
1836 vg_scss.scss_per_sig[VKI_SIGVGINT].scss_flags = VKI_SA_SIGINFO;
1837 VG_(ksigfillset)(&vg_scss.scss_per_sig[VKI_SIGVGINT].scss_mask);
1838 vg_scss.scss_per_sig[VKI_SIGVGKILL].scss_handler = VKI_SIG_IGN;
1839 vg_scss.scss_per_sig[VKI_SIGVGKILL].scss_flags = VKI_SA_SIGINFO;
1840 VG_(ksigfillset)(&vg_scss.scss_per_sig[VKI_SIGVGKILL].scss_mask);
1841
sewardj2342c972002-05-22 23:34:20 +00001842 /* Copy the alt stack, if any. */
1843 ret = VG_(ksigaltstack)(NULL, &vg_scss.altstack);
1844 vg_assert(ret == 0);
1845
sewardj018f7622002-05-15 21:13:39 +00001846 /* Copy the process' signal mask into the root thread. */
1847 vg_assert(VG_(threads)[1].status == VgTs_Runnable);
1848 VG_(threads)[1].sig_mask = saved_procmask;
jsgf855d93d2003-10-13 22:26:55 +00001849 VG_(proxy_setsigmask)(1);
sewardj018f7622002-05-15 21:13:39 +00001850
njn12a57142003-04-30 20:49:10 +00001851 /* Register an alternative stack for our own signal handler to run on. */
sewardjde4a1d02002-03-22 01:27:54 +00001852 altstack_info.ss_sp = &(VG_(sigstack)[0]);
njn6eba4ef2003-05-01 08:06:41 +00001853 altstack_info.ss_size = VG_SIGSTACK_SIZE_W * sizeof(UInt);
sewardjde4a1d02002-03-22 01:27:54 +00001854 altstack_info.ss_flags = 0;
1855 ret = VG_(ksigaltstack)(&altstack_info, NULL);
1856 if (ret != 0) {
njne427a662002-10-02 11:08:25 +00001857 VG_(core_panic)(
sewardjde4a1d02002-03-22 01:27:54 +00001858 "vg_sigstartup_actions: couldn't install alternative sigstack");
1859 }
1860 if (VG_(clo_trace_signals)) {
1861 VG_(message)(Vg_DebugExtraMsg,
1862 "vg_sigstartup_actions: sigstack installed ok");
1863 }
1864
sewardj7a61d912002-04-25 01:27:35 +00001865 /* DEBUGGING HACK */
1866 /* VG_(ksignal)(VKI_SIGUSR1, &VG_(oursignalhandler)); */
1867
sewardj018f7622002-05-15 21:13:39 +00001868 /* Calculate SKSS and apply it. This also sets the initial kernel
1869 mask we need to run with. */
1870 VG_(handle_SCSS_change)( True /* forced update */ );
jsgf855d93d2003-10-13 22:26:55 +00001871
sewardjde4a1d02002-03-22 01:27:54 +00001872}
1873
1874
1875/* Copy the process' sim signal state to the real state,
1876 for when we transfer from the simulated to real CPU.
1877 PROBLEM: what if we're running a signal handler when we
1878 get here? Hmm.
1879 I guess we wind up in vg_signalreturn_bogusRA, *or* the
1880 handler has done/will do a longjmp, in which case we're ok.
sewardjde4a1d02002-03-22 01:27:54 +00001881*/
1882void VG_(sigshutdown_actions) ( void )
1883{
1884 Int i, ret;
1885
sewardjde4a1d02002-03-22 01:27:54 +00001886 vki_ksigset_t saved_procmask;
1887 vki_ksigaction sa;
1888
sewardj2e93c502002-04-12 11:12:52 +00001889 VG_(block_all_host_signals)( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00001890
sewardj018f7622002-05-15 21:13:39 +00001891 /* Copy per-signal settings from SCSS. */
sewardjb48e5002002-05-13 00:16:03 +00001892 for (i = 1; i <= VKI_KNSIG; i++) {
sewardj018f7622002-05-15 21:13:39 +00001893
1894 sa.ksa_handler = vg_scss.scss_per_sig[i].scss_handler;
1895 sa.ksa_flags = vg_scss.scss_per_sig[i].scss_flags;
1896 sa.ksa_mask = vg_scss.scss_per_sig[i].scss_mask;
1897 sa.ksa_restorer = vg_scss.scss_per_sig[i].scss_restorer;
1898
1899 if (VG_(clo_trace_signals))
1900 VG_(printf)("restoring handler 0x%x for signal %d\n",
1901 (Addr)(sa.ksa_handler), i );
1902
sewardje8fb72e2002-06-28 02:08:28 +00001903 /* Set the old host action */
sewardj018f7622002-05-15 21:13:39 +00001904 ret = VG_(ksigaction)(i, &sa, NULL);
sewardje8fb72e2002-06-28 02:08:28 +00001905 if (i != VKI_SIGKILL && i != VKI_SIGSTOP)
1906 vg_assert(ret == 0);
sewardjde4a1d02002-03-22 01:27:54 +00001907 }
1908
sewardj2342c972002-05-22 23:34:20 +00001909 /* Restore the sig alt stack. */
1910 ret = VG_(ksigaltstack)(&vg_scss.altstack, NULL);
1911 vg_assert(ret == 0);
1912
sewardj018f7622002-05-15 21:13:39 +00001913 /* A bit of a kludge -- set the sigmask to that of the root
1914 thread. */
1915 vg_assert(VG_(threads)[1].status != VgTs_Empty);
1916 VG_(restore_all_host_signals)( &VG_(threads)[1].sig_mask );
sewardjde4a1d02002-03-22 01:27:54 +00001917}
1918
1919
sewardjde4a1d02002-03-22 01:27:54 +00001920/*--------------------------------------------------------------------*/
1921/*--- end vg_signals.c ---*/
1922/*--------------------------------------------------------------------*/