Cygwin: uname: add host machine tag to sysname.
[newlib-cygwin.git] / winsup / cygwin / DevDocs / how-signals-work.txt
blob09d7d0aa5b84175e5b19a0c0c41212892a20ec27
1 Contributed by Christopher Faylor
3 [note that the following discussion is still incomplete]
5 How do signals work?
7 On process startup, cygwin starts a secondary thread which deals with
8 signals.  This thread contains a loop which blocks waiting for
9 information to arrive on a pipe whose handle (sendsig) is currently
10 stored in _pinfo (this may change).
12 Communication on the sendsig pipe is via the 'sigpacket' structure.
13 This structure is filled out by the sig_send function with information
14 about the signal being sent, such as (as of this writing) the signal
15 number, the originating pid, the originating thread, and the address of
16 the mask to use (this may change).
18 Any cygwin function which calls a win32 api function is wrapped by the
19 assembly functions "_sigfe" and "_sigbe".  These functions maintain a
20 cygwin "signal stack" which is used by the signal thread to control
21 handling of signal interrupts.  Cygwin functions which need to be
22 wrapped by these functions (the majority) are labelled by the SIGFE
23 option in the file cygwin.din.
25 The cygwin.din function is translated into a standard cygwin.def file by
26 the perl script "gendef".  This function notices exported cygwin
27 functions which are labelled as SIGFE and generates a front end assembly
28 file "sigfe.s" which contains the wrapper glue necessary for every
29 function to call sigfe prior to actually dispatching to the real cygwin
30 function.  This generated file contains low-level signal related
31 functions: _sigfe, _sigbe, sigdelayed, sigreturn, longjmp, and setjmp.
33 The signal stack maintained by sigfe/sigbe and friends is a secondary
34 shadow stack.  Addresses from this stack are swapped into the "real"
35 stack as needed to control program flow.  The intent is that executing
36 cygwin functions will still see the same stack layout as if they had
37 been called directly and will be able to retrieve arguments from the
38 stack but will always return to the _sigbe routine so that any signal
39 handlers will be properly called.
41 Upon receipt of a "non-special" (see below) signal, the function
42 sigpacket::process is called.  This function determines what action, if
43 any, to take on the signal.  Possible actions are: Ignore the signal
44 (e.g., SIGUSR1), terminate the program (SIGKILL, SIGTERM), stop the
45 program (SIGSTOP, SIGTSTP, etc.), wake up a sigwait or sigwaitinfo in a
46 targetted thread, or call a signal handler (possibly in a thread).  If
47 no thread information has been sent to sigpacket::process, it determines
48 the correct thread to use based on various heuristics, as per UNIX.  As
49 per linux, the only time a handler is called in a thread is when there
50 is some kind of fault like SIGSEGV, SIGILL, etc.  Signals sent via the
51 UNIX kill() function are normally sent to the main thread.  Ditto
52 signals sent as the result of pressing tty keys, like CTRL-C.
54 Signals which stop a process are handled by a special internal handler:
55 sig_handle_tty_stop.  Some signals (e.g., SIGKILL, SIGSTOP) are
56 uncatchable, as on UNIX.
58 If the signal has an associated signal handler, then the setup_handler
59 function is eventually called.  It is passed the signal, the address of
60 the handler, a standard UNIX sigaction structure, and a pointer to the
61 thread's "_cygtls" information.  The meat of signal processing is in
62 setup_handler.
64 setup_handler has a "simple" task.  It tries to stop the appropriate
65 thread and either redirect its execution to the signal handler function,
66 flag that a signal has been received (sigwait) or both (sigpause).
68 To accomplish its task, setup_handler first inspects the target thread's
69 local storage (_cygtls) structure.  This structure contains information
70 on any not-yet-handled signals that may have been set up by a previous
71 call to setup_handler but not yet dispatched in the target thread.  If this
72 structure seems to be "active", then setup_handler returns, notifying it's
73 parent via a false value.  Otherwise processing continues.
75 (For pending signals, the theory is that the signal handler thread will
76 be forced to be rerun by having some strategic cygwin function call
77 sig_send with a __SIGFLUSH argument.  This causes the signal handler to
78 rescan the signal array looking for pending signals.)
80 After determining that it's ok to send a signal, setup_handler will lock
81 the cygtls stack to ensure that it has complete access.  It will then
82 inspect the thread's 'incyg' boolean.  If this is true, the thread is
83 currently executing a cygwin function.  If it is false, the thread is
84 unlocked and it is assumed that the thread is executing "user" code.
85 The actions taken by setup_handler differ based on whether the program
86 is executing a cygwin routine or not.
88 If the program is executing a cygwin routine, then the
89 interrupt_on_return function is called which causes the address of the
90 'sigdelayed' function to be pushed onto the thread's signal stack, and
91 the signal's mask and handler to be saved in the tls structure.  After
92 performing these operations, the 'signal_arrived' event is signalled, as
93 well as any thread-specific wait event.
95 Since the sigdelayed function was saved on the thread's signal stack,
96 when the cygwin function returns, it will eventually return to the
97 sigdelayed "front end".  The sigdelayed function will save a lot of
98 state on the stack and set the signal mask as appropriate for POSIX.
99 It uses information from the _cygtls structure which has been filled in
100 by interrupt_setup, as called by setup_handler.  sigdelayed pushes a
101 "call" to the function "sigreturn" on the thread's signal stack.  This
102 will be the return address eventually seen by the signal handler.  After
103 setting up the return value, modifying the signal mask, and saving other
104 information on the stack, sigreturn clears the signal number in the
105 _cygtls structure so that setup_handler can use it and jumps to the
106 signal handler function.  And, so a UNIX signal handler function is
107 emulated.
109 The signal handler function operates as normal for UNIX but, upon
110 return, it does not go directly back to the return address of the
111 original cygwin function.  Instead it returns to the previously
112 mentioned 'sigreturn' assembly language function.
114 sigreturn resets the process mask to its state prior to calling the
115 signal handler.  It checks to see if a cygwin routine has set a special
116 "restore this errno on returning from a signal" value and sets errno to
117 this, if so.  It pops the signal stack, places the new return address on
118 the real stack, restores all of the register values that were in effect
119 when sigdelayed was called, and then returns.
121 Ok.  That is more or less how cygwin interrupts a process which is
122 executing a cygwin function.  We are almost ready to talk about how
123 cygwin interrupts user code but there is one more thing to talk about:
124 SA_RESTART.
126 UNIX allows some blocking functions to be interrupted by a signal
127 handler and then return to blocking.  In cygwin, so far, only
128 read/readv() and the wait* functions operate in this fashion.  To
129 accommodate this behavior, a function notices when a signal comes in and
130 then calls the _cygtls function 'call_signal_handler_now'.
131 'call_signal_handler_now' emulates the behavior of both sigdelayed and
132 sigreturn.  It sets the appropriate masks and calls the handler,
133 returning true to the caller if SA_RESTART is active.  If SA_RESTART is
134 active, the function will loop.  Otherwise it will typically return -1
135 and set the errno to EINTR.
137 Phew.  So, now we turn to the case where cygwin needs to interrupt the
138 program when it is not executing a cygwin function.  In this scenario,
139 we rely on the win32 "SuspendThread" function.  Cygwin will suspend the
140 thread using this function and then inspect the location at which the
141 thread is executing using the win32 "GetThreadContext" call.  In theory,
142 the program should not be executing in a win32 api since attempts to
143 suspend a process executing a win32 call can cause disastrous results,
144 especially on Win9x.
146 If the process is executing in an unsafe location then setup_handler
147 will (quickly!) return false as in the case above.  Otherwise, the
148 current location of the thread is pushed on the thread's signal stack
149 and the thread is redirected to the sigdelayed function via the win32
150 "SetThreadContext" call.  Then the thread is restarted using the win32
151 "ResumeThread" call and things proceed as per the sigdelayed discussion
152 above.
154 This leads us to the sig_send function.  This is the "client side" part
155 of the signal manipulation process.  sig_send is the low-level function
156 called by a high level process like kill() or pthread_kill().
158 ** More to come **