Fix typo in FAQ.
[valgrind.git] / coregrind / m_libcsignal.c
bloba32b53a2f4cefb65cdaccc81fddde345adc402f1
2 /*--------------------------------------------------------------------*/
3 /*--- Signal-related libc stuff. m_libcsignal.c ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2017 Julian Seward
11 jseward@acm.org
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #include "pub_core_basics.h"
30 #include "pub_core_debuglog.h"
31 #include "pub_core_vki.h"
32 #include "pub_core_vkiscnums.h"
33 #include "pub_core_libcbase.h"
34 #include "pub_core_libcassert.h"
35 #include "pub_core_syscall.h"
36 #include "pub_core_libcsignal.h" /* self */
37 #include "pub_core_libcproc.h"
39 #if !defined(VGO_solaris)
40 # define _VKI_MAXSIG (_VKI_NSIG - 1)
41 #endif
42 STATIC_ASSERT((_VKI_MAXSIG % _VKI_NSIG_BPW) != 0);
44 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
45 of syscalls rather than the vanilla version, if a _nocancel version
46 is available. See docs/internals/Darwin-notes.txt for the reason
47 why. */
49 /* sigemptyset, sigfullset, sigaddset and sigdelset return 0 on
50 success and -1 on error. */
51 /* In the sigset routines below, be aware that _VKI_NSIG_BPW can be
52 either 32 or 64, and hence the sig[] words can either be 32- or
53 64-bits. And which they are it doesn't necessarily follow from the
54 host word size. */
56 /* Functions VG_(isemptysigset) and VG_(isfullsigset) check only bits that
57 represent valid signals (i.e. signals <= _VKI_MAXSIG). The same applies
58 for the comparison in VG_(iseqsigset). This is important because when
59 a signal set is received from an operating system then bits which represent
60 signals > _VKI_MAXSIG can have unexpected values for Valgrind. This is
61 mainly specific to the Solaris kernel which clears these bits. */
63 Int VG_(sigfillset)( vki_sigset_t* set )
65 Int i;
66 if (set == NULL)
67 return -1;
68 for (i = 0; i < _VKI_NSIG_WORDS; i++)
69 set->sig[i] = ~0;
70 return 0;
73 Int VG_(sigemptyset)( vki_sigset_t* set )
75 Int i;
76 if (set == NULL)
77 return -1;
78 for (i = 0; i < _VKI_NSIG_WORDS; i++)
79 set->sig[i] = 0;
80 return 0;
83 Bool VG_(isemptysigset)( const vki_sigset_t* set )
85 Int i;
86 vg_assert(set != NULL);
87 for (i = 0; i < _VKI_NSIG_WORDS; i++) {
88 if (_VKI_NSIG_BPW * (i + 1) <= (_VKI_MAXSIG + 1)) {
89 /* Full word check. */
90 if (set->sig[i] != 0) return False;
92 else {
93 /* Partial word check. */
94 ULong mask = ((ULong)1UL << (_VKI_MAXSIG % _VKI_NSIG_BPW)) - 1;
95 if ((set->sig[i] & mask) != 0) return False;
96 break;
99 return True;
102 Bool VG_(isfullsigset)( const vki_sigset_t* set )
104 Int i;
105 vg_assert(set != NULL);
106 for (i = 0; i < _VKI_NSIG_WORDS; i++) {
107 if (_VKI_NSIG_BPW * (i + 1) <= (_VKI_MAXSIG + 1)) {
108 /* Full word check. */
109 if (set->sig[i] != ~0) return False;
111 else {
112 /* Partial word check. */
113 ULong mask = ((ULong)1UL << (_VKI_MAXSIG % _VKI_NSIG_BPW)) - 1;
114 if ((set->sig[i] & mask) != mask) return False;
115 break;
118 return True;
121 Bool VG_(iseqsigset)( const vki_sigset_t* set1, const vki_sigset_t* set2 )
123 Int i;
124 vg_assert(set1 != NULL && set2 != NULL);
125 for (i = 0; i < _VKI_NSIG_WORDS; i++) {
126 if (_VKI_NSIG_BPW * (i + 1) <= (_VKI_MAXSIG + 1)) {
127 /* Full word comparison. */
128 if (set1->sig[i] != set2->sig[i]) return False;
130 else {
131 /* Partial word comparison. */
132 ULong mask = ((ULong)1UL << (_VKI_MAXSIG % _VKI_NSIG_BPW)) - 1;
133 if ((set1->sig[i] & mask) != (set2->sig[i] & mask)) return False;
134 break;
137 return True;
141 Int VG_(sigaddset)( vki_sigset_t* set, Int signum )
143 if (set == NULL)
144 return -1;
145 if (signum < 1 || signum > _VKI_NSIG)
146 return -1;
147 signum--;
148 set->sig[signum / _VKI_NSIG_BPW] |= (1ULL << (signum % _VKI_NSIG_BPW));
149 return 0;
152 Int VG_(sigdelset)( vki_sigset_t* set, Int signum )
154 if (set == NULL)
155 return -1;
156 if (signum < 1 || signum > _VKI_NSIG)
157 return -1;
158 signum--;
159 set->sig[signum / _VKI_NSIG_BPW] &= ~(1ULL << (signum % _VKI_NSIG_BPW));
160 return 0;
163 Int VG_(sigismember) ( const vki_sigset_t* set, Int signum )
165 if (set == NULL)
166 return 0;
167 if (signum < 1 || signum > _VKI_NSIG)
168 return 0;
169 signum--;
170 if (1 & ((set->sig[signum / _VKI_NSIG_BPW]) >> (signum % _VKI_NSIG_BPW)))
171 return 1;
172 else
173 return 0;
176 /* Add all signals in src to dst. */
177 void VG_(sigaddset_from_set)( vki_sigset_t* dst, const vki_sigset_t* src )
179 Int i;
180 vg_assert(dst != NULL && src != NULL);
181 for (i = 0; i < _VKI_NSIG_WORDS; i++)
182 dst->sig[i] |= src->sig[i];
185 /* Remove all signals in src from dst. */
186 void VG_(sigdelset_from_set)( vki_sigset_t* dst, const vki_sigset_t* src )
188 Int i;
189 vg_assert(dst != NULL && src != NULL);
190 for (i = 0; i < _VKI_NSIG_WORDS; i++)
191 dst->sig[i] &= ~(src->sig[i]);
194 /* dst = dst `intersect` src. */
195 void VG_(sigintersectset)( vki_sigset_t* dst, const vki_sigset_t* src )
197 Int i;
198 vg_assert(dst != NULL && src != NULL);
199 for (i = 0; i < _VKI_NSIG_WORDS; i++)
200 dst->sig[i] &= src->sig[i];
203 /* dst = ~src */
204 void VG_(sigcomplementset)( vki_sigset_t* dst, const vki_sigset_t* src )
206 Int i;
207 vg_assert(dst != NULL && src != NULL);
208 for (i = 0; i < _VKI_NSIG_WORDS; i++)
209 dst->sig[i] = ~ src->sig[i];
213 /* The functions sigaction, sigprocmask, sigpending and sigsuspend
214 return 0 on success and -1 on error.
216 Int VG_(sigprocmask)( Int how, const vki_sigset_t* set, vki_sigset_t* oldset)
218 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
219 # if defined(__NR_rt_sigprocmask)
220 SysRes res = VG_(do_syscall4)(__NR_rt_sigprocmask,
221 how, (UWord)set, (UWord)oldset,
222 _VKI_NSIG_WORDS * sizeof(UWord));
223 # else
224 SysRes res = VG_(do_syscall3)(__NR_sigprocmask,
225 how, (UWord)set, (UWord)oldset);
226 # endif
228 # elif defined(VGO_darwin)
229 /* On Darwin, __NR_sigprocmask appears to affect the entire
230 process, not just this thread. Hence need to use
231 __NR___pthread_sigmask instead. */
232 SysRes res = VG_(do_syscall3)(__NR___pthread_sigmask,
233 how, (UWord)set, (UWord)oldset);
234 # else
235 # error "Unknown OS"
236 # endif
237 return sr_isError(res) ? -1 : 0;
241 #if defined(VGO_darwin)
242 /* A helper function for sigaction on Darwin. */
243 static
244 void darwin_signal_demux(void* a1, UWord a2, UWord a3, void* a4, void* a5) {
245 VG_(debugLog)(2, "libcsignal",
246 "PRE demux sig, a2 = %lu, signo = %lu\n", a2, a3);
247 if (a2 == 1)
248 ((void(*)(int))a1) (a3);
249 else
250 ((void(*)(int,void*,void*))a1) (a3,a4,a5);
251 VG_(debugLog)(2, "libcsignal",
252 "POST demux sig, a2 = %lu, signo = %lu\n", a2, a3);
253 VG_(do_syscall2)(__NR_sigreturn, (UWord)a5, 0x1E);
254 /* NOTREACHED */
255 __asm__ __volatile__("ud2");
257 #endif
259 Int VG_(sigaction) ( Int signum,
260 const vki_sigaction_toK_t* act,
261 vki_sigaction_fromK_t* oldact)
263 # if defined(VGO_linux)
264 /* Normal case: vki_sigaction_toK_t and vki_sigaction_fromK_t are
265 identical types. */
266 SysRes res = VG_(do_syscall4)(__NR_rt_sigaction,
267 signum, (UWord)act, (UWord)oldact,
268 _VKI_NSIG_WORDS * sizeof(UWord));
269 return sr_isError(res) ? -1 : 0;
271 # elif defined(VGO_darwin)
272 /* If we're passing a new action to the kernel, make a copy of the
273 new action, install our own sa_tramp field in it, and ignore
274 whatever we were provided with. This is OK because all the
275 sigaction requests come from m_signals, and are not directly
276 what the client program requested, so there is no chance that we
277 will inadvertently ignore the sa_tramp field requested by the
278 client. (In fact m_signals does ignore it when building signal
279 frames for the client, but that's a completely different
280 matter).
282 If we're receiving an old action from the kernel, be very
283 paranoid and make sure the kernel doesn't trash bits of memory
284 that we don't expect it to. */
285 SysRes res;
287 vki_sigaction_toK_t actCopy;
288 struct {
289 ULong before[2];
290 vki_sigaction_fromK_t oa;
291 ULong after[2];
293 oldactCopy;
295 vki_sigaction_toK_t* real_act;
296 vki_sigaction_fromK_t* real_oldact;
298 real_act = act ? &actCopy : NULL;
299 real_oldact = oldact ? &oldactCopy.oa : NULL;
300 VG_(memset)(&oldactCopy, 0x55, sizeof(oldactCopy));
301 if (real_act) {
302 *real_act = *act;
303 real_act->sa_tramp = (void*)&darwin_signal_demux;
305 res = VG_(do_syscall3)(__NR_sigaction,
306 signum, (UWord)real_act, (UWord)real_oldact);
307 if (real_oldact) {
308 vg_assert(oldactCopy.before[0] == 0x5555555555555555ULL);
309 vg_assert(oldactCopy.before[1] == 0x5555555555555555ULL);
310 vg_assert(oldactCopy.after[0] == 0x5555555555555555ULL);
311 vg_assert(oldactCopy.after[1] == 0x5555555555555555ULL);
312 *oldact = *real_oldact;
314 return sr_isError(res) ? -1 : 0;
316 # elif defined(VGO_solaris)
317 /* vki_sigaction_toK_t and vki_sigaction_fromK_t are identical types. */
318 SysRes res = VG_(do_syscall3)(__NR_sigaction,
319 signum, (UWord)act, (UWord)oldact);
320 return sr_isError(res) ? -1 : 0;
322 # elif defined(VGO_freebsd)
323 SysRes res = VG_(do_syscall3)(__NR_sigaction,
324 signum, (UWord)act, (UWord)oldact);
325 return sr_isError(res) ? -1 : 0;
328 # elif defined(VGO_freebsd)
329 SysRes res = VG_(do_syscall3)(__NR_sigaction,
330 signum, (UWord)act, (UWord)oldact);
331 return sr_isError(res) ? -1 : 0;
334 # else
335 # error "Unsupported OS"
336 # endif
340 /* See explanation in pub_core_libcsignal.h. */
341 void
342 VG_(convert_sigaction_fromK_to_toK)( const vki_sigaction_fromK_t* fromK,
343 /*OUT*/vki_sigaction_toK_t* toK )
345 # if defined(VGO_linux) || defined(VGO_solaris) || defined(VGO_freebsd)
346 *toK = *fromK;
347 # elif defined(VGO_darwin)
348 toK->ksa_handler = fromK->ksa_handler;
349 toK->sa_tramp = NULL; /* the cause of all the difficulty */
350 toK->sa_mask = fromK->sa_mask;
351 toK->sa_flags = fromK->sa_flags;
352 # else
353 # error "Unsupported OS"
354 # endif
358 Int VG_(kill)( Int pid, Int signo )
360 # if defined(VGO_linux) || defined(VGO_solaris)
361 SysRes res = VG_(do_syscall2)(__NR_kill, pid, signo);
362 # elif defined(VGO_darwin) || defined(VGO_freebsd)
363 SysRes res = VG_(do_syscall3)(__NR_kill,
364 pid, signo, 1/*posix-compliant*/);
365 # else
366 # error "Unsupported OS"
367 # endif
368 return sr_isError(res) ? -1 : 0;
371 Int VG_(tkill)( Int lwpid, Int signo )
373 # if defined(__NR_tkill)
374 SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
375 res = VG_(do_syscall2)(__NR_tkill, lwpid, signo);
376 if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
377 res = VG_(do_syscall2)(__NR_kill, lwpid, signo);
378 return sr_isError(res) ? -1 : 0;
380 # elif defined(VGO_darwin)
381 // Note that the __pthread_kill syscall takes a Mach thread, not a pthread.
382 SysRes res;
383 res = VG_(do_syscall2)(__NR___pthread_kill, lwpid, signo);
384 return sr_isError(res) ? -1 : 0;
386 # elif defined(VGO_solaris)
387 SysRes res;
388 # if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL)
389 # if defined(SOLARIS_LWP_SIGQUEUE_SYSCALL_TAKES_PID)
390 res = VG_(do_syscall6)(__NR_lwp_sigqueue, 0, lwpid, signo,
391 0, VKI_SI_LWP, 0);
392 # else
393 res = VG_(do_syscall5)(__NR_lwp_sigqueue, lwpid, signo,
394 0, VKI_SI_LWP, 0);
395 # endif
396 # else
397 res = VG_(do_syscall2)(__NR_lwp_kill, lwpid, signo);
398 # endif
399 return sr_isError(res) ? -1 : 0;
401 # elif defined(VGO_freebsd)
402 SysRes res;
403 res = VG_(do_syscall2)(__NR_thr_kill, lwpid, signo);
404 return sr_isError(res) ? -1 : 0;
406 # else
407 # error "Unsupported plat"
408 # endif
411 /* ---------------------- sigtimedwait_zero ----------------------- */
413 /* A cut-down version of POSIX sigtimedwait: poll for pending signals
414 mentioned in the sigset_t, and if any are present, select one
415 arbitrarily, return its number (which must be > 0), and put
416 auxiliary info about it in the siginfo_t, and make it
417 not-pending-any-more. If none are pending, return zero. The _zero
418 refers to the fact that there is zero timeout, so if no signals are
419 pending it returns immediately. Perhaps a better name would be
420 'sigpoll'. Returns -1 on error, 0 if no signals pending, and n > 0
421 if signal n was selected.
423 The Linux implementation is trivial: do the corresponding syscall.
425 The Darwin implementation is horrible and probably broken in a dozen
426 obscure ways. I suspect it's only thread-safe because V forces
427 single-threadedness. */
429 /* ---------- sigtimedwait_zero: Linux ----------- */
431 #if defined(VGO_linux)
432 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
433 vki_siginfo_t *info )
435 static const struct vki_timespec zero = { 0, 0 };
436 SysRes res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info,
437 (UWord)&zero, sizeof(*set));
438 return sr_isError(res) ? -1 : sr_Res(res);
441 /* ---------- sigtimedwait_zero: Darwin ----------- */
443 #elif defined(VGO_darwin)
445 //static void show_set ( HChar* str, const vki_sigset_t* set ) {
446 // Int i;
447 // VG_(printf)("%s { ", str);
448 // for (i = 1; i <= _VKI_NSIG; i++) {
449 // if (VG_(sigismember)(set, i))
450 // VG_(printf)("%u ", i);
451 // }
452 // VG_(printf)("}\n");
455 /* The general idea is:
456 - use sigpending to find out which signals are pending
457 - choose one
458 - temporarily set its handler to sigtimedwait_zero_handler
459 - use sigsuspend atomically unblock it and wait for the signal.
460 Upon return, sigsuspend restores the signal mask to what it
461 was to start with.
462 - Restore the handler for the signal to whatever it was before.
465 /* A signal handler which does nothing (it doesn't need to). It does
466 however check that it's not handing a sync signal for which
467 returning is meaningless. */
468 static void sigtimedwait_zero_handler ( Int sig )
470 /* XXX this is wrong -- get rid of these. We could
471 get _any_ signal here */
472 vg_assert(sig != VKI_SIGILL);
473 vg_assert(sig != VKI_SIGSEGV);
474 vg_assert(sig != VKI_SIGBUS);
475 vg_assert(sig != VKI_SIGTRAP);
476 /* do nothing */
479 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
480 vki_siginfo_t *info )
482 const Bool debug = False;
483 Int i, ir;
484 SysRes sr;
485 vki_sigset_t pending, blocked, allbutone;
486 vki_sigaction_toK_t sa, saved_sa2;
487 vki_sigaction_fromK_t saved_sa;
489 //show_set("STWZ: looking for", set);
491 /* Find out what's pending: Darwin sigpending */
492 sr = VG_(do_syscall1)(__NR_sigpending, (UWord)&pending);
493 vg_assert(!sr_isError(sr));
495 /* don't try for signals not in 'set' */
496 /* pending = pending `intersect` set */
497 VG_(sigintersectset)(&pending, (const vki_sigset_t*)set);
499 /* don't try for signals not blocked at the moment */
500 ir = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &blocked);
501 vg_assert(ir == 0);
503 /* pending = pending `intersect` blocked */
504 VG_(sigintersectset)(&pending, &blocked);
506 /* decide which signal we're going to snarf */
507 for (i = 1; i < _VKI_NSIG; i++)
508 if (VG_(sigismember)(&pending,i))
509 break;
511 if (i == _VKI_NSIG)
512 return 0;
514 if (debug)
515 VG_(debugLog)(0, "libcsignal",
516 "sigtimedwait_zero: snarfing signal %d\n", i );
518 /* fetch signal i.
519 pre: i is blocked and pending
520 pre: we are the only thread running
522 /* Set up alternative signal handler */
523 VG_(sigfillset)(&sa.sa_mask);
524 sa.ksa_handler = &sigtimedwait_zero_handler;
525 sa.sa_flags = 0;
526 ir = VG_(sigaction)(i, &sa, &saved_sa);
527 vg_assert(ir == 0);
529 /* Switch signal masks and wait for the signal. This should happen
530 immediately, since we've already established it is pending and
531 blocked. */
532 VG_(sigfillset)(&allbutone);
533 VG_(sigdelset)(&allbutone, i);
534 /* Note: pass the sig mask by value here, not reference (!) */
535 vg_assert(_VKI_NSIG_WORDS == 1);
536 sr = VG_(do_syscall3)(__NR_sigsuspend_nocancel,
537 (UWord)allbutone.sig[0], 0,0);
538 if (debug)
539 VG_(debugLog)(0, "libcsignal",
540 "sigtimedwait_zero: sigsuspend got "
541 "res: %s %#lx\n",
542 sr_isError(sr) ? "FAIL" : "SUCCESS",
543 sr_isError(sr) ? sr_Err(sr) : sr_Res(sr));
544 vg_assert(sr_isError(sr));
545 vg_assert(sr_Err(sr) == VKI_EINTR);
547 /* Restore signal's handler to whatever it was before */
548 VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &saved_sa2 );
549 ir = VG_(sigaction)(i, &saved_sa2, NULL);
550 vg_assert(ir == 0);
552 /* This is bogus - we could get more info from the sighandler. */
553 VG_(memset)( info, 0, sizeof(*info) );
554 info->si_signo = i;
556 return i;
559 #elif defined(VGO_solaris)
560 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set, vki_siginfo_t *info )
562 /* Trivial as on Linux. */
563 static const struct vki_timespec zero = { 0, 0 };
564 SysRes res = VG_(do_syscall3)(__NR_sigtimedwait, (UWord)set, (UWord)info,
565 (UWord)&zero);
566 return sr_isError(res) ? -1 : sr_Res(res);
569 #elif defined(VGO_freebsd)
572 Int VG_(sigtimedwait_zero)( const vki_sigset_t *set,
573 vki_siginfo_t *info )
575 static const struct vki_timespec zero = { 0, 0 };
577 SysRes res = VG_(do_syscall3)(__NR_sigtimedwait, (UWord)set, (UWord)info,
578 (UWord)&zero);
579 return sr_isError(res) ? -1 : sr_Res(res);
582 #else
583 # error "Unknown OS"
584 #endif
586 /*--------------------------------------------------------------------*/
587 /*--- end ---*/
588 /*--------------------------------------------------------------------*/