1/* 2 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the author nor the names of any co-contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD: releng/10.3/lib/libkse/thread/thr_sig.c 177626 2008-03-26 07:32:08Z brueffer $ 30 */ 31 32#include "namespace.h" 33#include <sys/param.h> 34#include <sys/types.h> 35#include <sys/signalvar.h> 36#include <signal.h> 37#include <errno.h> 38#include <fcntl.h> 39#include <unistd.h> 40#include <string.h> 41#include <pthread.h> 42#include "un-namespace.h" 43#include "thr_private.h" 44 45/* Prototypes: */ 46static inline void build_siginfo(siginfo_t *info, int signo); 47#ifndef SYSTEM_SCOPE_ONLY 48static struct pthread *thr_sig_find(struct kse *curkse, int sig, 49 siginfo_t *info); 50#endif 51static inline void thr_sigframe_restore(struct pthread *thread, 52 struct pthread_sigframe *psf); 53static inline void thr_sigframe_save(struct pthread *thread, 54 struct pthread_sigframe *psf); 55 56#define SA_KILL 0x01 /* terminates process by default */ 57#define SA_STOP 0x02 58#define SA_CONT 0x04 59 60static int sigproptbl[NSIG] = { 61 SA_KILL, /* SIGHUP */ 62 SA_KILL, /* SIGINT */ 63 SA_KILL, /* SIGQUIT */ 64 SA_KILL, /* SIGILL */ 65 SA_KILL, /* SIGTRAP */ 66 SA_KILL, /* SIGABRT */ 67 SA_KILL, /* SIGEMT */ 68 SA_KILL, /* SIGFPE */ 69 SA_KILL, /* SIGKILL */ 70 SA_KILL, /* SIGBUS */ 71 SA_KILL, /* SIGSEGV */ 72 SA_KILL, /* SIGSYS */ 73 SA_KILL, /* SIGPIPE */ 74 SA_KILL, /* SIGALRM */ 75 SA_KILL, /* SIGTERM */ 76 0, /* SIGURG */ 77 SA_STOP, /* SIGSTOP */ 78 SA_STOP, /* SIGTSTP */ 79 SA_CONT, /* SIGCONT */ 80 0, /* SIGCHLD */ 81 SA_STOP, /* SIGTTIN */ 82 SA_STOP, /* SIGTTOU */ 83 0, /* SIGIO */ 84 SA_KILL, /* SIGXCPU */ 85 SA_KILL, /* SIGXFSZ */ 86 SA_KILL, /* SIGVTALRM */ 87 SA_KILL, /* SIGPROF */ 88 0, /* SIGWINCH */ 89 0, /* SIGINFO */ 90 SA_KILL, /* SIGUSR1 */ 91 SA_KILL /* SIGUSR2 */ 92}; 93 94/* #define DEBUG_SIGNAL */ 95#ifdef DEBUG_SIGNAL 96#define DBG_MSG stdout_debug 97#else 98#define DBG_MSG(x...) 99#endif 100 101/* 102 * Signal setup and delivery. 103 * 104 * 1) Delivering signals to threads in the same KSE. 105 * These signals are sent by upcall events and are set in the 106 * km_sigscaught field of the KSE mailbox. Since these signals 107 * are received while operating on the KSE stack, they can be 108 * delivered either by using signalcontext() to add a stack frame 109 * to the target thread's stack, or by adding them in the thread's 110 * pending set and having the thread run them down after it 111 * 2) Delivering signals to threads in other KSEs/KSEGs. 112 * 3) Delivering signals to threads in critical regions. 113 * 4) Delivering signals to threads after they change their signal masks. 114 * 115 * Methods of delivering signals. 116 * 117 * 1) Add a signal frame to the thread's saved context. 118 * 2) Add the signal to the thread structure, mark the thread as 119 * having signals to handle, and let the thread run them down 120 * after it resumes from the KSE scheduler. 121 * 122 * Problem with 1). You can't do this to a running thread or a 123 * thread in a critical region. 124 * 125 * Problem with 2). You can't do this to a thread that doesn't 126 * yield in some way (explicitly enters the scheduler). A thread 127 * blocked in the kernel or a CPU hungry thread will not see the 128 * signal without entering the scheduler. 129 * 130 * The solution is to use both 1) and 2) to deliver signals: 131 * 132 * o Thread in critical region - use 2). When the thread 133 * leaves the critical region it will check to see if it 134 * has pending signals and run them down. 135 * 136 * o Thread enters scheduler explicitly - use 2). The thread 137 * can check for pending signals after it returns from the 138 * the scheduler. 139 * 140 * o Thread is running and not current thread - use 2). When the 141 * thread hits a condition specified by one of the other bullets, 142 * the signal will be delivered. 143 * 144 * o Thread is running and is current thread (e.g., the thread 145 * has just changed its signal mask and now sees that it has 146 * pending signals) - just run down the pending signals. 147 * 148 * o Thread is swapped out due to quantum expiration - use 1) 149 * 150 * o Thread is blocked in kernel - kse_thr_wakeup() and then 151 * use 1) 152 */ 153 154/* 155 * Rules for selecting threads for signals received: 156 * 157 * 1) If the signal is a sychronous signal, it is delivered to 158 * the generating (current thread). If the thread has the 159 * signal masked, it is added to the threads pending signal 160 * set until the thread unmasks it. 161 * 162 * 2) A thread in sigwait() where the signal is in the thread's 163 * waitset. 164 * 165 * 3) A thread in sigsuspend() where the signal is not in the 166 * thread's suspended signal mask. 167 * 168 * 4) Any thread (first found/easiest to deliver) that has the 169 * signal unmasked. 170 */ 171 172#ifndef SYSTEM_SCOPE_ONLY 173 174static void * 175sig_daemon(void *arg __unused) 176{ 177 int i; 178 kse_critical_t crit; 179 struct timespec ts; 180 sigset_t set; 181 struct kse *curkse; 182 struct pthread *curthread = _get_curthread(); 183 184 DBG_MSG("signal daemon started(%p)\n", curthread); 185 186 curthread->name = strdup("signal thread"); 187 crit = _kse_critical_enter(); 188 curkse = _get_curkse(); 189 190 /* 191 * Daemon thread is a bound thread and we must be created with 192 * all signals masked 193 */ 194#if 0 195 SIGFILLSET(set); 196 __sys_sigprocmask(SIG_SETMASK, &set, NULL); 197#endif 198 __sys_sigpending(&set); 199 ts.tv_sec = 0; 200 ts.tv_nsec = 0; 201 while (1) { 202 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); 203 _thr_proc_sigpending = set; 204 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 205 for (i = 1; i <= _SIG_MAXSIG; i++) { 206 if (SIGISMEMBER(set, i) != 0) 207 _thr_sig_dispatch(curkse, i, 208 NULL /* no siginfo */); 209 } 210 ts.tv_sec = 30; 211 ts.tv_nsec = 0; 212 curkse->k_kcb->kcb_kmbx.km_flags = 213 KMF_NOUPCALL | KMF_NOCOMPLETED | KMF_WAITSIGEVENT; 214 kse_release(&ts); 215 curkse->k_kcb->kcb_kmbx.km_flags = 0; 216 set = curkse->k_kcb->kcb_kmbx.km_sigscaught; 217 } 218 return (0); 219} 220 221 222/* Utility function to create signal daemon thread */ 223int 224_thr_start_sig_daemon(void) 225{ 226 pthread_attr_t attr; 227 sigset_t sigset, oldset; 228 229 SIGFILLSET(sigset); 230 _pthread_sigmask(SIG_SETMASK, &sigset, &oldset); 231 _pthread_attr_init(&attr); 232 _pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); 233 attr->flags |= THR_SIGNAL_THREAD; 234 /* sigmask will be inherited */ 235 if (_pthread_create(&_thr_sig_daemon, &attr, sig_daemon, NULL)) 236 PANIC("can not create signal daemon thread!\n"); 237 _pthread_attr_destroy(&attr); 238 _pthread_sigmask(SIG_SETMASK, &oldset, NULL); 239 return (0); 240} 241 242/* 243 * This signal handler only delivers asynchronous signals. 244 * This must be called with upcalls disabled and without 245 * holding any locks. 246 */ 247void 248_thr_sig_dispatch(struct kse *curkse, int sig, siginfo_t *info) 249{ 250 struct kse_mailbox *kmbx; 251 struct pthread *thread; 252 253 DBG_MSG(">>> _thr_sig_dispatch(%d)\n", sig); 254 255 /* Check if the signal requires a dump of thread information: */ 256 if (_thr_dump_enabled() && (sig == SIGINFO)) { 257 /* Dump thread information to file: */ 258 _thread_dump_info(); 259 } 260 261 while ((thread = thr_sig_find(curkse, sig, info)) != NULL) { 262 /* 263 * Setup the target thread to receive the signal: 264 */ 265 DBG_MSG("Got signal %d, selecting thread %p\n", sig, thread); 266 KSE_SCHED_LOCK(curkse, thread->kseg); 267 if ((thread->state == PS_DEAD) || 268 (thread->state == PS_DEADLOCK) || 269 THR_IS_EXITING(thread) || THR_IS_SUSPENDED(thread)) { 270 KSE_SCHED_UNLOCK(curkse, thread->kseg); 271 _thr_ref_delete(NULL, thread); 272 } else if (SIGISMEMBER(thread->sigmask, sig)) { 273 KSE_SCHED_UNLOCK(curkse, thread->kseg); 274 _thr_ref_delete(NULL, thread); 275 } else { 276 kmbx = _thr_sig_add(thread, sig, info); 277 KSE_SCHED_UNLOCK(curkse, thread->kseg); 278 _thr_ref_delete(NULL, thread); 279 if (kmbx != NULL) 280 kse_wakeup(kmbx); 281 break; 282 } 283 } 284 DBG_MSG("<<< _thr_sig_dispatch\n"); 285} 286 287#endif /* ! SYSTEM_SCOPE_ONLY */ 288 289static __inline int 290sigprop(int sig) 291{ 292 293 if (sig > 0 && sig < NSIG) 294 return (sigproptbl[_SIG_IDX(sig)]); 295 return (0); 296} 297 298typedef void (*ohandler)(int sig, int code, 299 struct sigcontext *scp, char *addr, __sighandler_t *catcher); 300 301void 302_thr_sig_handler(int sig, siginfo_t *info, void *ucp_arg) 303{ 304 struct pthread_sigframe psf; 305 __siginfohandler_t *sigfunc; 306 struct pthread *curthread; 307 struct kse *curkse; 308 ucontext_t *ucp; 309 struct sigaction act; 310 int sa_flags, err_save; 311 312 err_save = errno; 313 ucp = (ucontext_t *)ucp_arg; 314 315 DBG_MSG(">>> _thr_sig_handler(%d)\n", sig); 316 317 curthread = _get_curthread(); 318 if (curthread == NULL) 319 PANIC("No current thread.\n"); 320 if (!(curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)) 321 PANIC("Thread is not system scope.\n"); 322 if (curthread->flags & THR_FLAGS_EXITING) { 323 errno = err_save; 324 return; 325 } 326 327 curkse = _get_curkse(); 328 /* 329 * If thread is in critical region or if thread is on 330 * the way of state transition, then latch signal into buffer. 331 */ 332 if (_kse_in_critical() || THR_IN_CRITICAL(curthread) || 333 curthread->state != PS_RUNNING) { 334 DBG_MSG(">>> _thr_sig_handler(%d) in critical\n", sig); 335 curthread->siginfo[sig-1] = *info; 336 curthread->check_pending = 1; 337 curkse->k_sigseqno++; 338 SIGADDSET(curthread->sigpend, sig); 339 /* 340 * If the kse is on the way to idle itself, but 341 * we have signal ready, we should prevent it 342 * to sleep, kernel will latch the wakeup request, 343 * so kse_release will return from kernel immediately. 344 */ 345 if (KSE_IS_IDLE(curkse)) 346 kse_wakeup(&curkse->k_kcb->kcb_kmbx); 347 errno = err_save; 348 return; 349 } 350 351 /* Check if the signal requires a dump of thread information: */ 352 if (_thr_dump_enabled() && (sig == SIGINFO)) { 353 /* Dump thread information to file: */ 354 _thread_dump_info(); 355 } 356 357 /* Check the threads previous state: */ 358 curthread->critical_count++; 359 if (curthread->sigbackout != NULL) 360 curthread->sigbackout((void *)curthread); 361 curthread->critical_count--; 362 thr_sigframe_save(curthread, &psf); 363 THR_ASSERT(!(curthread->sigbackout), "sigbackout was not cleared."); 364 365 _kse_critical_enter(); 366 /* Get a fresh copy of signal mask */ 367 __sys_sigprocmask(SIG_BLOCK, NULL, &curthread->sigmask); 368 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); 369 sigfunc = _thread_sigact[sig - 1].sa_sigaction; 370 sa_flags = _thread_sigact[sig - 1].sa_flags; 371 if (sa_flags & SA_RESETHAND) { 372 act.sa_handler = SIG_DFL; 373 act.sa_flags = SA_RESTART; 374 SIGEMPTYSET(act.sa_mask); 375 __sys_sigaction(sig, &act, NULL); 376 __sys_sigaction(sig, NULL, &_thread_sigact[sig - 1]); 377 } 378 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 379 _kse_critical_leave(&curthread->tcb->tcb_tmbx); 380 381 /* Now invoke real handler */ 382 if (((__sighandler_t *)sigfunc != SIG_DFL) && 383 ((__sighandler_t *)sigfunc != SIG_IGN) && 384 (sigfunc != (__siginfohandler_t *)_thr_sig_handler)) { 385 if ((sa_flags & SA_SIGINFO) != 0 || info == NULL) 386 (*(sigfunc))(sig, info, ucp); 387 else { 388 ((ohandler)(*sigfunc))( 389 sig, info->si_code, (struct sigcontext *)ucp, 390 info->si_addr, (__sighandler_t *)sigfunc); 391 } 392 } else { 393 if ((__sighandler_t *)sigfunc == SIG_DFL) { 394 if (sigprop(sig) & SA_KILL) { 395 if (_kse_isthreaded()) 396 kse_thr_interrupt(NULL, 397 KSE_INTR_SIGEXIT, sig); 398 else 399 kill(getpid(), sig); 400 } 401#ifdef NOTYET 402 else if (sigprop(sig) & SA_STOP) 403 kse_thr_interrupt(NULL, KSE_INTR_JOBSTOP, sig); 404#endif 405 } 406 } 407 _kse_critical_enter(); 408 curthread->sigmask = ucp->uc_sigmask; 409 SIG_CANTMASK(curthread->sigmask); 410 _kse_critical_leave(&curthread->tcb->tcb_tmbx); 411 412 thr_sigframe_restore(curthread, &psf); 413 414 DBG_MSG("<<< _thr_sig_handler(%d)\n", sig); 415 416 errno = err_save; 417} 418 419struct sighandle_info { 420 __siginfohandler_t *sigfunc; 421 int sa_flags; 422 int sig; 423 siginfo_t *info; 424 ucontext_t *ucp; 425}; 426 427static void handle_signal(struct pthread *curthread, 428 struct sighandle_info *shi); 429static void handle_signal_altstack(struct pthread *curthread, 430 struct sighandle_info *shi); 431 432/* Must be called with signal lock and schedule lock held in order */ 433static void 434thr_sig_invoke_handler(struct pthread *curthread, int sig, siginfo_t *info, 435 ucontext_t *ucp) 436{ 437 __siginfohandler_t *sigfunc; 438 sigset_t sigmask; 439 int sa_flags; 440 int onstack; 441 struct sigaction act; 442 struct kse *curkse; 443 struct sighandle_info shi; 444 445 /* 446 * Invoke the signal handler without going through the scheduler: 447 */ 448 DBG_MSG("Got signal %d, calling handler for current thread %p\n", 449 sig, curthread); 450 451 if (!_kse_in_critical()) 452 PANIC("thr_sig_invoke_handler without in critical\n"); 453 curkse = curthread->kse; 454 /* 455 * Check that a custom handler is installed and if 456 * the signal is not blocked: 457 */ 458 sigfunc = _thread_sigact[sig - 1].sa_sigaction; 459 sa_flags = _thread_sigact[sig - 1].sa_flags; 460 sigmask = curthread->sigmask; 461 SIGSETOR(curthread->sigmask, _thread_sigact[sig - 1].sa_mask); 462 if (!(sa_flags & (SA_NODEFER | SA_RESETHAND))) 463 SIGADDSET(curthread->sigmask, sig); 464 if ((sig != SIGILL) && (sa_flags & SA_RESETHAND)) { 465 act.sa_handler = SIG_DFL; 466 act.sa_flags = SA_RESTART; 467 SIGEMPTYSET(act.sa_mask); 468 __sys_sigaction(sig, &act, NULL); 469 __sys_sigaction(sig, NULL, &_thread_sigact[sig - 1]); 470 } 471 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 472 KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); 473 /* 474 * We are processing buffered signals, synchronize working 475 * signal mask into kernel. 476 */ 477 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 478 __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); 479 onstack = _thr_sigonstack(&sigfunc); 480 ucp->uc_stack = curthread->sigstk; 481 ucp->uc_stack.ss_flags = (curthread->sigstk.ss_flags & SS_DISABLE) 482 ? SS_DISABLE : ((onstack) ? SS_ONSTACK : 0); 483 if (curthread->oldsigmask) { 484 ucp->uc_sigmask = *(curthread->oldsigmask); 485 curthread->oldsigmask = NULL; 486 } else 487 ucp->uc_sigmask = sigmask; 488 shi.sigfunc = sigfunc; 489 shi.sig = sig; 490 shi.sa_flags = sa_flags; 491 shi.info = info; 492 shi.ucp = ucp; 493 if ((curthread->sigstk.ss_flags & SS_DISABLE) == 0) { 494 /* Deliver signal on alternative stack */ 495 if (sa_flags & SA_ONSTACK && !onstack) 496 handle_signal_altstack(curthread, &shi); 497 else 498 handle_signal(curthread, &shi); 499 } else { 500 handle_signal(curthread, &shi); 501 } 502 503 _kse_critical_enter(); 504 /* Don't trust after critical leave/enter */ 505 curkse = curthread->kse; 506 507 /* 508 * Restore the thread's signal mask. 509 */ 510 curthread->sigmask = ucp->uc_sigmask; 511 SIG_CANTMASK(curthread->sigmask); 512 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 513 __sys_sigprocmask(SIG_SETMASK, &ucp->uc_sigmask, NULL); 514 KSE_SCHED_LOCK(curkse, curkse->k_kseg); 515 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); 516 517 DBG_MSG("Got signal %d, handler returned %p\n", sig, curthread); 518} 519 520static void 521handle_signal(struct pthread *curthread, struct sighandle_info *shi) 522{ 523 _kse_critical_leave(&curthread->tcb->tcb_tmbx); 524 525 /* Check if the signal requires a dump of thread information: */ 526 if (_thr_dump_enabled() && (shi->sig == SIGINFO)) { 527 /* Dump thread information to file: */ 528 _thread_dump_info(); 529 } 530 531 if (((__sighandler_t *)shi->sigfunc != SIG_DFL) && 532 ((__sighandler_t *)shi->sigfunc != SIG_IGN)) { 533 if ((shi->sa_flags & SA_SIGINFO) != 0 || shi->info == NULL) 534 (*(shi->sigfunc))(shi->sig, shi->info, shi->ucp); 535 else { 536 ((ohandler)(*shi->sigfunc))( 537 shi->sig, shi->info->si_code, 538 (struct sigcontext *)shi->ucp, 539 shi->info->si_addr, 540 (__sighandler_t *)shi->sigfunc); 541 } 542 } else { 543 if ((__sighandler_t *)shi->sigfunc == SIG_DFL) { 544 if (sigprop(shi->sig) & SA_KILL) { 545 if (_kse_isthreaded()) 546 kse_thr_interrupt(NULL, 547 KSE_INTR_SIGEXIT, shi->sig); 548 else 549 kill(getpid(), shi->sig); 550 } 551#ifdef NOTYET 552 else if (sigprop(shi->sig) & SA_STOP) 553 kse_thr_interrupt(NULL, KSE_INTR_JOBSTOP, 554 shi->sig); 555#endif 556 } 557 } 558} 559 560static void 561handle_signal_wrapper(struct pthread *curthread, ucontext_t *ret_uc, 562 struct sighandle_info *shi) 563{ 564 shi->ucp->uc_stack.ss_flags = SS_ONSTACK; 565 handle_signal(curthread, shi); 566 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 567 setcontext(ret_uc); 568 else { 569 /* Work around for ia64, THR_SETCONTEXT does not work */ 570 _kse_critical_enter(); 571 curthread->tcb->tcb_tmbx.tm_context = *ret_uc; 572 _thread_switch(curthread->kse->k_kcb, curthread->tcb, 1); 573 /* THR_SETCONTEXT */ 574 } 575} 576 577/* 578 * Jump to stack set by sigaltstack before invoking signal handler 579 */ 580static void 581handle_signal_altstack(struct pthread *curthread, struct sighandle_info *shi) 582{ 583 volatile int once; 584 ucontext_t uc1, *uc2; 585 586 THR_ASSERT(_kse_in_critical(), "Not in critical"); 587 588 once = 0; 589 THR_GETCONTEXT(&uc1); 590 if (once == 0) { 591 once = 1; 592 /* XXX 593 * We are still in critical region, it is safe to operate thread 594 * context 595 */ 596 uc2 = &curthread->tcb->tcb_tmbx.tm_context; 597 uc2->uc_stack = curthread->sigstk; 598 makecontext(uc2, (void (*)(void))handle_signal_wrapper, 599 3, curthread, &uc1, shi); 600 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 601 setcontext(uc2); 602 else { 603 _thread_switch(curthread->kse->k_kcb, curthread->tcb, 1); 604 /* THR_SETCONTEXT(uc2); */ 605 } 606 } 607} 608 609int 610_thr_getprocsig(int sig, siginfo_t *siginfo) 611{ 612 kse_critical_t crit; 613 struct kse *curkse; 614 int ret; 615 616 DBG_MSG(">>> _thr_getprocsig\n"); 617 618 crit = _kse_critical_enter(); 619 curkse = _get_curkse(); 620 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); 621 ret = _thr_getprocsig_unlocked(sig, siginfo); 622 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 623 _kse_critical_leave(crit); 624 625 DBG_MSG("<<< _thr_getprocsig\n"); 626 return (ret); 627} 628 629int 630_thr_getprocsig_unlocked(int sig, siginfo_t *siginfo) 631{ 632 sigset_t sigset; 633 struct timespec ts; 634 635 /* try to retrieve signal from kernel */ 636 SIGEMPTYSET(sigset); 637 SIGADDSET(sigset, sig); 638 ts.tv_sec = 0; 639 ts.tv_nsec = 0; 640 SIGDELSET(_thr_proc_sigpending, sig); 641 if (__sys_sigtimedwait(&sigset, siginfo, &ts) > 0) 642 return (sig); 643 return (0); 644} 645 646#ifndef SYSTEM_SCOPE_ONLY 647/* 648 * Find a thread that can handle the signal. This must be called 649 * with upcalls disabled. 650 */ 651struct pthread * 652thr_sig_find(struct kse *curkse, int sig, siginfo_t *info __unused) 653{ 654 struct kse_mailbox *kmbx = NULL; 655 struct pthread *pthread; 656 struct pthread *suspended_thread, *signaled_thread; 657 __siginfohandler_t *sigfunc; 658 siginfo_t si; 659 660 DBG_MSG("Looking for thread to handle signal %d\n", sig); 661 662 /* 663 * Enter a loop to look for threads that have the signal 664 * unmasked. POSIX specifies that a thread in a sigwait 665 * will get the signal over any other threads. Second 666 * preference will be threads in a sigsuspend. Third 667 * preference will be the current thread. If none of the 668 * above, then the signal is delivered to the first thread 669 * that is found. Note that if a custom handler is not 670 * installed, the signal only affects threads in sigwait. 671 */ 672 suspended_thread = NULL; 673 signaled_thread = NULL; 674 675 KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock); 676 TAILQ_FOREACH(pthread, &_thread_list, tle) { 677 if (pthread == _thr_sig_daemon) 678 continue; 679 /* Signal delivering to bound thread is done by kernel */ 680 if (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 681 continue; 682 /* Take the scheduling lock. */ 683 KSE_SCHED_LOCK(curkse, pthread->kseg); 684 if ((pthread->state == PS_DEAD) || 685 (pthread->state == PS_DEADLOCK) || 686 THR_IS_EXITING(pthread) || 687 THR_IS_SUSPENDED(pthread)) { 688 ; /* Skip this thread. */ 689 } else if (pthread->state == PS_SIGWAIT && 690 SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) { 691 /* 692 * retrieve signal from kernel, if it is job control 693 * signal, and sigaction is SIG_DFL, then we will 694 * be stopped in kernel, we hold lock here, but that 695 * does not matter, because that's job control, and 696 * whole process should be stopped. 697 */ 698 if (_thr_getprocsig(sig, &si)) { 699 DBG_MSG("Waking thread %p in sigwait" 700 " with signal %d\n", pthread, sig); 701 /* where to put siginfo ? */ 702 *(pthread->data.sigwait->siginfo) = si; 703 kmbx = _thr_setrunnable_unlocked(pthread); 704 } 705 KSE_SCHED_UNLOCK(curkse, pthread->kseg); 706 /* 707 * POSIX doesn't doesn't specify which thread 708 * will get the signal if there are multiple 709 * waiters, so we give it to the first thread 710 * we find. 711 * 712 * Do not attempt to deliver this signal 713 * to other threads and do not add the signal 714 * to the process pending set. 715 */ 716 KSE_LOCK_RELEASE(curkse, &_thread_list_lock); 717 if (kmbx != NULL) 718 kse_wakeup(kmbx); 719 if (suspended_thread != NULL) 720 _thr_ref_delete(NULL, suspended_thread); 721 if (signaled_thread != NULL) 722 _thr_ref_delete(NULL, signaled_thread); 723 return (NULL); 724 } else if (!SIGISMEMBER(pthread->sigmask, sig)) { 725 /* 726 * If debugger is running, we don't quick exit, 727 * and give it a chance to check the signal. 728 */ 729 if (_libkse_debug == 0) { 730 sigfunc = _thread_sigact[sig - 1].sa_sigaction; 731 if ((__sighandler_t *)sigfunc == SIG_DFL) { 732 if (sigprop(sig) & SA_KILL) { 733 kse_thr_interrupt(NULL, 734 KSE_INTR_SIGEXIT, sig); 735 /* Never reach */ 736 } 737 } 738 } 739 if (pthread->state == PS_SIGSUSPEND) { 740 if (suspended_thread == NULL) { 741 suspended_thread = pthread; 742 suspended_thread->refcount++; 743 } 744 } else if (signaled_thread == NULL) { 745 signaled_thread = pthread; 746 signaled_thread->refcount++; 747 } 748 } 749 KSE_SCHED_UNLOCK(curkse, pthread->kseg); 750 } 751 KSE_LOCK_RELEASE(curkse, &_thread_list_lock); 752 753 if (suspended_thread != NULL) { 754 pthread = suspended_thread; 755 if (signaled_thread) 756 _thr_ref_delete(NULL, signaled_thread); 757 } else if (signaled_thread) { 758 pthread = signaled_thread; 759 } else { 760 pthread = NULL; 761 } 762 return (pthread); 763} 764#endif /* ! SYSTEM_SCOPE_ONLY */ 765 766static inline void 767build_siginfo(siginfo_t *info, int signo) 768{ 769 bzero(info, sizeof(*info)); 770 info->si_signo = signo; 771 info->si_pid = _thr_pid; 772} 773 774/* 775 * This is called by a thread when it has pending signals to deliver. 776 * It should only be called from the context of the thread. 777 */ 778void 779_thr_sig_rundown(struct pthread *curthread, ucontext_t *ucp) 780{ 781 struct pthread_sigframe psf; 782 siginfo_t siginfo; 783 int i, err_save; 784 kse_critical_t crit; 785 struct kse *curkse; 786 sigset_t sigmask; 787 788 err_save = errno; 789 790 DBG_MSG(">>> thr_sig_rundown (%p)\n", curthread); 791 792 /* Check the threads previous state: */ 793 curthread->critical_count++; 794 if (curthread->sigbackout != NULL) 795 curthread->sigbackout((void *)curthread); 796 curthread->critical_count--; 797 798 THR_ASSERT(!(curthread->sigbackout), "sigbackout was not cleared."); 799 THR_ASSERT((curthread->state == PS_RUNNING), "state is not PS_RUNNING"); 800 801 thr_sigframe_save(curthread, &psf); 802 /* 803 * Lower the priority before calling the handler in case 804 * it never returns (longjmps back): 805 */ 806 crit = _kse_critical_enter(); 807 curkse = curthread->kse; 808 KSE_SCHED_LOCK(curkse, curkse->k_kseg); 809 KSE_LOCK_ACQUIRE(curkse, &_thread_signal_lock); 810 curthread->active_priority &= ~THR_SIGNAL_PRIORITY; 811 SIGFILLSET(sigmask); 812 while (1) { 813 /* 814 * For bound thread, we mask all signals and get a fresh 815 * copy of signal mask from kernel 816 */ 817 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { 818 __sys_sigprocmask(SIG_SETMASK, &sigmask, 819 &curthread->sigmask); 820 } 821 for (i = 1; i <= _SIG_MAXSIG; i++) { 822 if (SIGISMEMBER(curthread->sigmask, i)) 823 continue; 824 if (SIGISMEMBER(curthread->sigpend, i)) { 825 SIGDELSET(curthread->sigpend, i); 826 siginfo = curthread->siginfo[i-1]; 827 break; 828 } 829 if (!(curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) 830 && SIGISMEMBER(_thr_proc_sigpending, i)) { 831 if (_thr_getprocsig_unlocked(i, &siginfo)) 832 break; 833 } 834 } 835 if (i <= _SIG_MAXSIG) 836 thr_sig_invoke_handler(curthread, i, &siginfo, ucp); 837 else { 838 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { 839 __sys_sigprocmask(SIG_SETMASK, 840 &curthread->sigmask, NULL); 841 } 842 break; 843 } 844 } 845 846 /* Don't trust after signal handling */ 847 curkse = curthread->kse; 848 KSE_LOCK_RELEASE(curkse, &_thread_signal_lock); 849 KSE_SCHED_UNLOCK(curkse, curkse->k_kseg); 850 _kse_critical_leave(&curthread->tcb->tcb_tmbx); 851 /* repost masked signal to kernel, it hardly happens in real world */ 852 if ((curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && 853 !SIGISEMPTY(curthread->sigpend)) { /* dirty read */ 854 __sys_sigprocmask(SIG_SETMASK, &sigmask, &curthread->sigmask); 855 for (i = 1; i <= _SIG_MAXSIG; ++i) { 856 if (SIGISMEMBER(curthread->sigpend, i)) { 857 SIGDELSET(curthread->sigpend, i); 858 if (!_kse_isthreaded()) 859 kill(getpid(), i); 860 else 861 kse_thr_interrupt( 862 &curthread->tcb->tcb_tmbx, 863 KSE_INTR_SENDSIG, 864 i); 865 } 866 } 867 __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); 868 } 869 DBG_MSG("<<< thr_sig_rundown (%p)\n", curthread); 870 871 thr_sigframe_restore(curthread, &psf); 872 errno = err_save; 873} 874 875/* 876 * This checks pending signals for the current thread. It should be 877 * called whenever a thread changes its signal mask. Note that this 878 * is called from a thread (using its stack). 879 * 880 * XXX - We might want to just check to see if there are pending 881 * signals for the thread here, but enter the UTS scheduler 882 * to actually install the signal handler(s). 883 */ 884void 885_thr_sig_check_pending(struct pthread *curthread) 886{ 887 ucontext_t uc; 888 volatile int once; 889 int errsave; 890 891 /* 892 * If the thread is in critical region, delay processing signals. 893 * If the thread state is not PS_RUNNING, it might be switching 894 * into UTS and but a THR_LOCK_RELEASE saw check_pending, and it 895 * goes here, in the case we delay processing signals, lets UTS 896 * process complicated things, normally UTS will call _thr_sig_add 897 * to resume the thread, so we needn't repeat doing it here. 898 */ 899 if (THR_IN_CRITICAL(curthread) || curthread->state != PS_RUNNING) 900 return; 901 902 errsave = errno; 903 once = 0; 904 THR_GETCONTEXT(&uc); 905 if (once == 0) { 906 once = 1; 907 curthread->check_pending = 0; 908 _thr_sig_rundown(curthread, &uc); 909 } 910 errno = errsave; 911} 912 913/* 914 * Perform thread specific actions in response to a signal. 915 * This function is only called if there is a handler installed 916 * for the signal, and if the target thread has the signal 917 * unmasked. 918 * 919 * This must be called with the thread's scheduling lock held. 920 */ 921struct kse_mailbox * 922_thr_sig_add(struct pthread *pthread, int sig, siginfo_t *info) 923{ 924 siginfo_t siginfo; 925 struct kse *curkse; 926 struct kse_mailbox *kmbx = NULL; 927 struct pthread *curthread = _get_curthread(); 928 int restart; 929 int suppress_handler = 0; 930 int fromproc = 0; 931 __sighandler_t *sigfunc; 932 933 DBG_MSG(">>> _thr_sig_add %p (%d)\n", pthread, sig); 934 935 curkse = _get_curkse(); 936 restart = _thread_sigact[sig - 1].sa_flags & SA_RESTART; 937 sigfunc = _thread_sigact[sig - 1].sa_handler; 938 fromproc = (curthread == _thr_sig_daemon); 939 940 if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK || 941 pthread->state == PS_STATE_MAX) 942 return (NULL); /* return false */ 943 944 if ((pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && 945 (curthread != pthread)) { 946 PANIC("Please use _thr_send_sig for bound thread"); 947 return (NULL); 948 } 949 950 if (pthread->state != PS_SIGWAIT && 951 SIGISMEMBER(pthread->sigmask, sig)) { 952 /* signal is masked, just add signal to thread. */ 953 if (!fromproc) { 954 SIGADDSET(pthread->sigpend, sig); 955 if (info == NULL) 956 build_siginfo(&pthread->siginfo[sig-1], sig); 957 else if (info != &pthread->siginfo[sig-1]) 958 memcpy(&pthread->siginfo[sig-1], info, 959 sizeof(*info)); 960 } else { 961 if (!_thr_getprocsig(sig, &pthread->siginfo[sig-1])) 962 return (NULL); 963 SIGADDSET(pthread->sigpend, sig); 964 } 965 } 966 else { 967 /* if process signal not exists, just return */ 968 if (fromproc) { 969 if (!_thr_getprocsig(sig, &siginfo)) 970 return (NULL); 971 info = &siginfo; 972 } 973 974 if (pthread->state != PS_SIGWAIT && sigfunc == SIG_DFL && 975 (sigprop(sig) & SA_KILL)) { 976 kse_thr_interrupt(NULL, KSE_INTR_SIGEXIT, sig); 977 /* Never reach */ 978 } 979 980 /* 981 * Process according to thread state: 982 */ 983 switch (pthread->state) { 984 case PS_DEAD: 985 case PS_DEADLOCK: 986 case PS_STATE_MAX: 987 return (NULL); /* XXX return false */ 988 case PS_LOCKWAIT: 989 case PS_SUSPENDED: 990 /* 991 * You can't call a signal handler for threads in these 992 * states. 993 */ 994 suppress_handler = 1; 995 break; 996 case PS_RUNNING: 997 if ((pthread->flags & THR_FLAGS_IN_RUNQ)) { 998 THR_RUNQ_REMOVE(pthread); 999 pthread->active_priority |= THR_SIGNAL_PRIORITY; 1000 THR_RUNQ_INSERT_TAIL(pthread); 1001 } else { 1002 /* Possible not in RUNQ and has curframe ? */ 1003 pthread->active_priority |= THR_SIGNAL_PRIORITY; 1004 } 1005 break; 1006 /* 1007 * States which cannot be interrupted but still require the 1008 * signal handler to run: 1009 */ 1010 case PS_COND_WAIT: 1011 case PS_MUTEX_WAIT: 1012 break; 1013 1014 case PS_SLEEP_WAIT: 1015 /* 1016 * Unmasked signals always cause sleep to terminate 1017 * early regardless of SA_RESTART: 1018 */ 1019 pthread->interrupted = 1; 1020 break; 1021 1022 case PS_JOIN: 1023 break; 1024 1025 case PS_SIGSUSPEND: 1026 pthread->interrupted = 1; 1027 break; 1028 1029 case PS_SIGWAIT: 1030 if (info == NULL) 1031 build_siginfo(&pthread->siginfo[sig-1], sig); 1032 else if (info != &pthread->siginfo[sig-1]) 1033 memcpy(&pthread->siginfo[sig-1], info, 1034 sizeof(*info)); 1035 /* 1036 * The signal handler is not called for threads in 1037 * SIGWAIT. 1038 */ 1039 suppress_handler = 1; 1040 /* Wake up the thread if the signal is not blocked. */ 1041 if (SIGISMEMBER(*(pthread->data.sigwait->waitset), sig)) { 1042 /* Return the signal number: */ 1043 *(pthread->data.sigwait->siginfo) = pthread->siginfo[sig-1]; 1044 /* Make the thread runnable: */ 1045 kmbx = _thr_setrunnable_unlocked(pthread); 1046 } else { 1047 /* Increment the pending signal count. */ 1048 SIGADDSET(pthread->sigpend, sig); 1049 if (!SIGISMEMBER(pthread->sigmask, sig)) { 1050 if (sigfunc == SIG_DFL && 1051 sigprop(sig) & SA_KILL) { 1052 kse_thr_interrupt(NULL, 1053 KSE_INTR_SIGEXIT, 1054 sig); 1055 /* Never reach */ 1056 } 1057 pthread->check_pending = 1; 1058 pthread->interrupted = 1; 1059 kmbx = _thr_setrunnable_unlocked(pthread); 1060 } 1061 } 1062 return (kmbx); 1063 } 1064 1065 SIGADDSET(pthread->sigpend, sig); 1066 if (info == NULL) 1067 build_siginfo(&pthread->siginfo[sig-1], sig); 1068 else if (info != &pthread->siginfo[sig-1]) 1069 memcpy(&pthread->siginfo[sig-1], info, sizeof(*info)); 1070 pthread->check_pending = 1; 1071 if (!(pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) && 1072 (pthread->blocked != 0) && !THR_IN_CRITICAL(pthread)) 1073 kse_thr_interrupt(&pthread->tcb->tcb_tmbx, 1074 restart ? KSE_INTR_RESTART : KSE_INTR_INTERRUPT, 0); 1075 if (suppress_handler == 0) { 1076 /* 1077 * Setup a signal frame and save the current threads 1078 * state: 1079 */ 1080 if (pthread->state != PS_RUNNING) { 1081 if (pthread->flags & THR_FLAGS_IN_RUNQ) 1082 THR_RUNQ_REMOVE(pthread); 1083 pthread->active_priority |= THR_SIGNAL_PRIORITY; 1084 kmbx = _thr_setrunnable_unlocked(pthread); 1085 } 1086 } 1087 } 1088 return (kmbx); 1089} 1090 1091/* 1092 * Send a signal to a specific thread (ala pthread_kill): 1093 */ 1094void 1095_thr_sig_send(struct pthread *pthread, int sig) 1096{ 1097 struct pthread *curthread = _get_curthread(); 1098 struct kse_mailbox *kmbx; 1099 1100 if (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) { 1101 kse_thr_interrupt(&pthread->tcb->tcb_tmbx, KSE_INTR_SENDSIG, sig); 1102 return; 1103 } 1104 1105 /* Lock the scheduling queue of the target thread. */ 1106 THR_SCHED_LOCK(curthread, pthread); 1107 if (_thread_sigact[sig - 1].sa_handler != SIG_IGN) { 1108 kmbx = _thr_sig_add(pthread, sig, NULL); 1109 /* Add a preemption point. */ 1110 if (kmbx == NULL && (curthread->kseg == pthread->kseg) && 1111 (pthread->active_priority > curthread->active_priority)) 1112 curthread->critical_yield = 1; 1113 THR_SCHED_UNLOCK(curthread, pthread); 1114 if (kmbx != NULL) 1115 kse_wakeup(kmbx); 1116 /* XXX 1117 * If thread sent signal to itself, check signals now. 1118 * It is not really needed, _kse_critical_leave should 1119 * have already checked signals. 1120 */ 1121 if (pthread == curthread && curthread->check_pending) 1122 _thr_sig_check_pending(curthread); 1123 1124 } else { 1125 THR_SCHED_UNLOCK(curthread, pthread); 1126 } 1127} 1128 1129static inline void 1130thr_sigframe_restore(struct pthread *curthread, struct pthread_sigframe *psf) 1131{ 1132 kse_critical_t crit; 1133 struct kse *curkse; 1134 1135 THR_THREAD_LOCK(curthread, curthread); 1136 curthread->cancelflags = psf->psf_cancelflags; 1137 crit = _kse_critical_enter(); 1138 curkse = curthread->kse; 1139 KSE_SCHED_LOCK(curkse, curthread->kseg); 1140 curthread->flags = psf->psf_flags; 1141 curthread->interrupted = psf->psf_interrupted; 1142 curthread->timeout = psf->psf_timeout; 1143 curthread->data = psf->psf_wait_data; 1144 curthread->wakeup_time = psf->psf_wakeup_time; 1145 curthread->continuation = psf->psf_continuation; 1146 KSE_SCHED_UNLOCK(curkse, curthread->kseg); 1147 _kse_critical_leave(crit); 1148 THR_THREAD_UNLOCK(curthread, curthread); 1149} 1150 1151static inline void 1152thr_sigframe_save(struct pthread *curthread, struct pthread_sigframe *psf) 1153{ 1154 kse_critical_t crit; 1155 struct kse *curkse; 1156 1157 THR_THREAD_LOCK(curthread, curthread); 1158 psf->psf_cancelflags = curthread->cancelflags; 1159 crit = _kse_critical_enter(); 1160 curkse = curthread->kse; 1161 KSE_SCHED_LOCK(curkse, curthread->kseg); 1162 /* This has to initialize all members of the sigframe. */ 1163 psf->psf_flags = (curthread->flags & (THR_FLAGS_PRIVATE | THR_FLAGS_EXITING)); 1164 psf->psf_interrupted = curthread->interrupted; 1165 psf->psf_timeout = curthread->timeout; 1166 psf->psf_wait_data = curthread->data; 1167 psf->psf_wakeup_time = curthread->wakeup_time; 1168 psf->psf_continuation = curthread->continuation; 1169 KSE_SCHED_UNLOCK(curkse, curthread->kseg); 1170 _kse_critical_leave(crit); 1171 THR_THREAD_UNLOCK(curthread, curthread); 1172} 1173 1174void 1175_thr_signal_init(void) 1176{ 1177 struct sigaction act; 1178 __siginfohandler_t *sigfunc; 1179 int i; 1180 sigset_t sigset; 1181 1182 SIGFILLSET(sigset); 1183 __sys_sigprocmask(SIG_SETMASK, &sigset, &_thr_initial->sigmask); 1184 /* Enter a loop to get the existing signal status: */ 1185 for (i = 1; i <= _SIG_MAXSIG; i++) { 1186 /* Get the signal handler details: */ 1187 if (__sys_sigaction(i, NULL, &_thread_sigact[i - 1]) != 0) { 1188 /* 1189 * Abort this process if signal 1190 * initialisation fails: 1191 */ 1192 PANIC("Cannot read signal handler info"); 1193 } 1194 /* Intall wrapper if handler was set */ 1195 sigfunc = _thread_sigact[i - 1].sa_sigaction; 1196 if (((__sighandler_t *)sigfunc) != SIG_DFL && 1197 ((__sighandler_t *)sigfunc) != SIG_IGN) { 1198 act = _thread_sigact[i - 1]; 1199 act.sa_flags |= SA_SIGINFO; 1200 act.sa_sigaction = 1201 (__siginfohandler_t *)_thr_sig_handler; 1202 __sys_sigaction(i, &act, NULL); 1203 } 1204 } 1205 if (_thr_dump_enabled()) { 1206 /* 1207 * Install the signal handler for SIGINFO. It isn't 1208 * really needed, but it is nice to have for debugging 1209 * purposes. 1210 */ 1211 _thread_sigact[SIGINFO - 1].sa_flags = SA_SIGINFO | SA_RESTART; 1212 SIGEMPTYSET(act.sa_mask); 1213 act.sa_flags = SA_SIGINFO | SA_RESTART; 1214 act.sa_sigaction = (__siginfohandler_t *)&_thr_sig_handler; 1215 if (__sys_sigaction(SIGINFO, &act, NULL) != 0) { 1216 __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, 1217 NULL); 1218 /* 1219 * Abort this process if signal initialisation fails: 1220 */ 1221 PANIC("Cannot initialize signal handler"); 1222 } 1223 } 1224 __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, NULL); 1225 __sys_sigaltstack(NULL, &_thr_initial->sigstk); 1226} 1227 1228void 1229_thr_signal_deinit(void) 1230{ 1231 int i; 1232 struct pthread *curthread = _get_curthread(); 1233 1234 /* Clear process pending signals. */ 1235 sigemptyset(&_thr_proc_sigpending); 1236 1237 /* Enter a loop to get the existing signal status: */ 1238 for (i = 1; i <= _SIG_MAXSIG; i++) { 1239 /* Check for signals which cannot be trapped: */ 1240 if (i == SIGKILL || i == SIGSTOP) { 1241 } 1242 1243 /* Set the signal handler details: */ 1244 else if (__sys_sigaction(i, &_thread_sigact[i - 1], 1245 NULL) != 0) { 1246 /* 1247 * Abort this process if signal 1248 * initialisation fails: 1249 */ 1250 PANIC("Cannot set signal handler info"); 1251 } 1252 } 1253 __sys_sigaltstack(&curthread->sigstk, NULL); 1254} 1255 1256