Signals and Signal Processing

pancakesbootΤεχνίτη Νοημοσύνη και Ρομποτική

24 Νοε 2013 (πριν από 3 χρόνια και 24 μέρες)

41 εμφανίσεις

Signals and Signal Processing

CIS 370


Lab 5

UMassD

Good Programming


It is always good practice to write several
small programs that do specific things and
combine them to do a task than write a large
monolithic program.


Ideally you would like several cooperating
processes.


UNIX provides a rich environment for IPCs
-

some of these are
signals, pipes
and
FIFOs.

Signals


We will focus on
signals

in this chapter and
get to
pipes
and

FIFOs
later.


Suppose you’re running a UNIX command

$cc largeprog.c


If the command does not terminate in a
reasonable period of time, one typically
terminates this by pressing ctrl
-
c.


The command is terminated and the shell
prompt returns.

What actually happens?


The part of the
kernel

responsible for the
keyboard input sees the interrupt character.


The
kernel

then sends a signal called
SIGINT to all the processes that recognize
the terminal as their controlling terminal.


This includes the invocation of
cc.


When
cc

receives the signal, it performs the
default action associated with SIGINT and
terminates.

What actually happens contined


The
shell

process also receives the signal.


It sensibly ignores the signal !


Programs can elect to “catch” SIGINT.


When they catch the signal they execute a
special interrupt routine (aka interrupt
service routine (ISR)).

Signals and the kernel


Signals are also used by the kernel to deal
with certain kinds of severe error.


Suppose a corrupt program containing
illegal machine instructions is executed
(accidentally or intentionally).


A process begins execution of the program.

Signal and the kernel


The kernel will detect the attempt to execute
the illegal instructions and send the process
the signal SIGILL (ILL stands for illegal) to
terminate it. It may look something like this


$faultyprog


Illegal instruction. Core dumped.


Process to process signals


Signals can also be sent between processes.


Consider the following:


$ gcc verybigprog.c &


[1] 1034


$ // after a long time


$ kill
-
9 1034


1034 terminated


$


The command
kill
sends a SIGTERM signal.
SIGTERM will terminate the process.

Process response to signals

A process can do three things with signals:



Choose the way it responds when it receives
a particular signal (signal handling).


Block out signals (that is, leave them for
later) for a specific piece of critical code.


Send a signal to another process.

Signal names


Signals are given mnemonic names.



They are defined in <signal.h>, with the
pre
-
processor directive
#define
.


They stand for small positive integers.


Most are intended for the kernel, although a
few are provided to be sent from process to
process.

Signal names


SIGABRT
-

Process abort signal
(abnormal
termination
-

core dumped)


SIGALRM
-

Alarm clock
(sent by the
kernel after timer has expired).


SIGBUS
-

Bus error

(sent if a hardware
fault is detected
-

abnormal termination)


SIGCHLD
-

Child process terminated
(whenever a child process stops or
terminates, the kernels sends this to the
parent).


SIGCONT
-

Continue executing if stopped

(This is a job control signal which will
continue if the process is stopped, else
ignored, inverse of SIGSTOP)


SIGFPE
-

Floating
-
point exception (AT).


SIGHUP
-

The hangup signal
. (The kernel
sends this to all processes attached to a
control terminal

when the terminal is
disconnected
-

applies to sessions as well).


SIGILL
-

Illegal instruction. (AT)


SIGKILL
-

Kill
(special signal sent from
one process to another to terminate the
receiver
-

cannot be ignored).


SIGPIPE
-

Write on pipe or socket when
recipient has terminated.
(discussed later).


SIGPOLL
-

Pollable event.

(signal is
generated by the kernel when an open file
descriptor is ready for input or output).


SIGPROF
-

Profiling time expired.
(signal
is generated when timer expires and can be
used by interpreters to profile execution).


SIGQUIT
-

Quit.
(similar to SIGINT)


SIGSEGV
-

Invalid memory reference. (AT)
(segmentation violation, generated when a
process attempts to access invalid memory)


SIGSTOP
-

Stop execution.
(job control
signal, cannot be ignored)


SIGSYS
-

Invalid system call. (AT)
(sent by
kernel when a process attempts to execute a
machine instruction which is not a sys call)


SIGTERM
-

Software termination signal
(used to terminate a process)


SIGTRAP
-

Trace trap.

(AT)

(special signal
used by debuggers such as sdb and adb,
along with
ptrace
system call).


SIGTSTP
-

Terminal stop signal.
(signal
generated by the user typing ctrl
-
z, can be
ignored)


SIGTTIN
-

Background process attempting
read.
(when a bg process attempts to read
from the controlling terminal, this signal is
sent and the process is typically stopped)


SIGTTOU
-

Background process
attempting write.
(generated when the bg
process attempts to write to the controlling
terminal)


SIGURG
-

High bandwidth data is
available at a socket.
(signal tells a process
that urgent or out of band data has been
received on a network connection)


SIGUSR1 and SIGUSR2
-

user defined
signals


SIGVTALRM
-

Virtual timer expired.

(sent
when user
-
mode time expires).


SIGXCPU
-

CPU time limit exceeded.

(signal generated when the process exceeds
its maximum CPU time limit).


SIGXFSZ
-

File size limit exceeded. (AT)
(generated when a process exceeds its
maximum file size limit)

Normal termination


For most signals normal termination occurs
when a signal is received.


The exit status returned to the parent in this
circumstance tells the parent what happened


There are macros defined in <sys/wait.h>
which allow the parent to determine the
cause of termination and in this particular
case the value of the signal which was
responsible.

Abnormal Termination


The signals
SIGABRT, SIGBUS, SIGSEGV,
SIGQUIT, SIGILL, SIGTRAP, SIGSYS,
SIGXCPU, SIGXFSZ and SIGFPE
cause
abnormal termination
-

core dumped.


The memory dump of the process is written
to a file called
core.


The
core

file will include the values of the
program variables, h/w registers and control
information
-

in binary.

Signal Handling


Once a signal is received the process may:


Take the default action, which is to terminate
the process. SIGSTOP will stop the process.


Ignore the signal and carry on processing. In
case of
batch programs

signals may be
ignored.


Take a specified user
-
defined action. Whenever
a program exits, whatever the cause, a
programmer might want to perform clean
-
up
operations such as removing work files.

Signal sets


Signal sets are one of the main parameters
passed to system calls that deal with signals


They simply specify a list of signals you
want to do something with.


Signal sets are defined of the type
sigset_t


You can empty the set, or remove a few,
keep only the ones that interest you.

Signal sets


Usage

#include <signal.h>


// initialize

int sigempty(sigset_t *set);

int sigfillset(sigset_t *set);

// manipulate

int sigaddset(segset_t *set, int signo);

int sigdelset(segset_t *set, int signo);

Setting the signal action


Once you have defined a signal set, you can
choose a particular method of handling a
signal using
sigaction.


Usage


#include <string.h>


int sigaction(int signo, const struct sigaction *act,





const struct sigaction *oact);

sigaction continued


sigaction

structure contains a signal set.


The first parameter
signo

specifies the
signal for which we want to specify action


SIGSTOP and SIGKILL are exempt


The second parameter
act
gives the action
you want to set for
signo.


The third parameter
oact

will be filled out
with the current settings.


Without interrupts

With an interrupt

Restoring a previous action

The
sigsetjmp and siglongjmp

A program position is saved in in an object of
type sigjmp_buf (defined in <setjmp.h>


sigsetjmp and siglongjmp signals


Sometimes it is useful to go back to a
certain part of a program if a signal occurs


sigsetjmp

saves the mask of the current
signal set and the current position in the
program


siglongjmp

restores the mask if
encountered (like a long
-
distance, non
-
local
goto statement) and returns control to the
point in the program where it was saved.

Signal Blocking


If a program is performing a sensitive task,
it may well need to be protected from
interrupts.


Rather than ignore the signals, a process can
block the signals


The signals will be handled after the
completion of the task.

The
sigprocmask
system call


Usage

#include <signal.h>

int sigprocmak(int how, const sigset_t *set,




sigset_t *oset);

The
how

parameter tells the system call what
specific action to take. For example it coul be
set to SIG_SETMASK, which means block out
the signals in the second parameter
set

from
now on. The third parameter is simply filled
with the current mask of blocked signals.

Sending signals to other processes


The
kill

system call



Usage

#include <sys/types.h>

#include <signal.h>


int kill(pid_t pid, int sig);

Sending signals using raise and alarm


raise()
simply sends a signal to the executing
process.


alarm()
is a simple and useful call that sets up
a process alarm clock. Signals are used to tell
the process that the clock’s timer has expired.


alarm
is not like
sleep
, which suspends the
process execution,
alarm
returns immediately.


After a
fork
, however the alarm clock is turned
off in a child process.

The
pause

system call


pause
is a companion to
alarm.


pause
suspends the calling process, in a
way that will not waste CPU cycles, until
any signal, such as SIGALRM, is received.


If the process ignores the signal, the
pause

also ignores the signal.


If the signal is caught, when the appropriate
interrupt routine is finished,
pause
returns a
-
1.

Piping


Pipes

and other IPCs