m_libcsignal.c revision f76d27a697a7b0bf3b84490baf60623fc96a23af
1 2/*--------------------------------------------------------------------*/ 3/*--- Signal-related libc stuff. m_libcsignal.c ---*/ 4/*--------------------------------------------------------------------*/ 5 6/* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2000-2009 Julian Seward 11 jseward@acm.org 12 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. 17 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. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26 02111-1307, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29*/ 30 31#include "pub_core_basics.h" 32#include "pub_core_debuglog.h" 33#include "pub_core_vki.h" 34#include "pub_core_vkiscnums.h" 35#include "pub_core_libcbase.h" 36#include "pub_core_libcassert.h" 37#include "pub_core_syscall.h" 38#include "pub_core_libcsignal.h" /* self */ 39 40/* IMPORTANT: on Darwin it is essential to use the _nocancel versions 41 of syscalls rather than the vanilla version, if a _nocancel version 42 is available. See docs/internals/Darwin-notes.txt for the reason 43 why. */ 44 45/* sigemptyset, sigfullset, sigaddset and sigdelset return 0 on 46 success and -1 on error. */ 47/* I believe the indexing scheme in ->sig[] is also correct for 48 32- and 64-bit AIX (verified 27 July 06). */ 49/* In the sigset routines below, be aware that _VKI_NSIG_BPW can be 50 either 32 or 64, and hence the sig[] words can either be 32- or 51 64-bits. And which they are it doesn't necessarily follow from the 52 host word size. */ 53 54Int VG_(sigfillset)( vki_sigset_t* set ) 55{ 56 Int i; 57 if (set == NULL) 58 return -1; 59 for (i = 0; i < _VKI_NSIG_WORDS; i++) 60 set->sig[i] = ~0; 61 return 0; 62} 63 64Int VG_(sigemptyset)( vki_sigset_t* set ) 65{ 66 Int i; 67 if (set == NULL) 68 return -1; 69 for (i = 0; i < _VKI_NSIG_WORDS; i++) 70 set->sig[i] = 0; 71 return 0; 72} 73 74Bool VG_(isemptysigset)( const vki_sigset_t* set ) 75{ 76 Int i; 77 vg_assert(set != NULL); 78 for (i = 0; i < _VKI_NSIG_WORDS; i++) 79 if (set->sig[i] != 0) return False; 80 return True; 81} 82 83Bool VG_(isfullsigset)( const vki_sigset_t* set ) 84{ 85 Int i; 86 vg_assert(set != NULL); 87 for (i = 0; i < _VKI_NSIG_WORDS; i++) 88 if (set->sig[i] != ~0) return False; 89 return True; 90} 91 92Bool VG_(iseqsigset)( const vki_sigset_t* set1, const vki_sigset_t* set2 ) 93{ 94 Int i; 95 vg_assert(set1 != NULL && set2 != NULL); 96 for (i = 0; i < _VKI_NSIG_WORDS; i++) 97 if (set1->sig[i] != set2->sig[i]) return False; 98 return True; 99} 100 101 102Int VG_(sigaddset)( vki_sigset_t* set, Int signum ) 103{ 104 if (set == NULL) 105 return -1; 106 if (signum < 1 || signum > _VKI_NSIG) 107 return -1; 108 signum--; 109 set->sig[signum / _VKI_NSIG_BPW] |= (1ULL << (signum % _VKI_NSIG_BPW)); 110 return 0; 111} 112 113Int VG_(sigdelset)( vki_sigset_t* set, Int signum ) 114{ 115 if (set == NULL) 116 return -1; 117 if (signum < 1 || signum > _VKI_NSIG) 118 return -1; 119 signum--; 120 set->sig[signum / _VKI_NSIG_BPW] &= ~(1ULL << (signum % _VKI_NSIG_BPW)); 121 return 0; 122} 123 124Int VG_(sigismember) ( const vki_sigset_t* set, Int signum ) 125{ 126 if (set == NULL) 127 return 0; 128 if (signum < 1 || signum > _VKI_NSIG) 129 return 0; 130 signum--; 131 if (1 & ((set->sig[signum / _VKI_NSIG_BPW]) >> (signum % _VKI_NSIG_BPW))) 132 return 1; 133 else 134 return 0; 135} 136 137/* Add all signals in src to dst. */ 138void VG_(sigaddset_from_set)( vki_sigset_t* dst, vki_sigset_t* src ) 139{ 140 Int i; 141 vg_assert(dst != NULL && src != NULL); 142 for (i = 0; i < _VKI_NSIG_WORDS; i++) 143 dst->sig[i] |= src->sig[i]; 144} 145 146/* Remove all signals in src from dst. */ 147void VG_(sigdelset_from_set)( vki_sigset_t* dst, vki_sigset_t* src ) 148{ 149 Int i; 150 vg_assert(dst != NULL && src != NULL); 151 for (i = 0; i < _VKI_NSIG_WORDS; i++) 152 dst->sig[i] &= ~(src->sig[i]); 153} 154 155/* dst = dst `intersect` src. */ 156void VG_(sigintersectset)( vki_sigset_t* dst, vki_sigset_t* src ) 157{ 158 Int i; 159 vg_assert(dst != NULL && src != NULL); 160 for (i = 0; i < _VKI_NSIG_WORDS; i++) 161 dst->sig[i] &= src->sig[i]; 162} 163 164/* dst = ~src */ 165void VG_(sigcomplementset)( vki_sigset_t* dst, vki_sigset_t* src ) 166{ 167 Int i; 168 vg_assert(dst != NULL && src != NULL); 169 for (i = 0; i < _VKI_NSIG_WORDS; i++) 170 dst->sig[i] = ~ src->sig[i]; 171} 172 173 174/* The functions sigaction, sigprocmask, sigpending and sigsuspend 175 return 0 on success and -1 on error. 176*/ 177Int VG_(sigprocmask)( Int how, const vki_sigset_t* set, vki_sigset_t* oldset) 178{ 179# if defined(VGO_linux) || defined(VGO_aix5) 180# if defined(__NR_rt_sigprocmask) 181 SysRes res = VG_(do_syscall4)(__NR_rt_sigprocmask, 182 how, (UWord)set, (UWord)oldset, 183 _VKI_NSIG_WORDS * sizeof(UWord)); 184# else 185 SysRes res = VG_(do_syscall3)(__NR_sigprocmask, 186 how, (UWord)set, (UWord)oldset); 187# endif 188 189# elif defined(VGO_darwin) 190 /* On Darwin, __NR_sigprocmask appears to affect the entire 191 process, not just this thread. Hence need to use 192 __NR___pthread_sigmask instead. */ 193 SysRes res = VG_(do_syscall3)(__NR___pthread_sigmask, 194 how, (UWord)set, (UWord)oldset); 195# else 196# error "Unknown OS" 197# endif 198 return sr_isError(res) ? -1 : 0; 199} 200 201 202#if defined(VGO_darwin) 203/* A helper function for sigaction on Darwin. */ 204static 205void darwin_signal_demux(void* a1, UWord a2, UWord a3, void* a4, void* a5) { 206 VG_(debugLog)(2, "libcsignal", 207 "PRE demux sig, a2 = %lu, signo = %lu\n", a2, a3); 208 if (a2 == 1) 209 ((void(*)(int))a1) (a3); 210 else 211 ((void(*)(int,void*,void*))a1) (a3,a4,a5); 212 VG_(debugLog)(2, "libcsignal", 213 "POST demux sig, a2 = %lu, signo = %lu\n", a2, a3); 214 VG_(do_syscall2)(__NR_sigreturn, (UWord)a5, 0x1E); 215 /* NOTREACHED */ 216 __asm__ __volatile__("ud2"); 217} 218#endif 219 220Int VG_(sigaction) ( Int signum, 221 const vki_sigaction_toK_t* act, 222 vki_sigaction_fromK_t* oldact) 223{ 224# if defined(VGO_linux) || defined(VGO_aix5) 225 /* Normal case: vki_sigaction_toK_t and vki_sigaction_fromK_t are 226 identical types. */ 227 SysRes res = VG_(do_syscall4)(__NR_rt_sigaction, 228 signum, (UWord)act, (UWord)oldact, 229 _VKI_NSIG_WORDS * sizeof(UWord)); 230 return sr_isError(res) ? -1 : 0; 231 232# elif defined(VGO_darwin) 233 /* If we're passing a new action to the kernel, make a copy of the 234 new action, install our own sa_tramp field in it, and ignore 235 whatever we were provided with. This is OK because all the 236 sigaction requests come from m_signals, and are not directly 237 what the client program requested, so there is no chance that we 238 will inadvertantly ignore the sa_tramp field requested by the 239 client. (In fact m_signals does ignore it when building signal 240 frames for the client, but that's a completely different 241 matter). 242 243 If we're receiving an old action from the kernel, be very 244 paranoid and make sure the kernel doesn't trash bits of memory 245 that we don't expect it to. */ 246 SysRes res; 247 248 vki_sigaction_toK_t actCopy; 249 struct { 250 ULong before[2]; 251 vki_sigaction_fromK_t oa; 252 ULong after[2]; 253 } 254 oldactCopy; 255 256 vki_sigaction_toK_t* real_act; 257 vki_sigaction_fromK_t* real_oldact; 258 259 real_act = act ? &actCopy : NULL; 260 real_oldact = oldact ? &oldactCopy.oa : NULL; 261 VG_(memset)(&oldactCopy, 0x55, sizeof(oldactCopy)); 262 if (real_act) { 263 *real_act = *act; 264 real_act->sa_tramp = (void*)&darwin_signal_demux; 265 } 266 res = VG_(do_syscall3)(__NR_sigaction, 267 signum, (UWord)real_act, (UWord)real_oldact); 268 if (real_oldact) { 269 vg_assert(oldactCopy.before[0] == 0x5555555555555555ULL); 270 vg_assert(oldactCopy.before[1] == 0x5555555555555555ULL); 271 vg_assert(oldactCopy.after[0] == 0x5555555555555555ULL); 272 vg_assert(oldactCopy.after[1] == 0x5555555555555555ULL); 273 *oldact = *real_oldact; 274 } 275 return sr_isError(res) ? -1 : 0; 276 277# else 278# error "Unsupported OS" 279# endif 280} 281 282 283/* See explanation in pub_core_libcsignal.h. */ 284void 285VG_(convert_sigaction_fromK_to_toK)( vki_sigaction_fromK_t* fromK, 286 /*OUT*/vki_sigaction_toK_t* toK ) 287{ 288# if defined(VGO_linux) || defined(VGO_aix5) 289 *toK = *fromK; 290# elif defined(VGO_darwin) 291 toK->ksa_handler = fromK->ksa_handler; 292 toK->sa_tramp = NULL; /* the cause of all the difficulty */ 293 toK->sa_mask = fromK->sa_mask; 294 toK->sa_flags = fromK->sa_flags; 295# else 296# error "Unsupported OS" 297# endif 298} 299 300 301Int VG_(kill)( Int pid, Int signo ) 302{ 303# if defined(VGO_linux) || defined(VGO_aix5) 304 SysRes res = VG_(do_syscall2)(__NR_kill, pid, signo); 305# elif defined(VGO_darwin) 306 SysRes res = VG_(do_syscall3)(__NR_kill, 307 pid, signo, 1/*posix-compliant*/); 308# else 309# error "Unsupported OS" 310# endif 311 return sr_isError(res) ? -1 : 0; 312} 313 314Int VG_(tkill)( Int lwpid, Int signo ) 315{ 316# if defined(__NR_tkill) 317 SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS); 318 res = VG_(do_syscall2)(__NR_tkill, lwpid, signo); 319 if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS) 320 res = VG_(do_syscall2)(__NR_kill, lwpid, signo); 321 return sr_isError(res) ? -1 : 0; 322 323# elif defined(VGO_darwin) 324 // Note that the __pthread_kill syscall takes a Mach thread, not a pthread. 325 SysRes res; 326 res = VG_(do_syscall2)(__NR___pthread_kill, lwpid, signo); 327 return sr_isError(res) ? -1 : 0; 328 329# else 330# error "Unsupported plat" 331# endif 332} 333 334/* ---------------------- sigtimedwait_zero ----------------------- */ 335 336/* A cut-down version of POSIX sigtimedwait: poll for pending signals 337 mentioned in the sigset_t, and if any are present, select one 338 arbitrarily, return its number (which must be > 0), and put 339 auxiliary info about it in the siginfo_t, and make it 340 not-pending-any-more. If none are pending, return zero. The _zero 341 refers to the fact that there is zero timeout, so if no signals are 342 pending it returns immediately. Perhaps a better name would be 343 'sigpoll'. Returns -1 on error, 0 if no signals pending, and n > 0 344 if signal n was selected. 345 346 The Linux implementation is trivial: do the corresponding syscall. 347 348 The AIX implementation is horrible and probably broken in a dozen 349 obscure ways. I suspect it's only thread-safe because V forces 350 single-threadedness. */ 351 352/* ---------- sigtimedwait_zero: Linux ----------- */ 353 354#if defined(VGO_linux) 355Int VG_(sigtimedwait_zero)( const vki_sigset_t *set, 356 vki_siginfo_t *info ) 357{ 358 static const struct vki_timespec zero = { 0, 0 }; 359 SysRes res = VG_(do_syscall4)(__NR_rt_sigtimedwait, (UWord)set, (UWord)info, 360 (UWord)&zero, sizeof(*set)); 361 return sr_isError(res) ? -1 : sr_Res(res); 362} 363 364/* ---------- sigtimedwait_zero: AIX5 ----------- */ 365 366#elif defined(VGO_aix5) 367/* The general idea is: 368 - use sigpending to find out which signals are pending 369 - choose one 370 - temporarily set its handler to sigtimedwait_zero_handler 371 - use sigsuspend atomically unblock it and wait for the signal. 372 Upon return, sigsuspend restores the signal mask to what it 373 was to start with. 374 - Restore the handler for the signal to whatever it was before. 375*/ 376 377/* A signal handler which does nothing (it doesn't need to). It does 378 however check that it's not handing a sync signal for which 379 returning is meaningless. */ 380static void sigtimedwait_zero_handler ( Int sig ) 381{ 382 vg_assert(sig != VKI_SIGILL); 383 vg_assert(sig != VKI_SIGSEGV); 384 vg_assert(sig != VKI_SIGBUS); 385 vg_assert(sig != VKI_SIGTRAP); 386 /* do nothing */ 387} 388 389Int VG_(sigtimedwait_zero)( const vki_sigset_t *set, 390 vki_siginfo_t *info ) 391{ 392 Int i, ir; 393 SysRes sr; 394 vki_sigset_t pending, blocked, allbutone; 395 struct vki_sigaction sa, saved_sa; 396 397 /* Find out what's pending: AIX _sigpending */ 398 sr = VG_(do_syscall1)(__NR__sigpending, (UWord)&pending); 399 vg_assert(!sr.isError); 400 401 /* don't try for signals not in 'set' */ 402 /* pending = pending `intersect` set */ 403 VG_(sigintersectset)(&pending, set); 404 405 /* don't try for signals not blocked at the moment */ 406 ir = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &blocked); 407 vg_assert(ir == 0); 408 409 /* pending = pending `intersect` blocked */ 410 VG_(sigintersectset)(&pending, blocked); 411 412 /* decide which signal we're going to snarf */ 413 for (i = 1; i < _VKI_NSIG; i++) 414 if (VG_(sigismember)(&pending,i)) 415 break; 416 417 if (i == _VKI_NSIG) 418 return 0; 419 420 /* fetch signal i. 421 pre: i is blocked and pending 422 pre: we are the only thread running 423 */ 424 /* Set up alternative signal handler */ 425 VG_(sigfillset)(&allbutone); 426 VG_(sigdelset)(&allbutone, i); 427 sa.sa_mask = allbutone; 428 sa.ksa_handler = &sigtimedwait_zero_handler; 429 sa.sa_flags = 0; 430 ir = VG_(sigaction)(i, &sa, &saved_sa); 431 vg_assert(ir == 0); 432 433 /* Switch signal masks and wait for the signal. This should happen 434 immediately, since we've already established it is pending and 435 blocked. */ 436 sr = VG_(do_syscall1)(__NR__sigsuspend, (UWord)&allbutone); 437 vg_assert(sr.isError); 438 if (0) 439 VG_(debugLog)(0, "libcsignal", 440 "sigtimedwait_zero: sigsuspend got res %ld err %ld\n", 441 sr.res, sr.err); 442 vg_assert(sr.res == (UWord)-1); 443 444 /* Restore signal's handler to whatever it was before */ 445 ir = VG_(sigaction)(i, &saved_sa, NULL); 446 vg_assert(ir == 0); 447 448 /* This is bogus - we could get more info from the sighandler. */ 449 VG_(memset)( info, 0, sizeof(*info) ); 450 info->si_signo = i; 451 452 return i; 453} 454 455/* ---------- sigtimedwait_zero: Darwin ----------- */ 456 457#elif defined(VGO_darwin) 458 459//static void show_set ( HChar* str, const vki_sigset_t* set ) { 460// Int i; 461// VG_(printf)("%s { ", str); 462// for (i = 1; i <= _VKI_NSIG; i++) { 463// if (VG_(sigismember)(set, i)) 464// VG_(printf)("%u ", i); 465// } 466// VG_(printf)("}\n"); 467//} 468 469static void sigtimedwait_zero_handler ( Int sig ) 470{ 471 /* XXX this is wrong -- get rid of these. We could 472 get _any_ signal here */ 473 vg_assert(sig != VKI_SIGILL); 474 vg_assert(sig != VKI_SIGSEGV); 475 vg_assert(sig != VKI_SIGBUS); 476 vg_assert(sig != VKI_SIGTRAP); 477 /* do nothing */ 478} 479 480Int VG_(sigtimedwait_zero)( const vki_sigset_t *set, 481 vki_siginfo_t *info ) 482{ 483 const Bool debug = False; 484 Int i, ir; 485 SysRes sr; 486 vki_sigset_t pending, blocked, allbutone; 487 vki_sigaction_toK_t sa, saved_sa2; 488 vki_sigaction_fromK_t saved_sa; 489 490 //show_set("STWZ: looking for", set); 491 492 /* Find out what's pending: Darwin sigpending */ 493 sr = VG_(do_syscall1)(__NR_sigpending, (UWord)&pending); 494 vg_assert(!sr_isError(sr)); 495 496 /* don't try for signals not in 'set' */ 497 /* pending = pending `intersect` set */ 498 VG_(sigintersectset)(&pending, (vki_sigset_t*)set); 499 500 /* don't try for signals not blocked at the moment */ 501 ir = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &blocked); 502 vg_assert(ir == 0); 503 504 /* pending = pending `intersect` blocked */ 505 VG_(sigintersectset)(&pending, &blocked); 506 507 /* decide which signal we're going to snarf */ 508 for (i = 1; i < _VKI_NSIG; i++) 509 if (VG_(sigismember)(&pending,i)) 510 break; 511 512 if (i == _VKI_NSIG) 513 return 0; 514 515 if (debug) 516 VG_(debugLog)(0, "libcsignal", 517 "sigtimedwait_zero: snarfing signal %d\n", i ); 518 519 /* fetch signal i. 520 pre: i is blocked and pending 521 pre: we are the only thread running 522 */ 523 /* Set up alternative signal handler */ 524 VG_(sigfillset)(&sa.sa_mask); 525 sa.ksa_handler = &sigtimedwait_zero_handler; 526 sa.sa_flags = 0; 527 ir = VG_(sigaction)(i, &sa, &saved_sa); 528 vg_assert(ir == 0); 529 530 /* Switch signal masks and wait for the signal. This should happen 531 immediately, since we've already established it is pending and 532 blocked. */ 533 VG_(sigfillset)(&allbutone); 534 VG_(sigdelset)(&allbutone, i); 535 /* Note: pass the sig mask by value here, not reference (!) */ 536 vg_assert(_VKI_NSIG_WORDS == 1); 537 sr = VG_(do_syscall3)(__NR_sigsuspend_nocancel, 538 (UWord)allbutone.sig[0], 0,0); 539 if (debug) 540 VG_(debugLog)(0, "libcsignal", 541 "sigtimedwait_zero: sigsuspend got " 542 "res: %s %#lx\n", 543 sr_isError(sr) ? "FAIL" : "SUCCESS", 544 sr_isError(sr) ? sr_Err(sr) : sr_Res(sr)); 545 vg_assert(sr_isError(sr)); 546 vg_assert(sr_Err(sr) == VKI_EINTR); 547 548 /* Restore signal's handler to whatever it was before */ 549 VG_(convert_sigaction_fromK_to_toK)( &saved_sa, &saved_sa2 ); 550 ir = VG_(sigaction)(i, &saved_sa2, NULL); 551 vg_assert(ir == 0); 552 553 /* This is bogus - we could get more info from the sighandler. */ 554 VG_(memset)( info, 0, sizeof(*info) ); 555 info->si_signo = i; 556 557 return i; 558} 559 560#else 561# error "Unknown OS" 562#endif 563 564/*--------------------------------------------------------------------*/ 565/*--- end ---*/ 566/*--------------------------------------------------------------------*/ 567