5fbb917cf8b6cd72ac127d9422db617f495c2080
[ghc.git] / rts / posix / Signals.c
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 1998-2005
4 *
5 * Signal processing / handling.
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #include "PosixSource.h"
10 #include "Rts.h"
11
12 #include "Schedule.h"
13 #include "RtsSignals.h"
14 #include "Signals.h"
15 #include "RtsUtils.h"
16 #include "Prelude.h"
17 #include "Stable.h"
18
19 #ifdef alpha_HOST_ARCH
20 # if defined(linux_HOST_OS)
21 # include <asm/fpu.h>
22 # else
23 # include <machine/fpu.h>
24 # endif
25 #endif
26
27 #ifdef HAVE_UNISTD_H
28 # include <unistd.h>
29 #endif
30
31 #ifdef HAVE_SIGNAL_H
32 # include <signal.h>
33 #endif
34
35 #ifdef HAVE_ERRNO_H
36 # include <errno.h>
37 #endif
38
39 #ifdef HAVE_EVENTFD_H
40 # include <sys/eventfd.h>
41 #endif
42
43 #ifdef HAVE_TERMIOS_H
44 #include <termios.h>
45 #endif
46
47 #include <stdlib.h>
48 #include <string.h>
49
50 /* This curious flag is provided for the benefit of the Haskell binding
51 * to POSIX.1 to control whether or not to include SA_NOCLDSTOP when
52 * installing a SIGCHLD handler.
53 */
54 HsInt nocldstop = 0;
55
56 /* -----------------------------------------------------------------------------
57 * The table of signal handlers
58 * -------------------------------------------------------------------------- */
59
60 #if defined(RTS_USER_SIGNALS)
61
62 /* SUP: The type of handlers is a little bit, well, doubtful... */
63 StgInt *signal_handlers = NULL; /* Dynamically grown array of signal handlers */
64 static StgInt nHandlers = 0; /* Size of handlers array */
65
66 static nat n_haskell_handlers = 0;
67
68 static sigset_t userSignals;
69 static sigset_t savedSignals;
70
71 #ifdef THREADED_RTS
72 static Mutex sig_mutex; // protects signal_handlers, nHandlers
73 #endif
74
75 /* -----------------------------------------------------------------------------
76 * Initialisation / deinitialisation
77 * -------------------------------------------------------------------------- */
78
79 void
80 initUserSignals(void)
81 {
82 sigemptyset(&userSignals);
83 #ifdef THREADED_RTS
84 initMutex(&sig_mutex);
85 #endif
86 }
87
88 void
89 freeSignalHandlers(void) {
90 if (signal_handlers != NULL) {
91 stgFree(signal_handlers);
92 signal_handlers = NULL;
93 nHandlers = 0;
94 n_haskell_handlers = 0;
95 }
96 #ifdef THREADED_RTS
97 closeMutex(&sig_mutex);
98 #endif
99 }
100
101 /* -----------------------------------------------------------------------------
102 * Allocate/resize the table of signal handlers.
103 * -------------------------------------------------------------------------- */
104
105 static void
106 more_handlers(int sig)
107 {
108 StgInt i;
109
110 if (sig < nHandlers)
111 return;
112
113 if (signal_handlers == NULL)
114 signal_handlers = (StgInt *)stgMallocBytes((sig + 1) * sizeof(StgInt),
115 "more_handlers");
116 else
117 signal_handlers = (StgInt *)stgReallocBytes(signal_handlers,
118 (sig + 1) * sizeof(StgInt),
119 "more_handlers");
120
121 for(i = nHandlers; i <= sig; i++)
122 // Fill in the new slots with default actions
123 signal_handlers[i] = STG_SIG_DFL;
124
125 nHandlers = sig + 1;
126 }
127
128 // Here's the pipe into which we will send our signals
129 static int io_manager_wakeup_fd = -1;
130 static int timer_manager_control_wr_fd = -1;
131
132 #define IO_MANAGER_WAKEUP 0xff
133 #define IO_MANAGER_DIE 0xfe
134 #define IO_MANAGER_SYNC 0xfd
135
136 void setTimerManagerControlFd(int fd) {
137 timer_manager_control_wr_fd = fd;
138 }
139
140 void
141 setIOManagerWakeupFd (int fd)
142 {
143 // only called when THREADED_RTS, but unconditionally
144 // compiled here because GHC.Event.Control depends on it.
145 io_manager_wakeup_fd = fd;
146 }
147
148 /* -----------------------------------------------------------------------------
149 * Wake up at least one IO or timer manager HS thread.
150 * -------------------------------------------------------------------------- */
151 void
152 ioManagerWakeup (void)
153 {
154 int r;
155 // Wake up the IO Manager thread by sending a byte down its pipe
156 if (io_manager_wakeup_fd >= 0) {
157 #if defined(HAVE_EVENTFD)
158 StgWord64 n = (StgWord64)IO_MANAGER_WAKEUP;
159 r = write(io_manager_wakeup_fd, (char *) &n, 8);
160 #else
161 StgWord8 byte = (StgWord8)IO_MANAGER_WAKEUP;
162 r = write(io_manager_wakeup_fd, &byte, 1);
163 #endif
164 if (r == -1) { sysErrorBelch("ioManagerWakeup: write"); }
165 }
166 }
167
168 #if defined(THREADED_RTS)
169 void
170 ioManagerDie (void)
171 {
172 StgWord8 byte = (StgWord8)IO_MANAGER_DIE;
173 nat i;
174 int fd;
175 int r;
176
177 if (0 <= timer_manager_control_wr_fd) {
178 r = write(timer_manager_control_wr_fd, &byte, 1);
179 if (r == -1) { sysErrorBelch("ioManagerDie: write"); }
180 timer_manager_control_wr_fd = -1;
181 }
182
183 for (i=0; i < n_capabilities; i++) {
184 fd = capabilities[i]->io_manager_control_wr_fd;
185 if (0 <= fd) {
186 r = write(fd, &byte, 1);
187 if (r == -1) { sysErrorBelch("ioManagerDie: write"); }
188 capabilities[i]->io_manager_control_wr_fd = -1;
189 }
190 }
191 }
192
193 void
194 ioManagerStartCap (Capability **cap)
195 {
196 rts_evalIO(cap,&base_GHCziConcziIO_ensureIOManagerIsRunning_closure,NULL);
197 }
198
199 void
200 ioManagerStart (void)
201 {
202 // Make sure the IO manager thread is running
203 Capability *cap;
204 if (timer_manager_control_wr_fd < 0 || io_manager_wakeup_fd < 0) {
205 cap = rts_lock();
206 ioManagerStartCap(&cap);
207 rts_unlock(cap);
208 }
209 }
210 #endif
211
212 #if !defined(THREADED_RTS)
213
214 #define N_PENDING_HANDLERS 16
215
216 siginfo_t pending_handler_buf[N_PENDING_HANDLERS];
217 siginfo_t *next_pending_handler = pending_handler_buf;
218
219 #endif /* THREADED_RTS */
220
221 /* -----------------------------------------------------------------------------
222 * Low-level signal handler
223 *
224 * Places the requested handler on a stack of pending handlers to be
225 * started up at the next context switch.
226 * -------------------------------------------------------------------------- */
227
228 static void
229 generic_handler(int sig USED_IF_THREADS,
230 siginfo_t *info,
231 void *p STG_UNUSED)
232 {
233 #if defined(THREADED_RTS)
234
235 StgWord8 buf[sizeof(siginfo_t) + 1];
236 int r;
237
238 buf[0] = sig;
239 if (info == NULL) {
240 // info may be NULL on Solaris (see #3790)
241 memset(buf+1, 0, sizeof(siginfo_t));
242 } else {
243 memcpy(buf+1, info, sizeof(siginfo_t));
244 }
245
246 if (0 <= timer_manager_control_wr_fd)
247 {
248 r = write(timer_manager_control_wr_fd, buf, sizeof(siginfo_t)+1);
249 if (r == -1 && errno == EAGAIN) {
250 errorBelch("lost signal due to full pipe: %d\n", sig);
251 }
252 }
253
254 // If the IO manager hasn't told us what the FD of the write end
255 // of its pipe is, there's not much we can do here, so just ignore
256 // the signal..
257
258 #else /* not THREADED_RTS */
259
260 /* Can't call allocate from here. Probably can't call malloc
261 either. However, we have to schedule a new thread somehow.
262
263 It's probably ok to request a context switch and allow the
264 scheduler to start the handler thread, but how do we
265 communicate this to the scheduler?
266
267 We need some kind of locking, but with low overhead (i.e. no
268 blocking signals every time around the scheduler).
269
270 Signal Handlers are atomic (i.e. they can't be interrupted), and
271 we can make use of this. We just need to make sure the
272 critical section of the scheduler can't be interrupted - the
273 only way to do this is to block signals. However, we can lower
274 the overhead by only blocking signals when there are any
275 handlers to run, i.e. the set of pending handlers is
276 non-empty.
277 */
278
279 /* We use a stack to store the pending signals. We can't
280 dynamically grow this since we can't allocate any memory from
281 within a signal handler.
282
283 Hence unfortunately we have to bomb out if the buffer
284 overflows. It might be acceptable to carry on in certain
285 circumstances, depending on the signal.
286 */
287
288 memcpy(next_pending_handler, info, sizeof(siginfo_t));
289
290 next_pending_handler++;
291
292 // stack full?
293 if (next_pending_handler == &pending_handler_buf[N_PENDING_HANDLERS]) {
294 errorBelch("too many pending signals");
295 stg_exit(EXIT_FAILURE);
296 }
297
298 interruptCapability(&MainCapability);
299
300 #endif /* THREADED_RTS */
301 }
302
303 /* -----------------------------------------------------------------------------
304 * Blocking/Unblocking of the user signals
305 * -------------------------------------------------------------------------- */
306
307 void
308 blockUserSignals(void)
309 {
310 sigprocmask(SIG_BLOCK, &userSignals, &savedSignals);
311 }
312
313 void
314 unblockUserSignals(void)
315 {
316 sigprocmask(SIG_SETMASK, &savedSignals, NULL);
317 }
318
319 rtsBool
320 anyUserHandlers(void)
321 {
322 return n_haskell_handlers != 0;
323 }
324
325 #if !defined(THREADED_RTS)
326 void
327 awaitUserSignals(void)
328 {
329 while (!signals_pending() && sched_state == SCHED_RUNNING) {
330 pause();
331 }
332 }
333 #endif
334
335 /* -----------------------------------------------------------------------------
336 * Install a Haskell signal handler.
337 *
338 * We should really do this in Haskell in GHC.Conc, and share the
339 * signal_handlers array with the one there.
340 *
341 * -------------------------------------------------------------------------- */
342
343 int
344 stg_sig_install(int sig, int spi, void *mask)
345 {
346 sigset_t signals, osignals;
347 struct sigaction action;
348 StgInt previous_spi;
349
350 ACQUIRE_LOCK(&sig_mutex);
351
352 // Block the signal until we figure out what to do
353 // Count on this to fail if the signal number is invalid
354 if (sig < 0 ||
355 sigemptyset(&signals) ||
356 sigaddset(&signals, sig) ||
357 sigprocmask(SIG_BLOCK, &signals, &osignals)) {
358 RELEASE_LOCK(&sig_mutex);
359 return STG_SIG_ERR;
360 }
361
362 more_handlers(sig);
363
364 previous_spi = signal_handlers[sig];
365
366 action.sa_flags = 0;
367
368 switch(spi) {
369 case STG_SIG_IGN:
370 action.sa_handler = SIG_IGN;
371 break;
372
373 case STG_SIG_DFL:
374 action.sa_handler = SIG_DFL;
375 break;
376
377 case STG_SIG_RST:
378 action.sa_flags |= SA_RESETHAND;
379 /* fall through */
380 case STG_SIG_HAN:
381 action.sa_sigaction = generic_handler;
382 action.sa_flags |= SA_SIGINFO;
383 break;
384
385 default:
386 barf("stg_sig_install: bad spi");
387 }
388
389 if (mask != NULL)
390 action.sa_mask = *(sigset_t *)mask;
391 else
392 sigemptyset(&action.sa_mask);
393
394 action.sa_flags |= sig == SIGCHLD && nocldstop ? SA_NOCLDSTOP : 0;
395
396 if (sigaction(sig, &action, NULL))
397 {
398 errorBelch("sigaction");
399 RELEASE_LOCK(&sig_mutex);
400 return STG_SIG_ERR;
401 }
402
403 signal_handlers[sig] = spi;
404
405 switch(spi) {
406 case STG_SIG_RST:
407 case STG_SIG_HAN:
408 sigaddset(&userSignals, sig);
409 if (previous_spi != STG_SIG_HAN && previous_spi != STG_SIG_RST) {
410 n_haskell_handlers++;
411 }
412 break;
413
414 default:
415 sigdelset(&userSignals, sig);
416 if (previous_spi == STG_SIG_HAN || previous_spi == STG_SIG_RST) {
417 n_haskell_handlers--;
418 }
419 break;
420 }
421
422 if (sigprocmask(SIG_SETMASK, &osignals, NULL))
423 {
424 errorBelch("sigprocmask");
425 RELEASE_LOCK(&sig_mutex);
426 return STG_SIG_ERR;
427 }
428
429 RELEASE_LOCK(&sig_mutex);
430 return previous_spi;
431 }
432
433 /* -----------------------------------------------------------------------------
434 * Creating new threads for signal handlers.
435 * -------------------------------------------------------------------------- */
436
437 #if !defined(THREADED_RTS)
438 void
439 startSignalHandlers(Capability *cap)
440 {
441 siginfo_t *info;
442 int sig;
443
444 blockUserSignals();
445
446 while (next_pending_handler != pending_handler_buf) {
447
448 next_pending_handler--;
449
450 sig = next_pending_handler->si_signo;
451 if (signal_handlers[sig] == STG_SIG_DFL) {
452 continue; // handler has been changed.
453 }
454
455 info = stgMallocBytes(sizeof(siginfo_t), "startSignalHandlers");
456 // freed by runHandler
457 memcpy(info, next_pending_handler, sizeof(siginfo_t));
458
459 scheduleThread(cap,
460 createIOThread(cap,
461 RtsFlags.GcFlags.initialStkSize,
462 rts_apply(cap,
463 rts_apply(cap,
464 &base_GHCziConcziSignal_runHandlersPtr_closure,
465 rts_mkPtr(cap, info)),
466 rts_mkInt(cap, info->si_signo))));
467 }
468
469 unblockUserSignals();
470 }
471 #endif
472
473 /* ----------------------------------------------------------------------------
474 * Mark signal handlers during GC.
475 * -------------------------------------------------------------------------- */
476
477 void
478 markSignalHandlers (evac_fn evac STG_UNUSED, void *user STG_UNUSED)
479 {
480 // nothing to do
481 }
482
483 #else /* !RTS_USER_SIGNALS */
484 StgInt
485 stg_sig_install(StgInt sig STG_UNUSED,
486 StgInt spi STG_UNUSED,
487 void* mask STG_UNUSED)
488 {
489 //barf("User signals not supported");
490 return STG_SIG_DFL;
491 }
492
493 #endif
494
495 #if defined(RTS_USER_SIGNALS)
496 /* -----------------------------------------------------------------------------
497 * SIGINT handler.
498 *
499 * We like to shutdown nicely after receiving a SIGINT, write out the
500 * stats, write profiling info, close open files and flush buffers etc.
501 * -------------------------------------------------------------------------- */
502 static void
503 shutdown_handler(int sig STG_UNUSED)
504 {
505 // If we're already trying to interrupt the RTS, terminate with
506 // extreme prejudice. So the first ^C tries to exit the program
507 // cleanly, and the second one just kills it.
508 if (sched_state >= SCHED_INTERRUPTING) {
509 stg_exit(EXIT_INTERRUPTED);
510 } else {
511 interruptStgRts();
512 }
513 }
514
515 /* -----------------------------------------------------------------------------
516 * An empty signal handler, currently used for SIGPIPE
517 * -------------------------------------------------------------------------- */
518 static void
519 empty_handler (int sig STG_UNUSED)
520 {
521 // nothing
522 }
523
524 /* -----------------------------------------------------------------------------
525 SIGTSTP handling
526
527 When a process is suspeended with ^Z and resumed again, the shell
528 makes no attempt to save and restore the terminal settings. So on
529 resume, any terminal setting modificaions we made (e.g. turning off
530 ICANON due to hSetBuffering NoBuffering) may well be lost. Hence,
531 we arrange to save and restore the terminal settings ourselves.
532
533 The trick we use is:
534 - catch SIGTSTP
535 - in the handler, kill(getpid(),SIGSTOP)
536 - when this returns, restore the TTY settings
537 This means we don't have to catch SIGCONT too.
538
539 Note we don't re-throw SIGTSTP, we throw SIGSTOP instead. This is
540 for a few reasons:
541
542 - re-throwing SIGTSTP would require temporarily restoring the
543 default sigaction.
544
545 - it doesn't work on certain buggy pthread implementations
546 (e.g. OpenBSD).
547
548 - throwing SIGTSTP seems slightly dodgy anyway.
549
550 -------------------------------------------------------------------------- */
551
552 static void sigtstp_handler(int sig);
553 static void set_sigtstp_action (rtsBool handle);
554
555 static void
556 sigtstp_handler (int sig STG_UNUSED)
557 {
558 int fd;
559 struct termios ts[3];
560
561 // save the current TTY state for TTYs we modified
562 for (fd = 0; fd <= 2; fd++) {
563 if (__hscore_get_saved_termios(fd) != NULL) {
564 tcgetattr(fd,&ts[fd]);
565 }
566 }
567
568 // really stop the process now
569 kill(getpid(), SIGSTOP);
570
571 // on return, restore the TTY state
572 for (fd = 0; fd <= 2; fd++) {
573 if (__hscore_get_saved_termios(fd) != NULL) {
574 tcsetattr(0,TCSANOW,&ts[fd]);
575 }
576 }
577 }
578
579 static void
580 set_sigtstp_action (rtsBool handle)
581 {
582 struct sigaction sa;
583 if (handle) {
584 sa.sa_handler = sigtstp_handler;
585 } else {
586 sa.sa_handler = SIG_DFL;
587 }
588 sa.sa_flags = 0;
589 sigemptyset(&sa.sa_mask);
590 if (sigaction(SIGTSTP, &sa, NULL) != 0) {
591 sysErrorBelch("warning: failed to install SIGTSTP handler");
592 }
593 }
594
595 /* -----------------------------------------------------------------------------
596 * Install default signal handlers.
597 *
598 * The RTS installs a default signal handler for catching
599 * SIGINT, so that we can perform an orderly shutdown.
600 *
601 * Haskell code may install their own SIGINT handler, which is
602 * fine, provided they're so kind as to put back the old one
603 * when they de-install.
604 *
605 * In addition to handling SIGINT, the RTS also handles SIGFPE
606 * by ignoring it. Apparently IEEE requires floating-point
607 * exceptions to be ignored by default, but alpha-dec-osf3
608 * doesn't seem to do so.
609 * -------------------------------------------------------------------------- */
610 void
611 initDefaultHandlers(void)
612 {
613 struct sigaction action,oact;
614
615 // install the SIGINT handler
616 action.sa_handler = shutdown_handler;
617 sigemptyset(&action.sa_mask);
618 action.sa_flags = 0;
619 if (sigaction(SIGINT, &action, &oact) != 0) {
620 sysErrorBelch("warning: failed to install SIGINT handler");
621 }
622
623 #if defined(HAVE_SIGINTERRUPT)
624 siginterrupt(SIGINT, 1); // isn't this the default? --SDM
625 #endif
626
627 // install the SIGFPE handler
628
629 // In addition to handling SIGINT, also handle SIGFPE by ignoring it.
630 // Apparently IEEE requires floating-point exceptions to be ignored by
631 // default, but alpha-dec-osf3 doesn't seem to do so.
632
633 // Commented out by SDM 2/7/2002: this causes an infinite loop on
634 // some architectures when an integer division by zero occurs: we
635 // don't recover from the floating point exception, and the
636 // program just generates another one immediately.
637 #if 0
638 action.sa_handler = SIG_IGN;
639 sigemptyset(&action.sa_mask);
640 action.sa_flags = 0;
641 if (sigaction(SIGFPE, &action, &oact) != 0) {
642 sysErrorBelch("warning: failed to install SIGFPE handler");
643 }
644 #endif
645
646 #ifdef alpha_HOST_ARCH
647 ieee_set_fp_control(0);
648 #endif
649
650 // ignore SIGPIPE; see #1619
651 // actually, we use an empty signal handler rather than SIG_IGN,
652 // so that SIGPIPE gets reset to its default behaviour on exec.
653 action.sa_handler = empty_handler;
654 sigemptyset(&action.sa_mask);
655 action.sa_flags = 0;
656 if (sigaction(SIGPIPE, &action, &oact) != 0) {
657 sysErrorBelch("warning: failed to install SIGPIPE handler");
658 }
659
660 set_sigtstp_action(rtsTrue);
661 }
662
663 void
664 resetDefaultHandlers(void)
665 {
666 struct sigaction action;
667
668 action.sa_handler = SIG_DFL;
669 sigemptyset(&action.sa_mask);
670 action.sa_flags = 0;
671
672 // restore SIGINT
673 if (sigaction(SIGINT, &action, NULL) != 0) {
674 sysErrorBelch("warning: failed to uninstall SIGINT handler");
675 }
676 // restore SIGPIPE
677 if (sigaction(SIGPIPE, &action, NULL) != 0) {
678 sysErrorBelch("warning: failed to uninstall SIGPIPE handler");
679 }
680
681 set_sigtstp_action(rtsFalse);
682 }
683
684 #endif /* RTS_USER_SIGNALS */