blob: 29e7d4c6b151313f2ba17f9a52cd34e2e1b4fa74 [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
nethercotebb1c9912004-01-04 16:43:23 +000011 Copyright (C) 2000-2004 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
nethercote75d26242004-08-01 22:59:18 +000067 If we get a synchronous signal, we longjmp back into the scheduler,
jsgf855d93d2003-10-13 22:26:55 +000068 since we can't resume executing the client code. The scheduler
69 immediately starts signal delivery to the thread which generated
70 the signal.
71
72 On older kernels without thread-groups, we need to poll the pending
73 signal with sigtimedwait() and farm any signals off to the
74 appropriate proxy LWP.
75 */
sewardjde4a1d02002-03-22 01:27:54 +000076
nethercotef1e5e152004-09-01 23:58:16 +000077#include "core.h"
jsgf855d93d2003-10-13 22:26:55 +000078#include <stddef.h> /* OK, no library dependencies */
sewardjde4a1d02002-03-22 01:27:54 +000079
sewardj018f7622002-05-15 21:13:39 +000080/* Define to give more sanity checking for signals. */
81#define DEBUG_SIGNALS
82
83
84/* ---------------------------------------------------------------------
85 Forwards decls.
86 ------------------------------------------------------------------ */
87
jsgf855d93d2003-10-13 22:26:55 +000088static void vg_sync_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * );
89static void vg_async_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * );
90static void vg_babyeater ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * );
91static void proxy_sigvg_handler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext * );
sewardj018f7622002-05-15 21:13:39 +000092
jsgf855d93d2003-10-13 22:26:55 +000093static Bool is_correct_sigmask(void);
94static const Char *signame(Int sigNo);
sewardj018f7622002-05-15 21:13:39 +000095
96/* ---------------------------------------------------------------------
nethercote759dda32004-08-07 18:16:56 +000097 Signal stack
98 ------------------------------------------------------------------ */
99
100/* Valgrind's signal stack size, in words */
101#define VG_SIGSTACK_SIZE_W 10000
102
103/* We have to ask for signals to be delivered on an alternative
104 stack, since it is possible, although unlikely, that we'll have to run
105 client code from inside the Valgrind-installed signal handler. */
106static Addr sigstack[VG_SIGSTACK_SIZE_W];
107
108extern void VG_(get_sigstack_bounds)( Addr* low, Addr* high )
109{
110 *low = (Addr) & sigstack[0];
111 *high = (Addr) & sigstack[VG_SIGSTACK_SIZE_W];
112}
113
114/* ---------------------------------------------------------------------
sewardj018f7622002-05-15 21:13:39 +0000115 HIGH LEVEL STUFF TO DO WITH SIGNALS: POLICY (MOSTLY)
116 ------------------------------------------------------------------ */
117
jsgf855d93d2003-10-13 22:26:55 +0000118/* If set to true, the currently running kernel doesn't do the right
119 thing with signals and LWPs, so we need to do our own. */
120Bool VG_(do_signal_routing) = False;
121
fitzhardingee1c06d82003-10-30 07:21:44 +0000122/* Set of signal which are pending for the whole process. This is
123 only used when we're doing signal routing, and this is a place to
124 remember pending signals which we can't keep actually pending for
125 some reason. */
126static vki_ksigset_t proc_pending; /* process-wide pending signals */
127
jsgf855d93d2003-10-13 22:26:55 +0000128/* Since we use a couple of RT signals, we need to handle allocating
129 the rest for application use. */
130Int VG_(sig_rtmin) = VKI_SIGRTUSERMIN;
131Int VG_(sig_rtmax) = VKI_SIGRTMAX;
132
133Int VG_(sig_alloc_rtsig)(Int high)
134{
135 Int ret;
136
137 if (VG_(sig_rtmin) >= VG_(sig_rtmax))
138 ret = -1;
139 else
140 ret = high ? VG_(sig_rtmin)++ : VG_(sig_rtmax)--;
141
142 vg_assert(ret >= VKI_SIGRTUSERMIN);
143
144 return ret;
145}
146
sewardjde4a1d02002-03-22 01:27:54 +0000147/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000148 Signal state for this process.
149 ------------------------------------------------------------------ */
150
sewardj018f7622002-05-15 21:13:39 +0000151
sewardjb48e5002002-05-13 00:16:03 +0000152/* Base-ment of these arrays[VKI_KNSIG].
153
154 Valid signal numbers are 1 .. VKI_KNSIG inclusive.
155 Rather than subtracting 1 for indexing these arrays, which
156 is tedious and error-prone, they are simply dimensioned 1 larger,
157 and entry [0] is not used.
158 */
159
sewardjb48e5002002-05-13 00:16:03 +0000160
sewardj018f7622002-05-15 21:13:39 +0000161/* -----------------------------------------------------
162 Static client signal state (SCSS). This is the state
163 that the client thinks it has the kernel in.
164 SCSS records verbatim the client's settings. These
165 are mashed around only when SKSS is calculated from it.
166 -------------------------------------------------- */
sewardjb48e5002002-05-13 00:16:03 +0000167
sewardj018f7622002-05-15 21:13:39 +0000168typedef
169 struct {
170 void* scss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN or ptr to
171 client's handler */
172 UInt scss_flags;
173 vki_ksigset_t scss_mask;
174 void* scss_restorer; /* god knows; we ignore it. */
175 }
176 SCSS_Per_Signal;
sewardjb48e5002002-05-13 00:16:03 +0000177
sewardj018f7622002-05-15 21:13:39 +0000178typedef
179 struct {
sewardj2342c972002-05-22 23:34:20 +0000180 /* per-signal info */
sewardj018f7622002-05-15 21:13:39 +0000181 SCSS_Per_Signal scss_per_sig[1+VKI_KNSIG];
sewardj2342c972002-05-22 23:34:20 +0000182
sewardj018f7622002-05-15 21:13:39 +0000183 /* Additional elements to SCSS not stored here:
184 - for each thread, the thread's blocking mask
185 - for each thread in WaitSIG, the set of waited-on sigs
186 */
187 }
188 SCSS;
sewardjb48e5002002-05-13 00:16:03 +0000189
sewardj018f7622002-05-15 21:13:39 +0000190static SCSS vg_scss;
191
192
193/* -----------------------------------------------------
194 Static kernel signal state (SKSS). This is the state
195 that we have the kernel in. It is computed from SCSS.
196 -------------------------------------------------- */
197
198/* Let's do:
199 sigprocmask assigns to all thread masks
200 so that at least everything is always consistent
201 Flags:
jsgf855d93d2003-10-13 22:26:55 +0000202 SA_SIGINFO -- we always set it, and honour it for the client
sewardj018f7622002-05-15 21:13:39 +0000203 SA_NOCLDSTOP -- passed to kernel
204 SA_ONESHOT or SA_RESETHAND -- required; abort if not set
jsgf855d93d2003-10-13 22:26:55 +0000205 SA_RESTART -- we observe this but set our handlers to always restart
206 SA_NOMASK or SA_NODEFER -- we observe this, but our handlers block everything
sewardj018f7622002-05-15 21:13:39 +0000207 SA_ONSTACK -- currently not supported; abort if set.
jsgf855d93d2003-10-13 22:26:55 +0000208 SA_NOCLDWAIT -- we observe this, but we never set it (doesn't quite
209 work if client is blocked in a wait4() syscall)
sewardjb48e5002002-05-13 00:16:03 +0000210*/
sewardjde4a1d02002-03-22 01:27:54 +0000211
sewardj77e466c2002-04-14 02:29:29 +0000212
sewardj018f7622002-05-15 21:13:39 +0000213typedef
214 struct {
215 void* skss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN
216 or ptr to our handler */
217 UInt skss_flags;
218 /* There is no skss_mask, since we know that we will always ask
jsgf855d93d2003-10-13 22:26:55 +0000219 for all signals to be blocked in our sighandlers. */
sewardj018f7622002-05-15 21:13:39 +0000220 /* Also there is no skss_restorer. */
221 }
222 SKSS_Per_Signal;
sewardjde4a1d02002-03-22 01:27:54 +0000223
sewardj018f7622002-05-15 21:13:39 +0000224typedef
225 struct {
226 SKSS_Per_Signal skss_per_sig[1+VKI_KNSIG];
sewardj018f7622002-05-15 21:13:39 +0000227 }
228 SKSS;
229
230static SKSS vg_skss;
sewardjde4a1d02002-03-22 01:27:54 +0000231
jsgf855d93d2003-10-13 22:26:55 +0000232Bool VG_(is_sig_ign)(Int sigNo)
233{
234 vg_assert(sigNo >= 1 && sigNo <= VKI_KNSIG);
sewardj2e93c502002-04-12 11:12:52 +0000235
jsgf855d93d2003-10-13 22:26:55 +0000236 return vg_scss.scss_per_sig[sigNo].scss_handler == VKI_SIG_IGN;
237}
sewardjb48e5002002-05-13 00:16:03 +0000238
sewardj018f7622002-05-15 21:13:39 +0000239/* ---------------------------------------------------------------------
240 Compute the SKSS required by the current SCSS.
241 ------------------------------------------------------------------ */
242
sewardj4f29ddf2002-05-03 22:29:04 +0000243static
sewardj018f7622002-05-15 21:13:39 +0000244void pp_SKSS ( void )
245{
246 Int sig;
247 VG_(printf)("\n\nSKSS:\n");
248 for (sig = 1; sig <= VKI_KNSIG; sig++) {
249 VG_(printf)("sig %d: handler 0x%x, flags 0x%x\n", sig,
250 vg_skss.skss_per_sig[sig].skss_handler,
251 vg_skss.skss_per_sig[sig].skss_flags );
sewardj77e466c2002-04-14 02:29:29 +0000252
sewardj018f7622002-05-15 21:13:39 +0000253 }
sewardj018f7622002-05-15 21:13:39 +0000254}
255
sewardj018f7622002-05-15 21:13:39 +0000256/* This is the core, clever bit. Computation is as follows:
257
258 For each signal
259 handler = if client has a handler, then our handler
jsgf855d93d2003-10-13 22:26:55 +0000260 else if client is DFL, then our handler as well
261 else (client must be IGN)
262 if (signal == SIGCHLD), then handler is vg_babyeater
263 else IGN
sewardj018f7622002-05-15 21:13:39 +0000264
jsgf855d93d2003-10-13 22:26:55 +0000265 We don't really bother with blocking signals here, because the we
266 rely on the proxyLWP having set it as part of its kernel state.
sewardj018f7622002-05-15 21:13:39 +0000267*/
268static
269void calculate_SKSS_from_SCSS ( SKSS* dst )
270{
271 Int sig;
sewardj018f7622002-05-15 21:13:39 +0000272 UInt scss_flags;
273 UInt skss_flags;
274
sewardj018f7622002-05-15 21:13:39 +0000275 for (sig = 1; sig <= VKI_KNSIG; sig++) {
jsgf855d93d2003-10-13 22:26:55 +0000276 void *skss_handler;
277 void *scss_handler;
278
sewardj018f7622002-05-15 21:13:39 +0000279 scss_handler = vg_scss.scss_per_sig[sig].scss_handler;
280 scss_flags = vg_scss.scss_per_sig[sig].scss_flags;
281
jsgf855d93d2003-10-13 22:26:55 +0000282 switch(sig) {
283 case VKI_SIGSEGV:
284 case VKI_SIGBUS:
285 case VKI_SIGFPE:
286 case VKI_SIGILL:
287 /* For these, we always want to catch them and report, even
288 if the client code doesn't. */
289 skss_handler = vg_sync_signalhandler;
290 break;
291
292 case VKI_SIGVGINT:
293 case VKI_SIGVGKILL:
294 skss_handler = proxy_sigvg_handler;
295 break;
296
297 case VKI_SIGCHLD:
298 if (scss_handler == VKI_SIG_IGN) {
299 skss_handler = vg_babyeater;
300 break;
301 }
302 /* FALLTHROUGH */
303 default:
304 if (scss_handler == VKI_SIG_IGN)
305 skss_handler = VKI_SIG_IGN;
306 else
307 skss_handler = vg_async_signalhandler;
308 break;
309 }
310
sewardj018f7622002-05-15 21:13:39 +0000311 /* Restorer */
312 /*
313 Doesn't seem like we can spin this one.
314 if (vg_scss.scss_per_sig[sig].scss_restorer != NULL)
315 VG_(unimplemented)
316 ("sigactions with non-NULL .sa_restorer field");
317 */
318
sewardj018f7622002-05-15 21:13:39 +0000319 /* Flags */
320
321 skss_flags = 0;
jsgf855d93d2003-10-13 22:26:55 +0000322
sewardj018f7622002-05-15 21:13:39 +0000323 /* SA_NOCLDSTOP: pass to kernel */
324 if (scss_flags & VKI_SA_NOCLDSTOP)
325 skss_flags |= VKI_SA_NOCLDSTOP;
jsgf855d93d2003-10-13 22:26:55 +0000326
327 /* SA_NOCLDWAIT - don't set */
328 /* XXX we could set this if we're not using wait() ourselves for
329 tracking proxyLWPs (ie, have_futex is true in
330 vg_syscalls.c. */
331
sewardj018f7622002-05-15 21:13:39 +0000332 /* SA_ONESHOT: ignore client setting */
333 /*
334 if (!(scss_flags & VKI_SA_ONESHOT))
335 VG_(unimplemented)
336 ("sigactions without SA_ONESHOT");
337 vg_assert(scss_flags & VKI_SA_ONESHOT);
338 skss_flags |= VKI_SA_ONESHOT;
339 */
jsgf855d93d2003-10-13 22:26:55 +0000340
341 /* SA_RESTART: ignore client setting and always set it for us
342 (even though we never rely on the kernel to restart a
343 syscall, we observe whether it wanted to restart the syscall
344 or not, which guides our actions) */
sewardj018f7622002-05-15 21:13:39 +0000345 skss_flags |= VKI_SA_RESTART;
jsgf855d93d2003-10-13 22:26:55 +0000346
347 /* SA_NOMASK: ignore it */
348
sewardj2342c972002-05-22 23:34:20 +0000349 /* SA_ONSTACK: client setting is irrelevant here */
350 /*
sewardj018f7622002-05-15 21:13:39 +0000351 if (scss_flags & VKI_SA_ONSTACK)
352 VG_(unimplemented)
353 ("signals on an alternative stack (SA_ONSTACK)");
354 vg_assert(!(scss_flags & VKI_SA_ONSTACK));
sewardj2342c972002-05-22 23:34:20 +0000355 */
sewardj018f7622002-05-15 21:13:39 +0000356 /* ... but WE ask for on-stack ourselves ... */
357 skss_flags |= VKI_SA_ONSTACK;
358
jsgf855d93d2003-10-13 22:26:55 +0000359 /* always ask for SA_SIGINFO */
360 skss_flags |= VKI_SA_SIGINFO;
sewardj018f7622002-05-15 21:13:39 +0000361
fitzhardinge4f10ada2004-06-03 10:00:42 +0000362 /* use our own restorer */
363 skss_flags |= VKI_SA_RESTORER;
364
jsgf855d93d2003-10-13 22:26:55 +0000365 /* Create SKSS entry for this signal. */
sewardj018f7622002-05-15 21:13:39 +0000366
sewardj6a3c26e2002-05-23 17:09:43 +0000367 if (sig != VKI_SIGKILL && sig != VKI_SIGSTOP)
368 dst->skss_per_sig[sig].skss_handler = skss_handler;
369 else
370 dst->skss_per_sig[sig].skss_handler = VKI_SIG_DFL;
371
sewardj018f7622002-05-15 21:13:39 +0000372 dst->skss_per_sig[sig].skss_flags = skss_flags;
373 }
374
375 /* Sanity checks. */
376 vg_assert(dst->skss_per_sig[VKI_SIGKILL].skss_handler
377 == VKI_SIG_DFL);
378 vg_assert(dst->skss_per_sig[VKI_SIGSTOP].skss_handler
379 == VKI_SIG_DFL);
sewardj018f7622002-05-15 21:13:39 +0000380
381 if (0)
382 pp_SKSS();
383}
384
385
386/* ---------------------------------------------------------------------
387 After a possible SCSS change, update SKSS and the kernel itself.
388 ------------------------------------------------------------------ */
389
nethercote9dd11512004-08-04 15:31:30 +0000390static void handle_SCSS_change ( Bool force_update )
sewardj018f7622002-05-15 21:13:39 +0000391{
392 Int res, sig;
393 SKSS skss_old;
394 vki_ksigaction ksa, ksa_old;
395
jsgf855d93d2003-10-13 22:26:55 +0000396 vg_assert(is_correct_sigmask());
sewardj018f7622002-05-15 21:13:39 +0000397
398 /* Remember old SKSS and calculate new one. */
399 skss_old = vg_skss;
400 calculate_SKSS_from_SCSS ( &vg_skss );
401
402 /* Compare the new SKSS entries vs the old ones, and update kernel
403 where they differ. */
404 for (sig = 1; sig <= VKI_KNSIG; sig++) {
405
406 /* Trying to do anything with SIGKILL is pointless; just ignore
407 it. */
408 if (sig == VKI_SIGKILL || sig == VKI_SIGSTOP)
409 continue;
410
sewardj018f7622002-05-15 21:13:39 +0000411 if (!force_update) {
412 if ((skss_old.skss_per_sig[sig].skss_handler
413 == vg_skss.skss_per_sig[sig].skss_handler)
414 && (skss_old.skss_per_sig[sig].skss_flags
415 == vg_skss.skss_per_sig[sig].skss_flags))
416 /* no difference */
417 continue;
418 }
419
420 ksa.ksa_handler = vg_skss.skss_per_sig[sig].skss_handler;
421 ksa.ksa_flags = vg_skss.skss_per_sig[sig].skss_flags;
fitzhardinge4f10ada2004-06-03 10:00:42 +0000422 ksa.ksa_restorer = VG_(sigreturn);
423
sewardj018f7622002-05-15 21:13:39 +0000424 vg_assert(ksa.ksa_flags & VKI_SA_ONSTACK);
425 VG_(ksigfillset)( &ksa.ksa_mask );
426 VG_(ksigdelset)( &ksa.ksa_mask, VKI_SIGKILL );
427 VG_(ksigdelset)( &ksa.ksa_mask, VKI_SIGSTOP );
sewardj018f7622002-05-15 21:13:39 +0000428
429 if (VG_(clo_trace_signals))
430 VG_(message)(Vg_DebugMsg,
431 "setting ksig %d to: hdlr 0x%x, flags 0x%x, "
432 "mask(63..0) 0x%x 0x%x",
433 sig, ksa.ksa_handler,
434 ksa.ksa_flags,
435 ksa.ksa_mask.ws[1],
436 ksa.ksa_mask.ws[0]
437 );
438
439 res = VG_(ksigaction)( sig, &ksa, &ksa_old );
440 vg_assert(res == 0);
441
442 /* Since we got the old sigaction more or less for free, might
443 as well extract the maximum sanity-check value from it. */
444 if (!force_update) {
445 vg_assert(ksa_old.ksa_handler
446 == skss_old.skss_per_sig[sig].skss_handler);
447 vg_assert(ksa_old.ksa_flags
448 == skss_old.skss_per_sig[sig].skss_flags);
449 vg_assert(ksa_old.ksa_restorer
fitzhardingedc4d4f42004-06-03 17:12:07 +0000450 == VG_(sigreturn));
sewardj018f7622002-05-15 21:13:39 +0000451 VG_(ksigaddset)( &ksa_old.ksa_mask, VKI_SIGKILL );
452 VG_(ksigaddset)( &ksa_old.ksa_mask, VKI_SIGSTOP );
453 vg_assert(VG_(kisfullsigset)( &ksa_old.ksa_mask ));
454 }
455 }
sewardj018f7622002-05-15 21:13:39 +0000456}
457
458
459/* ---------------------------------------------------------------------
460 Update/query SCSS in accordance with client requests.
461 ------------------------------------------------------------------ */
462
sewardj2342c972002-05-22 23:34:20 +0000463/* Logic for this alt-stack stuff copied directly from do_sigaltstack
464 in kernel/signal.[ch] */
465
466/* True if we are on the alternate signal stack. */
nethercote511e4062004-09-11 13:34:08 +0000467static Int on_sig_stack ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000468{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000469 ThreadState *tst = VG_(get_ThreadState)(tid);
470
nethercote511e4062004-09-11 13:34:08 +0000471 return (m_SP - (Addr)tst->altstack.ss_sp < tst->altstack.ss_size);
sewardj2342c972002-05-22 23:34:20 +0000472}
473
nethercote511e4062004-09-11 13:34:08 +0000474static Int sas_ss_flags ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000475{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000476 ThreadState *tst = VG_(get_ThreadState)(tid);
477
478 return (tst->altstack.ss_size == 0
sewardj2342c972002-05-22 23:34:20 +0000479 ? VKI_SS_DISABLE
nethercote511e4062004-09-11 13:34:08 +0000480 : on_sig_stack(tid, m_SP) ? VKI_SS_ONSTACK : 0);
sewardj2342c972002-05-22 23:34:20 +0000481}
482
483
484void VG_(do__NR_sigaltstack) ( ThreadId tid )
485{
486 vki_kstack_t* ss;
487 vki_kstack_t* oss;
nethercote511e4062004-09-11 13:34:08 +0000488 Addr m_SP;
sewardj2342c972002-05-22 23:34:20 +0000489
490 vg_assert(VG_(is_valid_tid)(tid));
nethercote511e4062004-09-11 13:34:08 +0000491 ss = (vki_kstack_t*)PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch);
492 oss = (vki_kstack_t*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch);
493 m_SP = ARCH_STACK_PTR(VG_(threads)[tid].arch);
sewardj2342c972002-05-22 23:34:20 +0000494
495 if (VG_(clo_trace_signals))
496 VG_(message)(Vg_DebugExtraMsg,
497 "__NR_sigaltstack: tid %d, "
nethercote511e4062004-09-11 13:34:08 +0000498 "ss %p, oss %p (current SP %p)",
499 tid, (void*)ss, (void*)oss, (void*)m_SP );
sewardj2342c972002-05-22 23:34:20 +0000500
501 if (oss != NULL) {
fitzhardinge98c4dc02004-03-16 08:27:29 +0000502 oss->ss_sp = VG_(threads)[tid].altstack.ss_sp;
503 oss->ss_size = VG_(threads)[tid].altstack.ss_size;
nethercote511e4062004-09-11 13:34:08 +0000504 oss->ss_flags = VG_(threads)[tid].altstack.ss_flags | sas_ss_flags(tid, m_SP);
sewardj2342c972002-05-22 23:34:20 +0000505 }
506
507 if (ss != NULL) {
nethercote511e4062004-09-11 13:34:08 +0000508 if (on_sig_stack(tid, ARCH_STACK_PTR(VG_(threads)[tid].arch))) {
njnd3040452003-05-19 15:04:06 +0000509 SET_SYSCALL_RETVAL(tid, -VKI_EPERM);
sewardj2342c972002-05-22 23:34:20 +0000510 return;
511 }
512 if (ss->ss_flags != VKI_SS_DISABLE
513 && ss->ss_flags != VKI_SS_ONSTACK
514 && ss->ss_flags != 0) {
njnd3040452003-05-19 15:04:06 +0000515 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
sewardj2342c972002-05-22 23:34:20 +0000516 return;
517 }
518 if (ss->ss_flags == VKI_SS_DISABLE) {
fitzhardinge98c4dc02004-03-16 08:27:29 +0000519 VG_(threads)[tid].altstack.ss_flags = VKI_SS_DISABLE;
sewardj2342c972002-05-22 23:34:20 +0000520 } else {
521 if (ss->ss_size < VKI_MINSIGSTKSZ) {
njnd3040452003-05-19 15:04:06 +0000522 SET_SYSCALL_RETVAL(tid, -VKI_ENOMEM);
sewardj2342c972002-05-22 23:34:20 +0000523 return;
524 }
jsgf855d93d2003-10-13 22:26:55 +0000525
fitzhardinge98c4dc02004-03-16 08:27:29 +0000526 VG_(threads)[tid].altstack.ss_sp = ss->ss_sp;
527 VG_(threads)[tid].altstack.ss_size = ss->ss_size;
528 VG_(threads)[tid].altstack.ss_flags = 0;
sewardj2342c972002-05-22 23:34:20 +0000529 }
sewardj2342c972002-05-22 23:34:20 +0000530 }
njnd3040452003-05-19 15:04:06 +0000531 SET_SYSCALL_RETVAL(tid, 0);
sewardj2342c972002-05-22 23:34:20 +0000532}
533
534
sewardj018f7622002-05-15 21:13:39 +0000535void VG_(do__NR_sigaction) ( ThreadId tid )
536{
537 Int signo;
538 vki_ksigaction* new_act;
539 vki_ksigaction* old_act;
jsgf855d93d2003-10-13 22:26:55 +0000540
541 vg_assert(is_correct_sigmask());
sewardj018f7622002-05-15 21:13:39 +0000542
543 vg_assert(VG_(is_valid_tid)(tid));
nethercotebb4222b2004-09-10 17:42:11 +0000544 signo = PLATFORM_SYSCALL_ARG1(VG_(threads)[tid].arch);
545 new_act = (vki_ksigaction*)PLATFORM_SYSCALL_ARG2(VG_(threads)[tid].arch);
546 old_act = (vki_ksigaction*)PLATFORM_SYSCALL_ARG3(VG_(threads)[tid].arch);
sewardj018f7622002-05-15 21:13:39 +0000547
548 if (VG_(clo_trace_signals))
549 VG_(message)(Vg_DebugExtraMsg,
550 "__NR_sigaction: tid %d, sigNo %d, "
551 "new 0x%x, old 0x%x, new flags 0x%x",
552 tid, signo, (UInt)new_act, (UInt)old_act,
553 (UInt)(new_act ? new_act->ksa_flags : 0) );
554
555 /* Rule out various error conditions. The aim is to ensure that if
556 when the call is passed to the kernel it will definitely
557 succeed. */
558
559 /* Reject out-of-range signal numbers. */
560 if (signo < 1 || signo > VKI_KNSIG) goto bad_signo;
561
jsgf855d93d2003-10-13 22:26:55 +0000562 /* don't let them use our signals */
563 if ( (signo == VKI_SIGVGINT || signo == VKI_SIGVGKILL)
564 && new_act
565 && !(new_act->ksa_handler == VKI_SIG_DFL || new_act->ksa_handler == VKI_SIG_IGN) )
nethercote9c42a0f2003-11-17 10:37:19 +0000566 goto bad_signo_reserved;
jsgf855d93d2003-10-13 22:26:55 +0000567
sewardj018f7622002-05-15 21:13:39 +0000568 /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
569 if ( (signo == VKI_SIGKILL || signo == VKI_SIGSTOP)
570 && new_act
571 && new_act->ksa_handler != VKI_SIG_DFL)
572 goto bad_sigkill_or_sigstop;
573
574 /* If the client supplied non-NULL old_act, copy the relevant SCSS
575 entry into it. */
576 if (old_act) {
577 old_act->ksa_handler = vg_scss.scss_per_sig[signo].scss_handler;
578 old_act->ksa_flags = vg_scss.scss_per_sig[signo].scss_flags;
579 old_act->ksa_mask = vg_scss.scss_per_sig[signo].scss_mask;
580 old_act->ksa_restorer = vg_scss.scss_per_sig[signo].scss_restorer;
581 }
582
583 /* And now copy new SCSS entry from new_act. */
584 if (new_act) {
585 vg_scss.scss_per_sig[signo].scss_handler = new_act->ksa_handler;
586 vg_scss.scss_per_sig[signo].scss_flags = new_act->ksa_flags;
587 vg_scss.scss_per_sig[signo].scss_mask = new_act->ksa_mask;
588 vg_scss.scss_per_sig[signo].scss_restorer = new_act->ksa_restorer;
589 }
590
591 /* All happy bunnies ... */
592 if (new_act) {
nethercote9dd11512004-08-04 15:31:30 +0000593 handle_SCSS_change( False /* lazy update */ );
sewardj018f7622002-05-15 21:13:39 +0000594 }
njnd3040452003-05-19 15:04:06 +0000595 SET_SYSCALL_RETVAL(tid, 0);
sewardj018f7622002-05-15 21:13:39 +0000596 return;
597
598 bad_signo:
sewardj37d06f22003-09-17 21:48:26 +0000599 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1)
njn25e49d8e72002-09-23 09:36:25 +0000600 VG_(message)(Vg_UserMsg,
nethercote9c42a0f2003-11-17 10:37:19 +0000601 "Warning: bad signal number %d in sigaction()",
njn25e49d8e72002-09-23 09:36:25 +0000602 signo);
njnd3040452003-05-19 15:04:06 +0000603 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
sewardj018f7622002-05-15 21:13:39 +0000604 return;
605
nethercote9c42a0f2003-11-17 10:37:19 +0000606 bad_signo_reserved:
fitzhardingebf459872003-11-18 16:55:33 +0000607 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1) {
nethercote9c42a0f2003-11-17 10:37:19 +0000608 VG_(message)(Vg_UserMsg,
609 "Warning: ignored attempt to set %s handler in sigaction();",
610 signame(signo));
611 VG_(message)(Vg_UserMsg,
612 " the %s signal is used internally by Valgrind",
613 signame(signo));
fitzhardingebf459872003-11-18 16:55:33 +0000614 }
nethercote9c42a0f2003-11-17 10:37:19 +0000615 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
616 return;
617
sewardj018f7622002-05-15 21:13:39 +0000618 bad_sigkill_or_sigstop:
sewardj37d06f22003-09-17 21:48:26 +0000619 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1)
njn25e49d8e72002-09-23 09:36:25 +0000620 VG_(message)(Vg_UserMsg,
nethercote9c42a0f2003-11-17 10:37:19 +0000621 "Warning: ignored attempt to set %s handler in sigaction();",
jsgf855d93d2003-10-13 22:26:55 +0000622 signame(signo));
nethercote9c42a0f2003-11-17 10:37:19 +0000623 VG_(message)(Vg_UserMsg,
624 " the %s signal is uncatchable",
625 signame(signo));
njnd3040452003-05-19 15:04:06 +0000626 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
sewardj018f7622002-05-15 21:13:39 +0000627 return;
628}
629
630
631static
632void do_sigprocmask_bitops ( Int vki_how,
633 vki_ksigset_t* orig_set,
634 vki_ksigset_t* modifier )
635{
636 switch (vki_how) {
637 case VKI_SIG_BLOCK:
638 VG_(ksigaddset_from_set)( orig_set, modifier );
639 break;
640 case VKI_SIG_UNBLOCK:
641 VG_(ksigdelset_from_set)( orig_set, modifier );
642 break;
643 case VKI_SIG_SETMASK:
644 *orig_set = *modifier;
645 break;
646 default:
njne427a662002-10-02 11:08:25 +0000647 VG_(core_panic)("do_sigprocmask_bitops");
sewardj018f7622002-05-15 21:13:39 +0000648 break;
649 }
650}
651
jsgf855d93d2003-10-13 22:26:55 +0000652/*
653 This updates the thread's signal mask. There's no such thing as a
654 process-wide signal mask.
sewardj018f7622002-05-15 21:13:39 +0000655
656 Note that the thread signal masks are an implicit part of SCSS,
657 which is why this routine is allowed to mess with them.
658*/
659static
660void do_setmask ( ThreadId tid,
661 Int how,
662 vki_ksigset_t* newset,
663 vki_ksigset_t* oldset )
664{
jsgf855d93d2003-10-13 22:26:55 +0000665 vg_assert(is_correct_sigmask());
sewardj018f7622002-05-15 21:13:39 +0000666
667 if (VG_(clo_trace_signals))
sewardja464e5c2002-05-23 17:34:49 +0000668 VG_(message)(Vg_DebugExtraMsg,
jsgf855d93d2003-10-13 22:26:55 +0000669 "do_setmask: tid = %d how = %d (%s), set = %p %08x%08x",
670 tid, how,
671 how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
672 how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
673 how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
674 newset, newset ? newset->ws[1] : 0, newset ? newset->ws[0] : 0
675 );
sewardj018f7622002-05-15 21:13:39 +0000676
jsgf855d93d2003-10-13 22:26:55 +0000677 /* Just do this thread. */
678 vg_assert(VG_(is_valid_tid)(tid));
679 if (oldset) {
680 *oldset = VG_(threads)[tid].eff_sig_mask;
681 if (VG_(clo_trace_signals))
682 VG_(message)(Vg_DebugExtraMsg,
683 "\toldset=%p %08x%08x",
684 oldset, oldset->ws[1], oldset->ws[0]);
sewardj018f7622002-05-15 21:13:39 +0000685 }
sewardj018f7622002-05-15 21:13:39 +0000686 if (newset) {
jsgf855d93d2003-10-13 22:26:55 +0000687 do_sigprocmask_bitops (how, &VG_(threads)[tid].sig_mask, newset );
688 VG_(ksigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGKILL);
689 VG_(ksigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGSTOP);
690 VG_(proxy_setsigmask)(tid);
sewardj018f7622002-05-15 21:13:39 +0000691 }
jsgf855d93d2003-10-13 22:26:55 +0000692
693 vg_assert(is_correct_sigmask());
sewardj018f7622002-05-15 21:13:39 +0000694}
695
696
697void VG_(do__NR_sigprocmask) ( ThreadId tid,
698 Int how,
699 vki_ksigset_t* set,
700 vki_ksigset_t* oldset )
701{
jsgf855d93d2003-10-13 22:26:55 +0000702 switch(how) {
703 case VKI_SIG_BLOCK:
704 case VKI_SIG_UNBLOCK:
705 case VKI_SIG_SETMASK:
sewardj018f7622002-05-15 21:13:39 +0000706 vg_assert(VG_(is_valid_tid)(tid));
jsgf855d93d2003-10-13 22:26:55 +0000707 /* Syscall returns 0 (success) to its thread. Set this up before
708 calling do_setmask() because we may get a signal as part of
709 setting the mask, which will confuse things.
710 */
njnd3040452003-05-19 15:04:06 +0000711 SET_SYSCALL_RETVAL(tid, 0);
jsgf855d93d2003-10-13 22:26:55 +0000712 do_setmask ( tid, how, set, oldset );
713
714 VG_(route_signals)(); /* if we're routing, do something before returning */
715 break;
716
717 default:
sewardj018f7622002-05-15 21:13:39 +0000718 VG_(message)(Vg_DebugMsg,
719 "sigprocmask: unknown `how' field %d", how);
njnd3040452003-05-19 15:04:06 +0000720 SET_SYSCALL_RETVAL(tid, -VKI_EINVAL);
jsgf855d93d2003-10-13 22:26:55 +0000721 break;
sewardj018f7622002-05-15 21:13:39 +0000722 }
723}
724
725
726void VG_(do_pthread_sigmask_SCSS_upd) ( ThreadId tid,
727 Int how,
728 vki_ksigset_t* set,
729 vki_ksigset_t* oldset )
730{
731 /* Assume that how has been validated by caller. */
732 vg_assert(how == VKI_SIG_BLOCK || how == VKI_SIG_UNBLOCK
733 || how == VKI_SIG_SETMASK);
734 vg_assert(VG_(is_valid_tid)(tid));
735 do_setmask ( tid, how, set, oldset );
736 /* The request return code is set in do_pthread_sigmask */
737}
738
739
sewardj018f7622002-05-15 21:13:39 +0000740/* ---------------------------------------------------------------------
741 LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
742 ------------------------------------------------------------------ */
sewardj77e466c2002-04-14 02:29:29 +0000743
sewardj2e93c502002-04-12 11:12:52 +0000744/* ---------------------------------------------------------------------
745 Handy utilities to block/restore all host signals.
746 ------------------------------------------------------------------ */
747
748/* Block all host signals, dumping the old mask in *saved_mask. */
749void VG_(block_all_host_signals) ( /* OUT */ vki_ksigset_t* saved_mask )
750{
751 Int ret;
752 vki_ksigset_t block_procmask;
753 VG_(ksigfillset)(&block_procmask);
754 ret = VG_(ksigprocmask)
755 (VKI_SIG_SETMASK, &block_procmask, saved_mask);
756 vg_assert(ret == 0);
757}
758
759/* Restore the blocking mask using the supplied saved one. */
sewardj018f7622002-05-15 21:13:39 +0000760void VG_(restore_all_host_signals) ( /* IN */ vki_ksigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +0000761{
762 Int ret;
763 ret = VG_(ksigprocmask)(VKI_SIG_SETMASK, saved_mask, NULL);
764 vg_assert(ret == 0);
765}
sewardjde4a1d02002-03-22 01:27:54 +0000766
jsgf855d93d2003-10-13 22:26:55 +0000767/* Sanity check - check the scheduler LWP has all the signals blocked
768 it is supposed to have blocked. */
769static Bool is_correct_sigmask(void)
770{
771 vki_ksigset_t mask;
772 Bool ret = True;
773
774 vg_assert(VG_(gettid)() == VG_(main_pid));
775
776#ifdef DEBUG_SIGNALS
777 VG_(ksigprocmask)(VKI_SIG_SETMASK, NULL, &mask);
778
779 /* unresumable signals */
780
781 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGSEGV);
782 VG_(ksigaddset)(&mask, VKI_SIGSEGV);
783
784 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGBUS);
785 VG_(ksigaddset)(&mask, VKI_SIGBUS);
786
787 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGFPE);
788 VG_(ksigaddset)(&mask, VKI_SIGFPE);
789
790 ret = ret && !VG_(ksigismember)(&mask, VKI_SIGILL);
791 VG_(ksigaddset)(&mask, VKI_SIGILL);
792
793 /* unblockable signals (doesn't really matter if these are
794 already present) */
795 VG_(ksigaddset)(&mask, VKI_SIGSTOP);
796 VG_(ksigaddset)(&mask, VKI_SIGKILL);
797
798 ret = ret && VG_(kisfullsigset)(&mask);
799#endif /* DEBUG_SIGNALS */
800
801 return ret;
802}
803
804/* Set the signal mask for the scheduer LWP; this should be set once
805 and left that way - all async signal handling is done in the proxy
806 LWPs. */
807static void set_main_sigmask(void)
808{
809 vki_ksigset_t mask;
810
811 VG_(ksigfillset)(&mask);
812 VG_(ksigdelset)(&mask, VKI_SIGSEGV);
813 VG_(ksigdelset)(&mask, VKI_SIGBUS);
814 VG_(ksigdelset)(&mask, VKI_SIGFPE);
815 VG_(ksigdelset)(&mask, VKI_SIGILL);
816
817 VG_(ksigprocmask)(VKI_SIG_SETMASK, &mask, NULL);
818
819 vg_assert(is_correct_sigmask());
820}
sewardjde4a1d02002-03-22 01:27:54 +0000821
822/* ---------------------------------------------------------------------
823 The signal simulation proper. A simplified version of what the
824 Linux kernel does.
825 ------------------------------------------------------------------ */
826
sewardjde4a1d02002-03-22 01:27:54 +0000827/* Set up a stack frame (VgSigContext) for the client's signal
nethercotefedd8102004-09-13 15:19:34 +0000828 handler. */
sewardjde4a1d02002-03-22 01:27:54 +0000829static
jsgf855d93d2003-10-13 22:26:55 +0000830void vg_push_signal_frame ( ThreadId tid, const vki_ksiginfo_t *siginfo )
sewardjde4a1d02002-03-22 01:27:54 +0000831{
nethercote6eec4602004-09-13 14:15:36 +0000832 Addr esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +0000833 ThreadState* tst;
jsgf855d93d2003-10-13 22:26:55 +0000834 Int sigNo = siginfo->si_signo;
sewardj2e93c502002-04-12 11:12:52 +0000835
sewardj2342c972002-05-22 23:34:20 +0000836 vg_assert(sigNo >= 1 && sigNo <= VKI_KNSIG);
sewardj018f7622002-05-15 21:13:39 +0000837 vg_assert(VG_(is_valid_tid)(tid));
838 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +0000839
jsgf855d93d2003-10-13 22:26:55 +0000840 if (VG_(clo_trace_signals))
841 VG_(message)(Vg_DebugMsg,
842 "vg_push_signal_frame (thread %d): signal %d", tid, sigNo);
843
sewardj2342c972002-05-22 23:34:20 +0000844 if (/* this signal asked to run on an alt stack */
jsgf855d93d2003-10-13 22:26:55 +0000845 (vg_scss.scss_per_sig[sigNo].scss_flags & VKI_SA_ONSTACK )
sewardj2342c972002-05-22 23:34:20 +0000846 && /* there is a defined and enabled alt stack, which we're not
847 already using. Logic from get_sigframe in
848 arch/i386/kernel/signal.c. */
nethercote511e4062004-09-11 13:34:08 +0000849 sas_ss_flags(tid, ARCH_STACK_PTR(tst->arch)) == 0
sewardj2342c972002-05-22 23:34:20 +0000850 ) {
851 esp_top_of_frame
fitzhardinge98c4dc02004-03-16 08:27:29 +0000852 = (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size;
sewardj2342c972002-05-22 23:34:20 +0000853 if (VG_(clo_trace_signals))
854 VG_(message)(Vg_DebugMsg,
jsgf855d93d2003-10-13 22:26:55 +0000855 "delivering signal %d (%s) to thread %d: on ALT STACK",
856 sigNo, signame(sigNo), tid );
njnfdc28af2003-02-24 10:36:48 +0000857
nethercote7cc9c232004-01-21 15:08:04 +0000858 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +0000859 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
njnfdc28af2003-02-24 10:36:48 +0000860
sewardj2342c972002-05-22 23:34:20 +0000861 } else {
nethercote511e4062004-09-11 13:34:08 +0000862 esp_top_of_frame = ARCH_STACK_PTR(tst->arch);
njnfdc28af2003-02-24 10:36:48 +0000863
nethercote7cc9c232004-01-21 15:08:04 +0000864 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +0000865 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
sewardj2342c972002-05-22 23:34:20 +0000866 }
nethercote6eec4602004-09-13 14:15:36 +0000867 VGA_(push_signal_frame)(tid, esp_top_of_frame, siginfo,
868 vg_scss.scss_per_sig[sigNo].scss_handler,
869 vg_scss.scss_per_sig[sigNo].scss_flags,
870 &vg_scss.scss_per_sig[sigNo].scss_mask);
sewardjde4a1d02002-03-22 01:27:54 +0000871}
872
sewardjde4a1d02002-03-22 01:27:54 +0000873/* Clear the signal frame created by vg_push_signal_frame, restore the
874 simulated machine state, and return the signal number that the
875 frame was for. */
876static
sewardj2e93c502002-04-12 11:12:52 +0000877Int vg_pop_signal_frame ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +0000878{
nethercote6eec4602004-09-13 14:15:36 +0000879 Int sigNo = VGA_(pop_signal_frame)(tid);
sewardjde4a1d02002-03-22 01:27:54 +0000880
jsgf855d93d2003-10-13 22:26:55 +0000881 VG_(proxy_setsigmask)(tid);
882
nethercote7cc9c232004-01-21 15:08:04 +0000883 /* Notify tools */
njnfdc28af2003-02-24 10:36:48 +0000884 VG_TRACK( post_deliver_signal, tid, sigNo );
885
sewardjde4a1d02002-03-22 01:27:54 +0000886 return sigNo;
887}
888
889
890/* A handler is returning. Restore the machine state from the stacked
891 VgSigContext and continue with whatever was going on before the
sewardj77e466c2002-04-14 02:29:29 +0000892 handler ran. Returns the SA_RESTART syscall-restartability-status
893 of the delivered signal. */
sewardjde4a1d02002-03-22 01:27:54 +0000894
sewardj77e466c2002-04-14 02:29:29 +0000895Bool VG_(signal_returns) ( ThreadId tid )
sewardjde4a1d02002-03-22 01:27:54 +0000896{
sewardj2e93c502002-04-12 11:12:52 +0000897 Int sigNo;
sewardjde4a1d02002-03-22 01:27:54 +0000898
sewardj2e93c502002-04-12 11:12:52 +0000899 /* Pop the signal frame and restore tid's status to what it was
900 before the signal was delivered. */
901 sigNo = vg_pop_signal_frame(tid);
sewardjde4a1d02002-03-22 01:27:54 +0000902
sewardjb48e5002002-05-13 00:16:03 +0000903 vg_assert(sigNo >= 1 && sigNo <= VKI_KNSIG);
sewardjde4a1d02002-03-22 01:27:54 +0000904
sewardj77e466c2002-04-14 02:29:29 +0000905 /* Scheduler now can resume this thread, or perhaps some other.
906 Tell the scheduler whether or not any syscall interrupted by
jsgf855d93d2003-10-13 22:26:55 +0000907 this signal should be restarted, if possible, or no. This is
908 only used for nanosleep; all other blocking syscalls are handled
909 in VG_(deliver_signal)().
910 */
sewardj018f7622002-05-15 21:13:39 +0000911 return
912 (vg_scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART)
913 ? True
914 : False;
sewardjde4a1d02002-03-22 01:27:54 +0000915}
916
jsgf855d93d2003-10-13 22:26:55 +0000917static const Char *signame(Int sigNo)
sewardjde4a1d02002-03-22 01:27:54 +0000918{
jsgf855d93d2003-10-13 22:26:55 +0000919 static Char buf[10];
sewardjb48e5002002-05-13 00:16:03 +0000920
jsgf855d93d2003-10-13 22:26:55 +0000921 switch(sigNo) {
922#define S(x) case VKI_##x: return #x
923 S(SIGHUP);
924 S(SIGINT);
925 S(SIGQUIT);
926 S(SIGILL);
927 S(SIGTRAP);
928 S(SIGABRT);
929 S(SIGBUS);
930 S(SIGFPE);
931 S(SIGKILL);
932 S(SIGUSR1);
933 S(SIGUSR2);
934 S(SIGSEGV);
935 S(SIGPIPE);
936 S(SIGALRM);
937 S(SIGTERM);
938 S(SIGSTKFLT);
939 S(SIGCHLD);
940 S(SIGCONT);
941 S(SIGSTOP);
942 S(SIGTSTP);
943 S(SIGTTIN);
944 S(SIGTTOU);
945 S(SIGURG);
946 S(SIGXCPU);
947 S(SIGXFSZ);
948 S(SIGVTALRM);
949 S(SIGPROF);
950 S(SIGWINCH);
951 S(SIGIO);
952 S(SIGPWR);
953 S(SIGUNUSED);
954#undef S
sewardjde4a1d02002-03-22 01:27:54 +0000955
jsgf855d93d2003-10-13 22:26:55 +0000956 case VKI_SIGRTMIN ... VKI_SIGRTMAX:
957 VG_(sprintf)(buf, "SIGRT%d", sigNo);
958 return buf;
sewardjde4a1d02002-03-22 01:27:54 +0000959
jsgf855d93d2003-10-13 22:26:55 +0000960 default:
961 VG_(sprintf)(buf, "SIG%d", sigNo);
962 return buf;
963 }
964}
sewardjde4a1d02002-03-22 01:27:54 +0000965
jsgf855d93d2003-10-13 22:26:55 +0000966/* Hit ourselves with a signal using the default handler */
967void VG_(kill_self)(Int sigNo)
968{
969 vki_ksigset_t mask, origmask;
970 vki_ksigaction sa, origsa;
sewardj018f7622002-05-15 21:13:39 +0000971
jsgf855d93d2003-10-13 22:26:55 +0000972 sa.ksa_handler = VKI_SIG_DFL;
973 sa.ksa_flags = 0;
974 sa.ksa_restorer = 0;
975 VG_(ksigemptyset)(&sa.ksa_mask);
sewardj2e93c502002-04-12 11:12:52 +0000976
jsgf855d93d2003-10-13 22:26:55 +0000977 VG_(ksigaction)(sigNo, &sa, &origsa);
sewardj018f7622002-05-15 21:13:39 +0000978
jsgf855d93d2003-10-13 22:26:55 +0000979 VG_(ksigfillset)(&mask);
980 VG_(ksigdelset)(&mask, sigNo);
981 VG_(ksigprocmask)(VKI_SIG_SETMASK, &mask, &origmask);
982
983 VG_(ktkill)(VG_(getpid)(), sigNo);
984
985 VG_(ksigaction)(sigNo, &origsa, NULL);
986 VG_(ksigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
987}
988
fitzhardinged65dcad2004-03-13 02:06:58 +0000989/*
990 Dump core
991
992 Generate a standard ELF core file corresponding to the client state
993 at the time of a crash.
994 */
995#include <elf.h>
996#ifndef NT_PRXFPREG
997#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
998#endif /* NT_PRXFPREG */
999
1000/* If true, then this Segment may be mentioned in the core */
1001static Bool may_dump(const Segment *seg)
1002{
1003 return (seg->flags & SF_VALGRIND) == 0 && VG_(is_client_addr)(seg->addr);
1004}
1005
1006/* If true, then this Segment's contents will be in the core */
1007static Bool should_dump(const Segment *seg)
1008{
1009 return may_dump(seg); // && (seg->prot & VKI_PROT_WRITE);
1010}
1011
1012static void fill_ehdr(Elf32_Ehdr *ehdr, Int num_phdrs)
1013{
1014 VG_(memset)(ehdr, 0, sizeof(ehdr));
1015
1016 VG_(memcpy)(ehdr->e_ident, ELFMAG, SELFMAG);
1017 ehdr->e_ident[EI_CLASS] = ELFCLASS32;
1018 ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
1019 ehdr->e_ident[EI_VERSION] = EV_CURRENT;
fitzhardinged65dcad2004-03-13 02:06:58 +00001020
1021 ehdr->e_type = ET_CORE;
1022 ehdr->e_machine = EM_386;
1023 ehdr->e_version = EV_CURRENT;
1024 ehdr->e_entry = 0;
1025 ehdr->e_phoff = sizeof(Elf32_Ehdr);
1026 ehdr->e_shoff = 0;
1027 ehdr->e_flags = 0;
1028 ehdr->e_ehsize = sizeof(Elf32_Ehdr);
1029 ehdr->e_phentsize = sizeof(Elf32_Phdr);
1030 ehdr->e_phnum = num_phdrs;
1031 ehdr->e_shentsize = 0;
1032 ehdr->e_shnum = 0;
1033 ehdr->e_shstrndx = 0;
1034
1035}
1036
1037static void fill_phdr(Elf32_Phdr *phdr, const Segment *seg, UInt off, Bool write)
1038{
1039 write = write && should_dump(seg);
1040
1041 VG_(memset)(phdr, 0, sizeof(*phdr));
1042
1043 phdr->p_type = PT_LOAD;
1044 phdr->p_offset = off;
1045 phdr->p_vaddr = seg->addr;
1046 phdr->p_paddr = 0;
1047 phdr->p_filesz = write ? seg->len : 0;
1048 phdr->p_memsz = seg->len;
1049 phdr->p_flags = 0;
1050
1051 if (seg->prot & VKI_PROT_READ)
1052 phdr->p_flags |= PF_R;
1053 if (seg->prot & VKI_PROT_WRITE)
1054 phdr->p_flags |= PF_W;
1055 if (seg->prot & VKI_PROT_EXEC)
1056 phdr->p_flags |= PF_X;
1057
1058 phdr->p_align = VKI_BYTES_PER_PAGE;
1059}
1060
1061struct note {
1062 struct note *next;
1063 Elf32_Nhdr note;
1064 Char name[0];
1065};
1066
1067static UInt note_size(const struct note *n)
1068{
1069 return sizeof(Elf32_Nhdr) + ROUNDUP(VG_(strlen)(n->name)+1, 4) + ROUNDUP(n->note.n_descsz, 4);
1070}
1071
1072static void add_note(struct note **list, const Char *name, UInt type, const void *data, UInt datasz)
1073{
1074 Int namelen = VG_(strlen)(name)+1;
1075 Int notelen = sizeof(struct note) +
1076 ROUNDUP(namelen, 4) +
1077 ROUNDUP(datasz, 4);
1078 struct note *n = VG_(arena_malloc)(VG_AR_CORE, notelen);
1079
1080 VG_(memset)(n, 0, notelen);
1081
1082 n->next = *list;
1083 *list = n;
1084
1085 n->note.n_type = type;
1086 n->note.n_namesz = namelen;
1087 n->note.n_descsz = datasz;
1088
1089 VG_(memcpy)(n->name, name, namelen);
1090 VG_(memcpy)(n->name+ROUNDUP(namelen,4), data, datasz);
1091}
1092
1093static void write_note(Int fd, const struct note *n)
1094{
1095 VG_(write)(fd, &n->note, note_size(n));
1096}
1097
1098static void fill_prpsinfo(const ThreadState *tst, struct elf_prpsinfo *prpsinfo)
1099{
1100 Char *name;
1101
1102 VG_(memset)(prpsinfo, 0, sizeof(*prpsinfo));
1103
1104 switch(tst->status) {
1105 case VgTs_Runnable:
1106 prpsinfo->pr_sname = 'R';
1107 break;
1108
1109 case VgTs_WaitJoinee:
1110 prpsinfo->pr_sname = 'Z';
1111 prpsinfo->pr_zomb = 1;
1112 break;
1113
1114 case VgTs_WaitJoiner:
1115 case VgTs_WaitMX:
1116 case VgTs_WaitCV:
1117 case VgTs_WaitSys:
1118 case VgTs_Sleeping:
1119 prpsinfo->pr_sname = 'S';
1120 break;
1121
1122 case VgTs_Empty:
1123 /* ? */
1124 break;
1125 }
1126
1127 prpsinfo->pr_uid = 0;
1128 prpsinfo->pr_gid = 0;
1129
1130 name = VG_(resolve_filename)(VG_(clexecfd));
1131
1132 if (name != NULL) {
1133 Char *n = name+VG_(strlen)(name)-1;
1134
1135 while(n > name && *n != '/')
1136 n--;
1137 if (n != name)
1138 n++;
1139
1140 VG_(strncpy)(prpsinfo->pr_fname, n, sizeof(prpsinfo->pr_fname));
1141 }
1142}
1143
1144static void fill_prstatus(const ThreadState *tst, struct elf_prstatus *prs, const vki_ksiginfo_t *si)
1145{
1146 struct user_regs_struct *regs;
1147
1148 VG_(memset)(prs, 0, sizeof(*prs));
1149
1150 prs->pr_info.si_signo = si->si_signo;
1151 prs->pr_info.si_code = si->si_code;
1152 prs->pr_info.si_errno = 0;
1153
1154 prs->pr_cursig = si->si_signo;
1155
1156 prs->pr_pid = VG_(main_pid) + tst->tid; /* just to distinguish threads from each other */
1157 prs->pr_ppid = 0;
1158 prs->pr_pgrp = VG_(main_pgrp);
1159 prs->pr_sid = VG_(main_pgrp);
1160
1161 regs = (struct user_regs_struct *)prs->pr_reg;
1162
1163 vg_assert(sizeof(*regs) == sizeof(prs->pr_reg));
1164
1165 if (VG_(is_running_thread)(tst->tid)) {
nethercotefedd8102004-09-13 15:19:34 +00001166 VGA_(fill_elfregs_from_BB)(regs);
fitzhardinged65dcad2004-03-13 02:06:58 +00001167 } else {
nethercotefedd8102004-09-13 15:19:34 +00001168 VGA_(fill_elfregs_from_tst)(regs, &tst->arch);
fitzhardinged65dcad2004-03-13 02:06:58 +00001169 }
1170}
1171
1172static void fill_fpu(const ThreadState *tst, elf_fpregset_t *fpu)
1173{
nethercotefedd8102004-09-13 15:19:34 +00001174 if (VG_(is_running_thread)(tst->tid))
1175 VGA_(fill_elffpregs_from_BB)(fpu);
1176 else
1177 VGA_(fill_elffpregs_from_tst)(fpu, &tst->arch);
fitzhardinged65dcad2004-03-13 02:06:58 +00001178}
1179
1180static void fill_xfpu(const ThreadState *tst, elf_fpxregset_t *xfpu)
1181{
nethercotefedd8102004-09-13 15:19:34 +00001182 if (VG_(is_running_thread)(tst->tid))
1183 VGA_(fill_elffpxregs_from_BB)(xfpu);
1184 else
1185 VGA_(fill_elffpxregs_from_tst)(xfpu, &tst->arch);
fitzhardinged65dcad2004-03-13 02:06:58 +00001186}
1187
1188static void make_coredump(ThreadId tid, const vki_ksiginfo_t *si, UInt max_size)
1189{
1190 Char buf[1000];
1191 Char *basename = "vgcore";
1192 Char *coreext = "";
1193 Int seq = 0;
1194 Int core_fd;
1195 Segment *seg;
1196 Elf32_Ehdr ehdr;
1197 Elf32_Phdr *phdrs;
1198 Int num_phdrs;
1199 Int i;
1200 UInt off;
1201 struct note *notelist, *note;
1202 UInt notesz;
1203 struct elf_prpsinfo prpsinfo;
1204 struct elf_prstatus prstatus;
1205
nethercotef8548672004-06-21 12:42:35 +00001206 if (VG_(clo_log_name) != NULL) {
fitzhardinged65dcad2004-03-13 02:06:58 +00001207 coreext = ".core";
nethercotef8548672004-06-21 12:42:35 +00001208 basename = VG_(clo_log_name);
fitzhardinged65dcad2004-03-13 02:06:58 +00001209 }
1210
1211 for(;;) {
1212 if (seq == 0)
1213 VG_(sprintf)(buf, "%s%s.pid%d",
1214 basename, coreext, VG_(main_pid));
1215 else
1216 VG_(sprintf)(buf, "%s%s.pid%d.%d",
1217 basename, coreext, VG_(main_pid), seq);
1218 seq++;
1219
1220 core_fd = VG_(open)(buf,
1221 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_EXCL|VKI_O_TRUNC,
1222 VKI_S_IRUSR|VKI_S_IWUSR);
1223 if (core_fd >= 0)
1224 break;
1225
1226 if (core_fd != -VKI_EEXIST)
1227 return; /* can't create file */
1228 }
1229
1230 /* First, count how many memory segments to dump */
1231 num_phdrs = 1; /* start with notes */
1232 for(seg = VG_(first_segment)();
1233 seg != NULL;
1234 seg = VG_(next_segment)(seg)) {
1235 if (!may_dump(seg))
1236 continue;
1237
1238 num_phdrs++;
1239 }
1240
1241 fill_ehdr(&ehdr, num_phdrs);
1242
1243 /* Second, work out their layout */
1244 phdrs = VG_(arena_malloc)(VG_AR_CORE, sizeof(*phdrs) * num_phdrs);
1245
1246 for(i = 1; i < VG_N_THREADS; i++) {
1247 elf_fpregset_t fpu;
1248
1249 if (VG_(threads)[i].status == VgTs_Empty)
1250 continue;
1251
1252 if (VG_(have_ssestate)) {
1253 elf_fpxregset_t xfpu;
1254
1255 fill_xfpu(&VG_(threads)[i], &xfpu);
1256 add_note(&notelist, "LINUX", NT_PRXFPREG, &xfpu, sizeof(xfpu));
1257 }
1258
1259 fill_fpu(&VG_(threads)[i], &fpu);
1260 add_note(&notelist, "CORE", NT_FPREGSET, &fpu, sizeof(fpu));
1261
1262 fill_prstatus(&VG_(threads)[i], &prstatus, si);
1263 add_note(&notelist, "CORE", NT_PRSTATUS, &prstatus, sizeof(prstatus));
1264 }
1265
1266 fill_prpsinfo(&VG_(threads)[tid], &prpsinfo);
1267 add_note(&notelist, "CORE", NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo));
1268
1269 for(note = notelist, notesz = 0; note != NULL; note = note->next)
1270 notesz += note_size(note);
1271
1272 off = sizeof(ehdr) + sizeof(*phdrs) * num_phdrs;
1273
1274 phdrs[0].p_type = PT_NOTE;
1275 phdrs[0].p_offset = off;
1276 phdrs[0].p_vaddr = 0;
1277 phdrs[0].p_paddr = 0;
1278 phdrs[0].p_filesz = notesz;
1279 phdrs[0].p_memsz = 0;
1280 phdrs[0].p_flags = 0;
1281 phdrs[0].p_align = 0;
1282
1283 off += notesz;
1284
1285 off = PGROUNDUP(off);
1286
1287 for(seg = VG_(first_segment)(), i = 1;
1288 seg != NULL;
1289 seg = VG_(next_segment)(seg), i++) {
1290 if (!may_dump(seg))
1291 continue;
1292
1293 fill_phdr(&phdrs[i], seg, off, (seg->len + off) < max_size);
1294
1295 off += phdrs[i].p_filesz;
1296 }
1297
1298 /* write everything out */
1299 VG_(write)(core_fd, &ehdr, sizeof(ehdr));
1300 VG_(write)(core_fd, phdrs, sizeof(*phdrs) * num_phdrs);
1301
1302 for(note = notelist; note != NULL; note = note->next)
1303 write_note(core_fd, note);
1304
1305 VG_(lseek)(core_fd, phdrs[1].p_offset, VKI_SEEK_SET);
1306
1307 for(seg = VG_(first_segment)(), i = 1;
1308 seg != NULL;
1309 seg = VG_(next_segment)(seg), i++) {
1310 if (!should_dump(seg))
1311 continue;
1312
1313 vg_assert(VG_(lseek)(core_fd, 0, VKI_SEEK_CUR) == phdrs[i].p_offset);
1314 if (phdrs[i].p_filesz > 0)
1315 VG_(write)(core_fd, (void *)seg->addr, seg->len);
1316 }
1317
1318 VG_(close)(core_fd);
1319}
1320
jsgf855d93d2003-10-13 22:26:55 +00001321/*
1322 Perform the default action of a signal. Returns if the default
1323 action isn't fatal.
1324
1325 If we're not being quiet, then print out some more detail about
1326 fatal signals (esp. core dumping signals).
1327 */
1328static void vg_default_action(const vki_ksiginfo_t *info, ThreadId tid)
1329{
1330 Int sigNo = info->si_signo;
1331 Bool terminate = False;
1332 Bool core = False;
1333
1334 switch(sigNo) {
1335 case VKI_SIGQUIT: /* core */
1336 case VKI_SIGILL: /* core */
1337 case VKI_SIGABRT: /* core */
1338 case VKI_SIGFPE: /* core */
1339 case VKI_SIGSEGV: /* core */
1340 case VKI_SIGBUS: /* core */
1341 case VKI_SIGTRAP: /* core */
1342 case VKI_SIGXCPU: /* core */
1343 case VKI_SIGXFSZ: /* core */
1344 terminate = True;
1345 core = True;
1346 break;
1347
1348 case VKI_SIGHUP: /* term */
1349 case VKI_SIGINT: /* term */
1350 case VKI_SIGKILL: /* term - we won't see this */
1351 case VKI_SIGPIPE: /* term */
1352 case VKI_SIGALRM: /* term */
1353 case VKI_SIGTERM: /* term */
1354 case VKI_SIGUSR1: /* term */
1355 case VKI_SIGUSR2: /* term */
1356 case VKI_SIGIO: /* term */
1357 case VKI_SIGPWR: /* term */
1358 case VKI_SIGSYS: /* term */
1359 case VKI_SIGPROF: /* term */
1360 case VKI_SIGVTALRM: /* term */
1361 case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
1362 terminate = True;
1363 break;
1364 }
1365
1366 vg_assert(!core || (core && terminate));
1367
fitzhardinge98abfc72003-12-16 02:05:15 +00001368 if (VG_(clo_trace_signals))
1369 VG_(message)(Vg_DebugMsg, "delivering %d to default handler %s%s",
1370 sigNo, terminate ? "terminate" : "", core ? "+core" : "");
1371
jsgf855d93d2003-10-13 22:26:55 +00001372 if (terminate) {
fitzhardinge4a4d1082004-03-15 23:46:54 +00001373 struct vki_rlimit corelim;
fitzhardinge7d71b432004-03-16 08:20:14 +00001374 Bool could_core = core;
fitzhardinge4a4d1082004-03-15 23:46:54 +00001375
fitzhardinge61a53412004-03-15 23:44:11 +00001376 if (core) {
1377 /* If they set the core-size limit to zero, don't generate a
1378 core file */
fitzhardinge61a53412004-03-15 23:44:11 +00001379
1380 VG_(getrlimit)(VKI_RLIMIT_CORE, &corelim);
1381
1382 if (corelim.rlim_cur == 0)
1383 core = False;
1384 }
1385
fitzhardinge7d71b432004-03-16 08:20:14 +00001386 if (VG_(clo_verbosity) != 0 && (could_core || VG_(clo_verbosity) > 1)) {
jsgf855d93d2003-10-13 22:26:55 +00001387 VG_(message)(Vg_UserMsg, "");
1388 VG_(message)(Vg_UserMsg, "Process terminating with default action of signal %d (%s)%s",
1389 sigNo, signame(sigNo), core ? ": dumping core" : "");
1390
1391 /* Be helpful - decode some more details about this fault */
1392 if (info->si_code > VKI_SI_USER) {
1393 const Char *event = NULL;
1394
1395 switch(sigNo) {
1396 case VKI_SIGSEGV:
1397 switch(info->si_code) {
fitzhardinge98abfc72003-12-16 02:05:15 +00001398 case 1: event = "Access not within mapped region"; break;
1399 case 2: event = "Bad permissions for mapped region"; break;
jsgf855d93d2003-10-13 22:26:55 +00001400 }
1401 break;
1402
1403 case VKI_SIGILL:
1404 switch(info->si_code) {
nethercote3b390c72003-11-13 17:53:43 +00001405 case 1: event = "Illegal opcode"; break;
1406 case 2: event = "Illegal operand"; break;
1407 case 3: event = "Illegal addressing mode"; break;
1408 case 4: event = "Illegal trap"; break;
1409 case 5: event = "Privileged opcode"; break;
1410 case 6: event = "Privileged register"; break;
1411 case 7: event = "Coprocessor error"; break;
1412 case 8: event = "Internal stack error"; break;
jsgf855d93d2003-10-13 22:26:55 +00001413 }
1414 break;
1415
1416 case VKI_SIGFPE:
1417 switch (info->si_code) {
nethercote3b390c72003-11-13 17:53:43 +00001418 case 1: event = "Integer divide by zero"; break;
1419 case 2: event = "Integer overflow"; break;
jsgf855d93d2003-10-13 22:26:55 +00001420 case 3: event = "FP divide by zero"; break;
1421 case 4: event = "FP overflow"; break;
1422 case 5: event = "FP underflow"; break;
1423 case 6: event = "FP inexact"; break;
1424 case 7: event = "FP invalid operation"; break;
1425 case 8: event = "FP subscript out of range"; break;
1426 }
1427 break;
1428
1429 case VKI_SIGBUS:
1430 switch (info->si_code) {
nethercote3b390c72003-11-13 17:53:43 +00001431 case 1: event = "Invalid address alignment"; break;
1432 case 2: event = "Non-existent physical address"; break;
1433 case 3: event = "Hardware error"; break;
jsgf855d93d2003-10-13 22:26:55 +00001434 }
1435 break;
1436 }
1437
1438 if (event != NULL)
nethercote3b390c72003-11-13 17:53:43 +00001439 VG_(message)(Vg_UserMsg, " %s at address %p",
jsgf855d93d2003-10-13 22:26:55 +00001440 event, info->_sifields._sigfault._addr);
1441 }
1442
1443 if (tid != VG_INVALID_THREADID) {
1444 ExeContext *ec = VG_(get_ExeContext)(tid);
1445 VG_(pp_ExeContext)(ec);
1446 }
1447 }
fitzhardinge126c64f2003-12-08 21:58:37 +00001448
nethercote04d0fbc2004-01-26 16:48:06 +00001449 if (VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) )) {
1450 VG_(start_debugger)( tid );
fitzhardinge126c64f2003-12-08 21:58:37 +00001451 }
1452
fitzhardinged65dcad2004-03-13 02:06:58 +00001453 if (core) {
fitzhardinge4a4d1082004-03-15 23:46:54 +00001454 static struct vki_rlimit zero = { 0, 0 };
1455
fitzhardinge61a53412004-03-15 23:44:11 +00001456 make_coredump(tid, info, corelim.rlim_cur);
fitzhardinged65dcad2004-03-13 02:06:58 +00001457
1458 /* make sure we don't get a confusing kernel-generated coredump */
1459 VG_(setrlimit)(VKI_RLIMIT_CORE, &zero);
1460 }
1461
nethercote238a3c32004-08-09 13:13:31 +00001462 VG_(scheduler_handle_fatal_signal)( sigNo );
sewardjde4a1d02002-03-22 01:27:54 +00001463 }
1464
jsgf855d93d2003-10-13 22:26:55 +00001465 VG_(kill_self)(sigNo);
sewardj018f7622002-05-15 21:13:39 +00001466
jsgf855d93d2003-10-13 22:26:55 +00001467 vg_assert(!terminate);
sewardjb48e5002002-05-13 00:16:03 +00001468}
1469
nethercoted5f5ee42004-08-01 23:06:22 +00001470static void synth_fault_common(ThreadId tid, Addr addr, Int si_code)
1471{
1472 vki_ksiginfo_t info;
1473
1474 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1475
1476 info.si_signo = VKI_SIGSEGV;
1477 info.si_code = si_code;
1478 info._sifields._sigfault._addr = (void*)addr;
1479
1480 VG_(resume_scheduler)(VKI_SIGSEGV, &info);
1481 VG_(deliver_signal)(tid, &info, False);
1482}
1483
1484// Synthesize a fault where the address is OK, but the page
1485// permissions are bad.
fitzhardingef1beb252004-03-16 09:49:08 +00001486void VG_(synth_fault_perms)(ThreadId tid, Addr addr)
1487{
nethercoted5f5ee42004-08-01 23:06:22 +00001488 synth_fault_common(tid, addr, 2);
fitzhardingef1beb252004-03-16 09:49:08 +00001489}
1490
nethercoted5f5ee42004-08-01 23:06:22 +00001491// Synthesize a fault where the address there's nothing mapped at the address.
fitzhardingef1beb252004-03-16 09:49:08 +00001492void VG_(synth_fault_mapping)(ThreadId tid, Addr addr)
1493{
nethercoted5f5ee42004-08-01 23:06:22 +00001494 synth_fault_common(tid, addr, 1);
fitzhardingef1beb252004-03-16 09:49:08 +00001495}
1496
nethercoted5f5ee42004-08-01 23:06:22 +00001497// Synthesize a misc memory fault.
fitzhardingef1beb252004-03-16 09:49:08 +00001498void VG_(synth_fault)(ThreadId tid)
1499{
nethercoted5f5ee42004-08-01 23:06:22 +00001500 synth_fault_common(tid, 0, 0x80);
fitzhardingef1beb252004-03-16 09:49:08 +00001501}
sewardjb48e5002002-05-13 00:16:03 +00001502
jsgf855d93d2003-10-13 22:26:55 +00001503void VG_(deliver_signal) ( ThreadId tid, const vki_ksiginfo_t *info, Bool async )
sewardjde4a1d02002-03-22 01:27:54 +00001504{
jsgf855d93d2003-10-13 22:26:55 +00001505 Int sigNo = info->si_signo;
1506 vki_ksigset_t handlermask;
jsgf855d93d2003-10-13 22:26:55 +00001507 SCSS_Per_Signal *handler = &vg_scss.scss_per_sig[sigNo];
fitzhardinge98abfc72003-12-16 02:05:15 +00001508 void *handler_fn;
jsgf855d93d2003-10-13 22:26:55 +00001509 ThreadState *tst = VG_(get_ThreadState)(tid);
1510
1511 if (VG_(clo_trace_signals))
1512 VG_(message)(Vg_DebugMsg,"delivering signal %d (%s) to thread %d",
1513 sigNo, signame(sigNo), tid );
1514
1515 if (sigNo == VKI_SIGVGINT) {
1516 /* If this is a SIGVGINT, then we just ACK the signal and carry
1517 on; the application need never know about it (except for any
1518 effect on its syscalls). */
1519 vg_assert(async);
1520
1521 if (tst->status == VgTs_WaitSys) {
1522 /* blocked in a syscall; we assume it should be interrupted */
nethercotebb4222b2004-09-10 17:42:11 +00001523 if (PLATFORM_SYSCALL_RET(tst->arch) == -VKI_ERESTARTSYS)
1524 PLATFORM_SYSCALL_RET(tst->arch) = -VKI_EINTR;
jsgf855d93d2003-10-13 22:26:55 +00001525 }
1526
1527 VG_(proxy_sigack)(tid, &tst->sig_mask);
1528 return;
1529 }
1530
1531 /* If thread is currently blocked in a syscall, then resume as
1532 runnable. If the syscall needs restarting, tweak the machine
1533 state to make it happen. */
1534 if (tst->status == VgTs_WaitSys) {
1535 vg_assert(tst->syscallno != -1);
1536
fitzhardingea09a1b52003-11-07 23:09:48 +00001537 /* OK, the thread was waiting for a syscall to complete. This
1538 means that the proxy has either not yet processed the
1539 RunSyscall request, or was processing it when the signal
1540 came. Either way, it is going to give us some syscall
1541 results right now, so wait for them to appear. This makes
1542 the thread runnable again, so we're in the right state to run
fitzhardinge31ba9052004-01-16 02:15:23 +00001543 the handler. We ask post_syscall to restart based on the
1544 client's sigaction flags. */
jsgf855d93d2003-10-13 22:26:55 +00001545 if (0)
fitzhardinge31ba9052004-01-16 02:15:23 +00001546 VG_(printf)("signal %d interrupted syscall %d; restart=%d\n",
1547 sigNo, tst->syscallno, !!(handler->scss_flags & VKI_SA_RESTART));
1548 VG_(proxy_wait_sys)(tid, !!(handler->scss_flags & VKI_SA_RESTART));
jsgf855d93d2003-10-13 22:26:55 +00001549 }
1550
fitzhardinge98abfc72003-12-16 02:05:15 +00001551 /* If the client specifies SIG_IGN, treat it as SIG_DFL */
1552 handler_fn = handler->scss_handler;
1553 if (handler_fn == VKI_SIG_IGN)
1554 handler_fn = VKI_SIG_DFL;
1555
1556 vg_assert(handler_fn != VKI_SIG_IGN);
jsgf855d93d2003-10-13 22:26:55 +00001557
1558 if (sigNo == VKI_SIGCHLD && (handler->scss_flags & VKI_SA_NOCLDWAIT)) {
1559 //VG_(printf)("sigNo==SIGCHLD and app asked for NOCLDWAIT\n");
1560 vg_babyeater(sigNo, NULL, NULL);
1561 }
1562
fitzhardinge98abfc72003-12-16 02:05:15 +00001563 if (handler_fn == VKI_SIG_DFL) {
jsgf855d93d2003-10-13 22:26:55 +00001564 handlermask = tst->sig_mask; /* no change to signal mask */
1565 vg_default_action(info, tid);
1566 } else {
1567 /* Create a signal delivery frame, and set the client's %ESP and
1568 %EIP so that when execution continues, we will enter the
1569 signal handler with the frame on top of the client's stack,
1570 as it expects. */
1571 vg_assert(VG_(is_valid_tid)(tid));
1572 vg_push_signal_frame ( tid, info );
1573
1574 if (handler->scss_flags & VKI_SA_ONESHOT) {
1575 /* Do the ONESHOT thing. */
1576 handler->scss_handler = VKI_SIG_DFL;
1577
nethercote9dd11512004-08-04 15:31:30 +00001578 handle_SCSS_change( False /* lazy update */ );
jsgf855d93d2003-10-13 22:26:55 +00001579 }
1580
fitzhardingea09a1b52003-11-07 23:09:48 +00001581 switch(tst->status) {
jsgf855d93d2003-10-13 22:26:55 +00001582 case VgTs_Runnable:
1583 break;
1584
1585 case VgTs_WaitSys:
jsgf855d93d2003-10-13 22:26:55 +00001586 case VgTs_WaitJoiner:
1587 case VgTs_WaitJoinee:
1588 case VgTs_WaitMX:
1589 case VgTs_WaitCV:
1590 case VgTs_Sleeping:
fitzhardingea09a1b52003-11-07 23:09:48 +00001591 tst->status = VgTs_Runnable;
jsgf855d93d2003-10-13 22:26:55 +00001592 break;
1593
1594 case VgTs_Empty:
1595 VG_(core_panic)("unexpected thread state");
1596 break;
1597 }
1598
jsgf855d93d2003-10-13 22:26:55 +00001599 /* handler gets the union of the signal's mask and the thread's
1600 mask */
1601 handlermask = handler->scss_mask;
1602 VG_(ksigaddset_from_set)(&handlermask, &VG_(threads)[tid].sig_mask);
1603
1604 /* also mask this signal, unless they ask us not to */
1605 if (!(handler->scss_flags & VKI_SA_NOMASK))
1606 VG_(ksigaddset)(&handlermask, sigNo);
1607 }
1608
1609 /* tell proxy we're about to start running the handler */
1610 if (async)
1611 VG_(proxy_sigack)(tid, &handlermask);
1612}
1613
1614
1615/*
1616 If the client set the handler for SIGCHLD to SIG_IGN, then we need
1617 to automatically dezombie any dead children. Also used if the
1618 client set the SA_NOCLDWAIT on their SIGCHLD handler.
1619 */
1620static
1621void vg_babyeater ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext *uc )
1622{
1623 Int status;
1624 Int pid;
1625
1626 vg_assert(sigNo == VKI_SIGCHLD);
1627
1628 while((pid = VG_(waitpid)(-1, &status, VKI_WNOHANG)) > 0) {
1629 if (VG_(clo_trace_signals))
1630 VG_(message)(Vg_DebugMsg, "babyeater reaped %d", pid);
1631 }
1632}
1633
1634/*
1635 Receive an async signal from the host.
1636
1637 It being called in the context of a proxy LWP, and therefore is an
1638 async signal aimed at one of our threads. In this case, we pass
1639 the signal info to the main thread with VG_(proxy_handlesig)().
1640
1641 This should *never* be in the context of the main LWP, because
1642 all signals for which this is the handler should be blocked there.
1643*/
1644static
1645void vg_async_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext *uc )
1646{
1647 if (VG_(gettid)() == VG_(main_pid)) {
1648 VG_(printf)("got signal %d in LWP %d (%d)\n",
1649 sigNo, VG_(gettid)(), VG_(gettid)(), VG_(main_pid));
1650 vg_assert(VG_(ksigismember)(&uc->uc_sigmask, sigNo));
1651 }
1652
1653 vg_assert(VG_(gettid)() != VG_(main_pid));
1654
1655 VG_(proxy_handlesig)(info, &uc->uc_mcontext);
1656}
1657
1658/*
1659 Recieve a sync signal from the host.
1660
1661 This should always be called from the main thread, though it may be
1662 called in a proxy LWP if someone sends an async version of one of
1663 the sync signals.
1664*/
1665static
1666void vg_sync_signalhandler ( Int sigNo, vki_ksiginfo_t *info, struct vki_ucontext *uc )
1667{
sewardj2e93c502002-04-12 11:12:52 +00001668 Int dummy_local;
jsgf855d93d2003-10-13 22:26:55 +00001669
1670 vg_assert(info != NULL);
1671 vg_assert(info->si_signo == sigNo);
1672 vg_assert(sigNo == VKI_SIGSEGV ||
1673 sigNo == VKI_SIGBUS ||
1674 sigNo == VKI_SIGFPE ||
1675 sigNo == VKI_SIGILL);
1676
1677 if (VG_(gettid)() != VG_(main_pid)) {
1678 /* We were sent one of our sync signals in an async way (or the
1679 proxy LWP code has a bug) */
1680 vg_assert(info->si_code <= VKI_SI_USER);
1681
1682 VG_(proxy_handlesig)(info, &uc->uc_mcontext);
1683 return;
1684 }
1685
sewardjde4a1d02002-03-22 01:27:54 +00001686
sewardj7a61d912002-04-25 01:27:35 +00001687 /*
1688 if (sigNo == VKI_SIGUSR1) {
1689 VG_(printf)("YOWZA! SIGUSR1\n\n");
1690 VG_(clo_trace_pthread_level) = 2;
1691 VG_(clo_trace_sched) = True;
1692 VG_(clo_trace_syscalls) = True;
1693 VG_(clo_trace_signals) = True;
1694 return;
1695 }
1696 */
1697
sewardjde4a1d02002-03-22 01:27:54 +00001698 if (VG_(clo_trace_signals)) {
fitzhardinge98abfc72003-12-16 02:05:15 +00001699 VG_(message)(Vg_DebugMsg, "signal %d arrived ... si_code=%d", sigNo, info->si_code );
sewardjde4a1d02002-03-22 01:27:54 +00001700 }
sewardjb48e5002002-05-13 00:16:03 +00001701 vg_assert(sigNo >= 1 && sigNo <= VKI_KNSIG);
sewardjde4a1d02002-03-22 01:27:54 +00001702
1703 /* Sanity check. Ensure we're really running on the signal stack
1704 we asked for. */
njn6eba4ef2003-05-01 08:06:41 +00001705 if (!(
nethercote759dda32004-08-07 18:16:56 +00001706 ((Char*)(&(sigstack[0])) <= (Char*)(&dummy_local))
njn6eba4ef2003-05-01 08:06:41 +00001707 &&
nethercote759dda32004-08-07 18:16:56 +00001708 ((Char*)(&dummy_local) < (Char*)(&(sigstack[VG_SIGSTACK_SIZE_W])))
sewardjde4a1d02002-03-22 01:27:54 +00001709 )
njn6eba4ef2003-05-01 08:06:41 +00001710 ) {
sewardj2e93c502002-04-12 11:12:52 +00001711 VG_(message)(Vg_DebugMsg,
1712 "FATAL: signal delivered on the wrong stack?!");
1713 VG_(message)(Vg_DebugMsg,
1714 "A possible workaround follows. Please tell me");
1715 VG_(message)(Vg_DebugMsg,
1716 "(jseward@acm.org) if the suggested workaround doesn't help.");
sewardjde4a1d02002-03-22 01:27:54 +00001717 VG_(unimplemented)
sewardj2e93c502002-04-12 11:12:52 +00001718 ("support for progs compiled with -p/-pg; "
1719 "rebuild your prog without -p/-pg");
sewardjde4a1d02002-03-22 01:27:54 +00001720 }
1721
nethercote759dda32004-08-07 18:16:56 +00001722 vg_assert((Char*)(&(sigstack[0])) <= (Char*)(&dummy_local));
1723 vg_assert((Char*)(&dummy_local) < (Char*)(&(sigstack[VG_SIGSTACK_SIZE_W])));
sewardjde4a1d02002-03-22 01:27:54 +00001724
fitzhardinge98abfc72003-12-16 02:05:15 +00001725 /* Special fault-handling case. We can now get signals which can
1726 act upon and immediately restart the faulting instruction.
1727 */
1728 if (info->si_signo == VKI_SIGSEGV) {
1729 ThreadId tid = VG_(get_current_or_recent_tid)();
1730 Addr fault = (Addr)info->_sifields._sigfault._addr;
nethercote511e4062004-09-11 13:34:08 +00001731 Addr esp = VG_(is_running_thread)(tid)
1732 ? VG_(baseBlock)[VGOFF_STACK_PTR]
1733 : ARCH_STACK_PTR(VG_(threads)[tid].arch);
fitzhardinge98abfc72003-12-16 02:05:15 +00001734 Segment *seg;
1735
1736 seg = VG_(find_segment)(fault);
1737 if (seg != NULL)
1738 seg = VG_(next_segment)(seg);
nethercotef84f6952004-07-15 14:58:33 +00001739 else
1740 seg = VG_(first_segment)();
fitzhardinge98abfc72003-12-16 02:05:15 +00001741
1742 if (VG_(clo_trace_signals)) {
1743 if (seg == NULL)
1744 VG_(message)(Vg_DebugMsg,
1745 "SIGSEGV: si_code=%d faultaddr=%p tid=%d esp=%p seg=NULL shad=%p-%p",
1746 info->si_code, fault, tid, esp,
1747 VG_(shadow_base), VG_(shadow_end));
1748 else
1749 VG_(message)(Vg_DebugMsg,
1750 "SIGSEGV: si_code=%d faultaddr=%p tid=%d esp=%p seg=%p-%p fl=%x shad=%p-%p",
1751 info->si_code, fault, tid, esp, seg->addr, seg->addr+seg->len, seg->flags,
1752 VG_(shadow_base), VG_(shadow_end));
1753 }
1754
1755 if (info->si_code == 1 && /* SEGV_MAPERR */
1756 seg != NULL &&
1757 fault >= esp &&
1758 fault < seg->addr &&
1759 (seg->flags & SF_GROWDOWN)) {
1760 /* If the fault address is above esp but below the current known
1761 stack segment base, and it was a fault because there was
1762 nothing mapped there (as opposed to a permissions fault),
1763 then extend the stack segment.
1764 */
1765 Addr base = PGROUNDDN(esp);
thughesc37184f2004-09-11 14:16:57 +00001766 if (seg->len + (seg->addr - base) <= VG_(threads)[tid].stack_size &&
1767 (void*)-1 != VG_(mmap)((Char *)base, seg->addr - base,
nethercoteb4250ae2004-07-10 16:50:09 +00001768 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
1769 VKI_MAP_PRIVATE|VKI_MAP_FIXED|VKI_MAP_ANONYMOUS|VKI_MAP_CLIENT,
1770 SF_STACK|SF_GROWDOWN,
1771 -1, 0))
1772 {
1773 return; // extension succeeded, restart instruction
fitzhardinge98abfc72003-12-16 02:05:15 +00001774 }
1775 /* Otherwise fall into normal signal handling */
1776 } else if (info->si_code == 2 && /* SEGV_ACCERR */
1777 VG_(needs).shadow_memory &&
1778 VG_(is_shadow_addr)(fault)) {
1779 /* If there's a fault within the shadow memory range, and it
1780 is a permissions fault, then it means that the client is
1781 using some memory which had not previously been used.
1782 This catches those faults, makes the memory accessible,
nethercote7cc9c232004-01-21 15:08:04 +00001783 and calls the tool to initialize that page.
fitzhardinge98abfc72003-12-16 02:05:15 +00001784 */
1785 static Int recursion = 0;
1786
1787 if (recursion++ == 0) {
1788 VG_(init_shadow_range)(PGROUNDDN(fault), VKI_BYTES_PER_PAGE, True);
1789 recursion--;
1790 return;
1791 } else {
1792 /* otherwise fall into normal SEGV handling */
1793 recursion--;
1794 }
1795 }
thughesc37184f2004-09-11 14:16:57 +00001796
1797 if (info->si_code == 1 && /* SEGV_MAPERR */
1798 seg != NULL &&
1799 fault >= esp &&
1800 fault < seg->addr &&
1801 (seg->flags & SF_STACK)) {
1802 VG_(message)(Vg_UserMsg, "Stack overflow in thread %d", tid);
1803 }
fitzhardinge98abfc72003-12-16 02:05:15 +00001804 }
1805
fitzhardingef1beb252004-03-16 09:49:08 +00001806 /* Can't continue; must longjmp back to the scheduler and thus
1807 enter the sighandler immediately. */
nethercote75d26242004-08-01 22:59:18 +00001808 VG_(resume_scheduler)(sigNo, info);
sewardj872051c2002-07-13 12:12:56 +00001809
jsgf855d93d2003-10-13 22:26:55 +00001810 if (info->si_code <= VKI_SI_USER) {
1811 /*
1812 OK, one of sync signals was sent from user-mode, so try to
fitzhardingee1c06d82003-10-30 07:21:44 +00001813 deliver it to someone who cares. Just add it to the
1814 process-wide pending signal set - signal routing will deliver
1815 it to someone eventually.
jsgf855d93d2003-10-13 22:26:55 +00001816
fitzhardingee1c06d82003-10-30 07:21:44 +00001817 The only other place which touches proc_pending is
1818 VG_(route_signals), and it has signals blocked while doing
1819 so, so there's no race.
1820 */
1821 VG_(message)(Vg_DebugMsg,
1822 "adding signal %d to pending set", sigNo);
1823 VG_(ksigaddset)(&proc_pending, sigNo);
jsgf855d93d2003-10-13 22:26:55 +00001824 } else {
1825 /*
1826 A bad signal came from the kernel (indicating an instruction
1827 generated it), but there was no jumpbuf set up. This means
1828 it was actually generated by Valgrind internally.
1829 */
1830 struct vki_sigcontext *sc = &uc->uc_mcontext;
fitzhardinge98abfc72003-12-16 02:05:15 +00001831 Char buf[1024];
jsgf855d93d2003-10-13 22:26:55 +00001832
1833 VG_(message)(Vg_DebugMsg,
1834 "INTERNAL ERROR: Valgrind received a signal %d (%s) - exiting",
1835 sigNo, signame(sigNo));
fitzhardinge98abfc72003-12-16 02:05:15 +00001836
1837 buf[0] = 0;
1838 if (1 && !VG_(get_fnname)(sc->eip, buf+2, sizeof(buf)-5)) {
1839 Int len;
1840
1841 buf[0] = ' ';
1842 buf[1] = '(';
1843 len = VG_(strlen)(buf);
1844 buf[len] = ')';
1845 buf[len+1] = '\0';
1846 }
1847
jsgf855d93d2003-10-13 22:26:55 +00001848 VG_(message)(Vg_DebugMsg,
fitzhardinge98abfc72003-12-16 02:05:15 +00001849 "si_code=%x Fault EIP: %p%s; Faulting address: %p",
1850 info->si_code, sc->eip, buf, info->_sifields._sigfault._addr);
jsgf855d93d2003-10-13 22:26:55 +00001851
1852 if (0)
1853 VG_(kill_self)(sigNo); /* generate a core dump */
1854 VG_(core_panic)("Killed by fatal signal");
1855 }
1856}
1857
1858
1859/*
1860 This signal handler exists only so that the scheduler thread can
1861 poke the LWP to make it fall out of whatever syscall it is in.
1862 Used for thread termination and cancellation.
1863 */
1864static void proxy_sigvg_handler(int signo, vki_ksiginfo_t *si, struct vki_ucontext *uc)
1865{
1866 vg_assert(signo == VKI_SIGVGINT || signo == VKI_SIGVGKILL);
1867 vg_assert(si->si_signo == signo);
1868
1869 /* only pay attention to it if it came from the scheduler */
1870 if (si->si_code == VKI_SI_TKILL &&
1871 si->_sifields._kill._pid == VG_(main_pid)) {
1872 vg_assert(si->si_code == VKI_SI_TKILL);
1873 vg_assert(si->_sifields._kill._pid == VG_(main_pid));
1874
1875 VG_(proxy_handlesig)(si, &uc->uc_mcontext);
sewardj872051c2002-07-13 12:12:56 +00001876 }
sewardjde4a1d02002-03-22 01:27:54 +00001877}
1878
1879
1880/* The outer insn loop calls here to reenable a host signal if
1881 vg_oursighandler longjmp'd.
1882*/
1883void VG_(unblock_host_signal) ( Int sigNo )
1884{
jsgf855d93d2003-10-13 22:26:55 +00001885 vg_assert(sigNo == VKI_SIGSEGV ||
1886 sigNo == VKI_SIGBUS ||
1887 sigNo == VKI_SIGILL ||
1888 sigNo == VKI_SIGFPE);
1889 set_main_sigmask();
sewardjde4a1d02002-03-22 01:27:54 +00001890}
1891
1892
1893static __attribute((unused))
1894void pp_vg_ksigaction ( vki_ksigaction* sa )
1895{
1896 Int i;
1897 VG_(printf)("vg_ksigaction: handler %p, flags 0x%x, restorer %p\n",
sewardj9a199dc2002-04-14 13:01:38 +00001898 sa->ksa_handler, (UInt)sa->ksa_flags, sa->ksa_restorer);
sewardjde4a1d02002-03-22 01:27:54 +00001899 VG_(printf)("vg_ksigaction: { ");
sewardjb48e5002002-05-13 00:16:03 +00001900 for (i = 1; i <= VKI_KNSIG; i++)
sewardjde4a1d02002-03-22 01:27:54 +00001901 if (VG_(ksigismember(&(sa->ksa_mask),i)))
1902 VG_(printf)("%d ", i);
1903 VG_(printf)("}\n");
1904}
1905
jsgf855d93d2003-10-13 22:26:55 +00001906/*
1907 In pre-2.6 kernels, the kernel didn't distribute signals to threads
1908 in a thread-group properly, so we need to do it here.
1909 */
1910void VG_(route_signals)(void)
1911{
1912 static const struct vki_timespec zero = { 0, 0 };
1913 static ThreadId start_tid = 1; /* tid to start scanning from */
1914 vki_ksigset_t set;
jsgf855d93d2003-10-13 22:26:55 +00001915 vki_ksiginfo_t si;
1916 Int sigNo;
1917
1918 vg_assert(VG_(gettid)() == VG_(main_pid));
1919 vg_assert(is_correct_sigmask());
1920
1921 if (!VG_(do_signal_routing))
1922 return;
1923
jsgf855d93d2003-10-13 22:26:55 +00001924 /* get the scheduler LWP's signal mask, and use it as the set of
fitzhardingee1c06d82003-10-30 07:21:44 +00001925 signals we're polling for - also block all signals to prevent
1926 races */
1927 VG_(block_all_host_signals) ( &set );
jsgf855d93d2003-10-13 22:26:55 +00001928
fitzhardingee1c06d82003-10-30 07:21:44 +00001929 /* grab any pending signals and add them to the pending signal set */
1930 while(VG_(ksigtimedwait)(&set, &si, &zero) > 0)
1931 VG_(ksigaddset)(&proc_pending, si.si_signo);
1932
1933 /* transfer signals from the process pending set to a particular
1934 thread which has it unblocked */
1935 for(sigNo = 0; sigNo < VKI_KNSIG; sigNo++) {
jsgf855d93d2003-10-13 22:26:55 +00001936 ThreadId tid;
1937 ThreadId end_tid;
1938 Int target = -1;
1939
fitzhardingee1c06d82003-10-30 07:21:44 +00001940 if (!VG_(ksigismember)(&proc_pending, sigNo))
1941 continue;
1942
jsgf855d93d2003-10-13 22:26:55 +00001943 end_tid = start_tid - 1;
1944 if (end_tid < 0 || end_tid >= VG_N_THREADS)
1945 end_tid = VG_N_THREADS-1;
1946
jsgf855d93d2003-10-13 22:26:55 +00001947 /* look for a suitable thread to deliver it to */
1948 for(tid = start_tid;
1949 tid != end_tid;
1950 tid = (tid + 1) % VG_N_THREADS) {
1951 ThreadState *tst = &VG_(threads)[tid];
1952
1953 if (tst->status == VgTs_Empty)
1954 continue;
1955
1956 if (!VG_(ksigismember)(&tst->sig_mask, sigNo)) {
1957 vg_assert(tst->proxy != NULL);
1958 target = tid;
1959 start_tid = tid;
1960 break;
1961 }
1962 }
1963
fitzhardingee1c06d82003-10-30 07:21:44 +00001964 /* found one - deliver it and be done */
jsgf855d93d2003-10-13 22:26:55 +00001965 if (target != -1) {
1966 if (VG_(clo_trace_signals))
1967 VG_(message)(Vg_DebugMsg, "Routing signal %d to tid %d",
1968 sigNo, tid);
fitzhardingee1c06d82003-10-30 07:21:44 +00001969 VG_(proxy_sendsig)(target, sigNo);
1970 VG_(ksigdelset)(&proc_pending, sigNo);
jsgf855d93d2003-10-13 22:26:55 +00001971 }
1972 }
1973
fitzhardingee1c06d82003-10-30 07:21:44 +00001974 /* restore signal mask */
1975 VG_(restore_all_host_signals) (&set);
jsgf855d93d2003-10-13 22:26:55 +00001976}
sewardjde4a1d02002-03-22 01:27:54 +00001977
sewardj018f7622002-05-15 21:13:39 +00001978/* At startup, copy the process' real signal state to the SCSS.
1979 Whilst doing this, block all real signals. Then calculate SKSS and
1980 set the kernel to that. Also initialise DCSS.
sewardjde4a1d02002-03-22 01:27:54 +00001981*/
1982void VG_(sigstartup_actions) ( void )
1983{
1984 Int i, ret;
sewardjde4a1d02002-03-22 01:27:54 +00001985 vki_ksigset_t saved_procmask;
1986 vki_kstack_t altstack_info;
1987 vki_ksigaction sa;
1988
sewardj2e93c502002-04-12 11:12:52 +00001989 /* VG_(printf)("SIGSTARTUP\n"); */
jsgf855d93d2003-10-13 22:26:55 +00001990 /* Block all signals. saved_procmask remembers the previous mask,
1991 which the first thread inherits.
1992 */
sewardj2e93c502002-04-12 11:12:52 +00001993 VG_(block_all_host_signals)( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00001994
fitzhardingee1c06d82003-10-30 07:21:44 +00001995 /* clear process-wide pending signal set */
1996 VG_(ksigemptyset)(&proc_pending);
1997
jsgf855d93d2003-10-13 22:26:55 +00001998 /* Set the signal mask which the scheduler LWP should maintain from
1999 now on. */
2000 set_main_sigmask();
2001
sewardj018f7622002-05-15 21:13:39 +00002002 /* Copy per-signal settings to SCSS. */
2003 for (i = 1; i <= VKI_KNSIG; i++) {
2004
2005 /* Get the old host action */
2006 ret = VG_(ksigaction)(i, NULL, &sa);
2007 vg_assert(ret == 0);
2008
2009 if (VG_(clo_trace_signals))
2010 VG_(printf)("snaffling handler 0x%x for signal %d\n",
2011 (Addr)(sa.ksa_handler), i );
2012
2013 vg_scss.scss_per_sig[i].scss_handler = sa.ksa_handler;
2014 vg_scss.scss_per_sig[i].scss_flags = sa.ksa_flags;
2015 vg_scss.scss_per_sig[i].scss_mask = sa.ksa_mask;
2016 vg_scss.scss_per_sig[i].scss_restorer = sa.ksa_restorer;
2017 }
2018
jsgf855d93d2003-10-13 22:26:55 +00002019 /* Our private internal signals are treated as ignored */
2020 vg_scss.scss_per_sig[VKI_SIGVGINT].scss_handler = VKI_SIG_IGN;
2021 vg_scss.scss_per_sig[VKI_SIGVGINT].scss_flags = VKI_SA_SIGINFO;
2022 VG_(ksigfillset)(&vg_scss.scss_per_sig[VKI_SIGVGINT].scss_mask);
2023 vg_scss.scss_per_sig[VKI_SIGVGKILL].scss_handler = VKI_SIG_IGN;
2024 vg_scss.scss_per_sig[VKI_SIGVGKILL].scss_flags = VKI_SA_SIGINFO;
2025 VG_(ksigfillset)(&vg_scss.scss_per_sig[VKI_SIGVGKILL].scss_mask);
2026
sewardj018f7622002-05-15 21:13:39 +00002027 /* Copy the process' signal mask into the root thread. */
2028 vg_assert(VG_(threads)[1].status == VgTs_Runnable);
2029 VG_(threads)[1].sig_mask = saved_procmask;
jsgf855d93d2003-10-13 22:26:55 +00002030 VG_(proxy_setsigmask)(1);
sewardj018f7622002-05-15 21:13:39 +00002031
njn12a57142003-04-30 20:49:10 +00002032 /* Register an alternative stack for our own signal handler to run on. */
nethercote759dda32004-08-07 18:16:56 +00002033 altstack_info.ss_sp = &(sigstack[0]);
njn6eba4ef2003-05-01 08:06:41 +00002034 altstack_info.ss_size = VG_SIGSTACK_SIZE_W * sizeof(UInt);
sewardjde4a1d02002-03-22 01:27:54 +00002035 altstack_info.ss_flags = 0;
2036 ret = VG_(ksigaltstack)(&altstack_info, NULL);
2037 if (ret != 0) {
njne427a662002-10-02 11:08:25 +00002038 VG_(core_panic)(
sewardjde4a1d02002-03-22 01:27:54 +00002039 "vg_sigstartup_actions: couldn't install alternative sigstack");
2040 }
2041 if (VG_(clo_trace_signals)) {
2042 VG_(message)(Vg_DebugExtraMsg,
2043 "vg_sigstartup_actions: sigstack installed ok");
2044 }
2045
sewardj7a61d912002-04-25 01:27:35 +00002046 /* DEBUGGING HACK */
2047 /* VG_(ksignal)(VKI_SIGUSR1, &VG_(oursignalhandler)); */
2048
sewardj018f7622002-05-15 21:13:39 +00002049 /* Calculate SKSS and apply it. This also sets the initial kernel
2050 mask we need to run with. */
nethercote9dd11512004-08-04 15:31:30 +00002051 handle_SCSS_change( True /* forced update */ );
jsgf855d93d2003-10-13 22:26:55 +00002052
sewardjde4a1d02002-03-22 01:27:54 +00002053}
2054
sewardjde4a1d02002-03-22 01:27:54 +00002055/*--------------------------------------------------------------------*/
2056/*--- end vg_signals.c ---*/
2057/*--------------------------------------------------------------------*/