13 Signal Handling - Department of Computer Science

advertisement
CSc 352
Signal Handling in Unix
Saumya Debray
Dept. of Computer Science
The University of Arizona, Tucson
debray@cs.arizona.edu
Signals
• A signal is a mechanism for notifying a program that
some event has occurred.
– intuition: signal  “software interrupt”
– when a signal is sent to a program, its normal execution is
interrupted
– depending on (1) the state of the program, and (2) the
type of signal, the program may
• enter some pre-specified signal handler; or
• take some default action.
2
Example Signals
Signal Name
SIGHUP
SIGINT
SIGQUIT
SIGILL
SIGTRAP
SIGFPE
SIGKILL
SIGSEGV
SIGTERM
SIGSTKFLT
SIGSTOP
SIGPROF
SIGWINCH
SIGPWR
…
Number
1
2
3
4
5
8
9
11
15
16
19
27
28
30
…
(not a complete list)
Description
Hangup (POSIX)
Terminal interrupt (ANSI)
Terminal quit (POSIX)
Illegal instruction (ANSI)
Trace trap (POSIX)
Floating point exception (ANSI)
Kill(can't be caught or ignored) (POSIX)
Invalid memory segment access (ANSI)
Termination (ANSI)
Stack fault
Stop executing(can't be caught or ignored) (POSIX)
Profiling alarm clock (4.2 BSD)
Window size change (4.3 BSD, Sun)
Power failure restart (System V)
…
3
Synchronous vs. Asynchronous Signals
• Synchronous signals:
– arise from executing an instruction in the process’s
instruction stream
• e.g.: illegal instruction (SIGILL); illegal address (SIGSEGV)
– causes a trap into the OS kernel trap handler
• sometimes referred to as “traps”
– directed to the process/thread that executed the
instruction
• Asynchronous signals:
– source is external to the current execution
• e.g.: profiling clock (SIGPROF); terminal interrupt, ^C (SIGINT)
4
What’s going on: A high-level view
• Signal sending:
processes
– OS kernel updates info
for destination process
• Signal receiving:
– kernel forces target
process to handle signal
• Pending signals are sent
but not yet received
• A process can block
some signals
signals
Operating system kernel
interrupts
devices
5
Dealing with Signals
• The way in which a process deals with a given signal
is called the disposition of that signal in that process.
• Possible dispositions:
– ignore
– default
• different for different signals
– programmer-specified handler
• Exceptions: SIGKILL and SIGSTOP
– defaults cannot be changed for these
6
Specifying a Signal Handler
7
Specifying a Signal Handler
changes the
signal handler
8
Specifying a Signal Handler
signal number
(can’t be SIGKILL
or SIGSTOP)
9
Specifying a Signal Handler
info about new handler)
10
Specifying a Signal Handler
if non-NULL,
where to save
old handler info
11
Specifying a Signal Handler
pointer to handler function:
void handler(int signal_num)
or SIG_DFL or SIG_IGN
12
Specifying a Signal Handler
specifies handler if sa_flags
contains SA_SIGINFO
13
Specifying a Signal Handler
specifies signals that should
be blocked while the handler
is executing
14
A Simple Example
structure to hold info
about handler
15
A Simple Example
signal handler function
16
A Simple Example
specifying the handler
17
A Simple Example
didn’t change the default
signal handler
NULL pointer dereference
produces a Segmentation
fault
18
A Simple Example
signal handler changed
but why does it get
executed over and over?
19
Behind the scenes of a SIGSEGV
• When a program tries to access a bad address:
– execution traps into the OS kernel
– if no handler is specified:
• kernel invokes the default handler
• default handler prints out “Segmentation fault” and kills the
process
– if a handler is specified:
• kernel executes the handler
– the expectation is that the handler fixes the problem
• restarts the offending operation
– this allows programmer-controlled recovery from errors
20
Another Example: weird factorial
no base case???
21
weird factorial: cont’d
y-1
j =

x
i=0
= x*y
22
weird factorial: cont’d
j = 1 * 2 * … * n = n!
23
weird factorial: cont’d
signal handler for SIGSEGV
(signal raised by
dereferencing a bad pointer
in factorial() )
prints out k = n! and exits
sets k = n!
24
Sending signals
• A program can send a signal to another program
using the kill() system call:
int kill(pid_t pid, int sig)
sends the signal number sig to process pid
(see /usr/include/asm-generic/signal.h)
• A user can send a signal from the command line
using the kill command:
kill –N pid
E.g., “kill -9 pid”
(9 = SIGKILL)
25
Asynchronous signals
SIGINT will be handled by
my_handler()
send SIGINT to process
with process-id = target
26
Asynchronous signals – cont’d
27
Blocking signals
• Each process has a list (bit-vector) of blocked signals
– when a signal is blocked, it remains pending
• Related system calls:
– sigprocmask(2) system call changes the list of blocked
signals
– sigpending(2) shows which signals are (blocked and)
pending
– sigsuspend(2) suspends the calling process until the
specified signal is received
28
Signal voodoo
• When a process forks off a child, it may want to hear
back about how things went
– when the child process exits, it becomes a zombie until its
exit status is reported to the parent process
– when something interesting happens to the child (it exits,
crashes, stops, etc.), a SIGCHLD signal is sent to its parent
– the parent can use the wait() system call (or variants) to
find the child’s exit status
• If the parent is not interested, it can use sigaction()
to explicitly specify that SIGCHLD should be ignored
29
Download