[unix programming] signal and signal processing

40
[Unix Programming] [Unix Programming] Signal and Signal Processing Signal and Signal Processing Young-Ju, Han Young-Ju, Han Email: [email protected] Email: [email protected]

Upload: azure

Post on 05-Jan-2016

140 views

Category:

Documents


2 download

DESCRIPTION

[Unix Programming] Signal and Signal Processing. Young-Ju, Han Email: [email protected]. Contents. Introduction signal names normal and abnormal termination signal handling signal sets setting the signal action : signal & sigaction Signal blocking Sending signals - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: [Unix Programming] Signal and Signal Processing

[Unix Programming][Unix Programming]Signal and Signal ProcessingSignal and Signal Processing

Young-Ju, HanYoung-Ju, Han

Email: [email protected]: [email protected]

Page 2: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

ContentsContents

Introduction signal names normal and abnormal termination

signal handling signal sets setting the signal action : signal & sigaction

Signal blocking Sending signals

to other processes : kill to yourself : raise and alarm pause system call

Page 3: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

IntroductionIntroduction

Signals A simple method for transmitting software interrupts to UNIX processes Asynchronous events has a name

begin with the three characters SIG defined by positive integer constants

<signal.h> 0 : special usage (normal error checking)

It is often used to determine if a specific process still exists.

3 things with signals signal handling signal blocking signal sending

Terminology generate : when event causes the signal occur delivered : when action for a signal is taken pending : during the time between generation and delivery option of block

if generated and action is default or catch then pending until unblocks or changes to ignore

Page 4: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

IntroductionIntroduction

Signal name

/usr/include/sys/iso/signal_iso.h default action

SIGABRT 6 abnormal termination (calling abort()) terminate w / core

SIGALRM 14 Alarm clock (time out) terminate

SIGBUS bus error (hardware fault) terminate w / core

SIGCHLD 18 child process terminated or stopped ignore

SIGCONT continue executing if stopped (job control) continue / ignore

SIGFPE arithmetic exception (floating-point exception) terminate w / core

SIGHUP 1 hang up terminate

SIGILL 4 illegal hardware instruction terminate w / core

SIGINT 2 terminal interrupt character terminate

SIGKILL 9 Kill, termination terminate

SIGPIPE 13 write on pipe or socket when recipient has terminated terminate

SIGPOLL pollable event terminate

SIGPROF profiling time expired terminate

signal name

Page 5: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

IntroductionIntroduction

Signal name /usr/include/sys/iso/signal_iso.h default action

SIGQUIT 3 terminal quit character terminate w / core

SIGSEGV invalid memory reference terminate w / core

SIGSTOP 23 Stop executing stop process

SIGSYS invalid system call terminate w / core

SIGTERM Software termination signal terminate

SIGTRAP 5 Trace trap, abnormal termination terminate w / core

SIGTSTP terminal stop character stop process

SIGTTIN background process attempting read from control tty stop process

SIGTTOU background process attempting write to control tty stop process

SIGURG urgent condition (socket) ignore

SIGUSR1 user-defined signal terminate

SIGVTALRM virtual timer alarm terminate

SIGXCPU CPU time limit exceeded terminate w / core

SIGXFSZ file size limit exceeded terminate w / core

Page 6: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

IntroductionIntroduction

abnormal termination SIGABRT, SIGBUS, SIGSEGV, SIGQUIT, SIGILL,

SIGTRAP, SIGSYS, SIGXCPU, SIGXFSZ, SIGFPEcore dump file

memory dump of process values of all program variables, h/w register and control

information from the kernel when it terminate

WCOREDUMP(status)

abort();SIGABRT signalcore dumpa process can send a signal to itself

Page 7: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

disposition of the signal (action) We can tell the kernel to do when a signal occurs ignore the signal

When delivered to process, it is discardednever be ignored: SIGKILL, SIGSTOP

Let the default action applyterminate process (abnormal terminate)ignore (SIGCHLD )stop (SIGSTOP,SIGSTP)

catch the signaltake a specified user-defined actionto perform clean-up operationNever be catched: SIGKILL, SIGSTOP

Page 8: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

signo : signal name sa_handler

SIG_IGN , SIG_DFL , user_defined signal handler

#include <signal.h>

void (*signal(int signo, void (*sa_handler)(int)))(int);Returns : previous disposition of signal (see following) if OK, SIG_ERR on error

=typedef void sigfunction (int);sigfunction *signal(int, sa_handler *);SIG_ERRSIG_DFLSIG_IGN

signal C library ANSI C

Page 9: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

#include <signal.h>

#include <stdio.h>

#include <unistd.h>

int main() {

void catchint(int);

signal(SIGINT,catchint);

printf(“sleep call #1\n”); sleep(4);

printf(“sleep call #2\n”); sleep(4);

printf(“Exiting \n”); exit(0);

}

void catchint(int signo) {

printf(“\nCATCHINT: signo=%d\n”, signo);

printf(“CATCHINT: returning\n\n”);

}

Ex) signal C library

Page 10: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

signal sets type sigset_t <signal.h> a list of signals (to do something with)

one of the main parameters passed to system call that deal with signal

#include <signal.h>

//initialize

int sigemptyset (sigset_t *set);

int sigfillset (sigset_t *set);

//manipulate

int sigaddset (sigset_t *set, int signo);

int sigdelset (sigset_t *set, int signo);

//signo 가 set 의 member 인지 check

int sigismember(const sigset_t *set, int signo);

0 : ok-1 : error

0 : ok-1 : error

0 : non-member1 : member

Page 11: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

signal sets

#include <signal.h>

sigset_t mask1, mask2;

sigemptyset(&mask1); sigaddset(&mask1, SIGINT);sigaddset(&mask1, SIGQUIT);

sigfillset(&mask2);sigdelset(&mask2, SIGCHLD);

Page 12: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

sigaction system call setting the signal action Detailed signal management to choose a particular method of handling a signal

#include <signal.h>

int sigaction(int signo, const struct sigaction *act, const struct sigaction *oldact );

previous settingspecify an actionexcept) SIGSTOP

SIGKILLto set

either one can NULL

Page 13: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

<signal.h>struct sigaction{ void (* sa_handler) (int); sigset_t sa_mask; int sa_flags; int (*sa_sigaction)(int, siginfo_t*, void *);} sigset_t

sa_handler: the action to be taken(SIG_IGN,SIG_DEF,func)sa_mask: to add signal blocked during sa_handlersa_flags: flags which affect the behavior of the signal

SA_RESETHAND : reset to SIG_DFL after executing sa_handler SA_SIGINFO : passing additional information to sa_sigaction

its number, sending PID, RUID of the sending PID.. Must use sa_sigaction() instead of sa_handler()

SA_RESTART : slow system call restart

Page 14: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

ex) catching SIGINT

#include <signal.h>

#include <stdio.h>

#include <unistd.h>

int main() {

static struct sigaction act;

void catchint(int);

act.sa_handler = catchint;

sigfillset(&(act.sa_mask));

sigaction(SIGINT, &act, NULL);

printf(“sleep call #1\n”); sleep(4);

printf(“sleep call #2\n”); sleep(4);

printf(“sleep call #3\n”); sleep(4);

printf(“sleep call #4\n”); sleep(4);

printf(“Exiting \n”); exit(0);

}

void catchint(int signo) {

printf(“\nCATCHINT: signo=%d\n”, signo);

printf(“CATCHINT: returning\n\n”);

}

Page 15: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

ex) ignoring SIGINT

#include <signal.h>

#include <stdio.h>

#include <unistd.h>

int main() {

static struct sigaction act;

act.sa_handler = SIG_IGN;

sigfillset(&(act.sa_mask));

sigaction(SIGINT, &act, NULL);

sigaction(SIGQUIT, &act, NULL);

printf(“sleep call #1\n”); sleep(4);

printf(“sleep call #2\n”); sleep(4);

printf(“sleep call #3\n”); sleep(4);

printf(“sleep call #4\n”); sleep(4);

printf(“Exiting \n”); exit(0);

}

Page 16: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

ex) restoring a previous action

#include <signal.h>

#include <stdio.h>

#include <unistd.h>

int main() {

static struct sigaction act, oldact;

void catchint(int);

act.sa_handler = catchint;

sigfillset(&(act.sa_mask));

//step1 : signal disposition 설정 sigaction(SIGINT, &act, NULL);

sleep(4);

printf(“sleep call #1\n”); sleep(4);

//step2 : step1 에서 설정한 signal disposition 을 저장 sigaction(SIGINT, NULL, &oldact);

Page 17: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

ex) restoring a previous action (cont’d)

act.sa_handler = SIG_IGN;

sigfillset(&(act.sa_mask));

//step3 : signal disposition 재설정 sigaction(SIGINT, &act, NULL); sigaction(SIGINT, &act, &oldact);

printf(“sleep call #2\n”); sleep(4);

printf(“sleep call #3\n”); sleep(4);

//step2 에서 저장했던 signal disposition 을 다시 복원 sigaction(SIGINT, &oldact, NULL);

printf(“sleep call #4\n”); sleep(4);

printf(“Exiting \n”); exit(0);

}

void catchint(int signo) {

printf(“\nCATCHINT: signo=%d\n”, signo);

printf(“CATCHINT: returning\n\n”);

}

Page 18: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal handlingsignal handling

ex) a graceful exit

#include <stdio.h>

#include <stdlib.h>

#include <signal.h>

#include <unistd.h>

int main(){

static struct sigaction act;

void g_exit(int);

act.sa_handler = g_exit;

sigaction(SIGINT, &act, NULL);

……… //tempfile 조작 }

void g_exit(int s) {

unlink(“tempfile”);

fprintf(stderr, “Interrupted – exiting\n”);

exit(1);

}

Page 19: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

Signals and System CallsSignals and System Calls

If a process is sent a signal when it is executing a system call Default action

the signal has no effect until the system call completes

Exception Slow system calls : read(), write(), open() etcReturn errno (errno = EINTR)

example for interrupted system calls

if(write(tfd, buf, size) < 0 ){

if(errno == EINTR){

fprintf(stderr,”write interrupted\n”);

}

/* handle other errors */

}

Page 20: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

Signals and system callsSignals and system calls

Solution for interrupted slow system calls Solution 1

Solution2sa_flags of struct sigaction : setting SA_RESTARTEx)

act.sa_flags |= SA_RESTART

again:

if(write(tfd, buf, size) < 0 ){

if(errno == EINTR){

fprintf(stderr,”write interrupted\n”);

goto again; // just an interrupted system call

}

/* handle other errors */

}

Page 21: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal blockingsignal blocking

Blocked Signal Not delivered to process When the signal is unblocked, it is delivered to process Don’t the block SIGKILL and SIGSTOP

Signal maskThe collection of signals that are currently blocked

Page 22: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal blockingsignal blocking

returns the set of signals that are blocked from delivery and currently pending for the calling process

The set of signals is returned through the set argument

#include <signal.h>

int sigpending(sigset_t *set);set : the set of signals that are pending

Returns : 0 if OK, -1 on error

Page 23: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal blockingsignal blocking

to block out specific signals

#include <signal.h>

int sigprocmask (int how, const sigset_t *set, sigset_t *oldset);

SIG_SETMASK Use set for the mask- ignore the previous value of the mask

SIG_UNBLOCK Unblock the signals in set- remove them from the existing mask

SIG_BLOCK Block the signals in set- add them to the existing mask. The new mask

is the union of the existing mask and set

if set ≠ NULL

≠ NULL : previous signal mask

NULL : not used

0: ok-1 : error

Page 24: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

Signal blockingSignal blocking

Print the signal mask for the process

void pr_mask() { sigset_t sigset; int errno_save;

errno_save = errno;

if(sigprocmask(SIG_SETMASK, NULL, &sigset) < 0) perror(“sigprocmask error”);

if(sigismember(&sigset, SIGINT)) printf(“SIGINT ”); if(sigismember(&sigset, SIGQUIT)) printf(“SIGQUIT ”); if(sigismember(&sigset, SIGUSR1)) printf(“SIGUSR1 ” ); if(sigismember(&sigset, SIGALRM)) printf(“SIGALRM ”);

printf(“\n”);}

Page 25: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal blockingsignal blocking

Ex) extremely critical code

#include <signal.h>

...

sigset_t set1;

sigfillset(&set1);

sigprocmask(SIG_SETMASK, &set1, NULL);...

/* perform extremely critical code */...sigprocmask(SIG_UNBLOCK, &set1, NULL);

Page 26: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal blockingsignal blocking

Ex) less critical piece of code

#include <signal.h>

sigset_t set1, set2;

sigfillset(&set1);

sigfillset(&set2);

sigdelset(&set2, SIGINT);

sigdelset(&set2, SIGQUIT);

/* perform non critical code */

sigprocmask(SIG_SETMASK, &set1, NULL);

/* perform extremely critical code */

sigprocmask(SIG_UNBLOCK, &set2, NULL);

/* perform less critical code */

sigprocmask(SIG_UNBLOCK, &set1, NULL);

Page 27: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal blockingsignal blocking

Signal blocking with fork and exec

#include <errno.h>#include <stdio.h>#include <signal.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>

void catchctrlc(int signo){printf("interupted %ld - %d\n", getpid(), signo);

}

int main(){pid_t child;sigset_t mask,omask;

struct sigaction act;

//SIGINT 로 signal mask 설정if((sigemptyset(&mask) == -1) || (sigaddset(&mask,SIGINT)== -1) ||

(sigprocmask(SIG_SETMASK,&mask,&omask) == -1)) {perror("sigprocmask");return 1;

}

act.sa_handler = catchctrlc; sigfillset(&(act.sa_mask));

sigaction(SIGINT, &act,NULL);

Page 28: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal blockingsignal blocking

Signal blocking with fork and execif((child=fork()) == -1)

return 1;

if(child == 0){

sleep(14);execl("/bin/ls","ls","-l",NULL);perror("execl");return 1;

}

sleep(5);//unblocked SIGINTif(sigprocmask(SIG_SETMASK, &omask, NULL) == -1){

return 1;

}

while(wait(NULL) == -1){if(errno != EINTR) {

perror("error");return 1 ;

}}return 0;

}

Page 29: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal blockingsignal blocking

pause system call to pause the calling process until any signal Obsolete by sigsuspend system call

#include <unistd.h> #include <signal.h> void sig_handler(int signo){ printf("SIGINT 발생 \n"); }int main(){ static struct sigaction act; act.sa_handler = sig_handler; sigfillset(&(act.sa_mask)); sigaction(SIGINT, &act, NULL); printf("hello world!\n"); pause(); printf("Interupt\n");}

#include <unistd.h>

int pause ();Returns : -1 with errno set to EINTR

Page 30: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal blockingsignal blocking

Reliability Problem of pause system call

if(!usr_interrupt)pause();

sigset_t newmask, oldmask;sigemptyset(&newmask);sigaddset(&newmask, SIGINT);

/* block SIGINT and save current signal mask */sigprocmask(SIG_BLOCK, &newmask, &oldmask);../* critical region of code */../* reset signal mask, which unblocks SIGINT */sigprocmask(SIG_SETMASK, &oldmask, NULL);

/* window is open */pause(); /*wait for signal to occur */

Unblock 된 Signal 이 발생한다면 ?

Page 31: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal blockingsignal blocking

A way to both reset the signal mask and put the process to sleep in a single atomic operation

Replace the caller’s signal mask with the set of signals pointed to by the sigmask argument

Suspend the caller until delivery of a signal whose action is either to execute a signal catching function or to terminate the process

If a signal is caught and if the signal handler returns, then sigsuspend returns and the signal mask of the process is set to its value before the call to sigsuspend

#include <signal.h>

int sigsuspend(const sigset_t *sigmask)sigmask : blocked signal (usually empty set)Returns : -1 with errno set to EINTR(OK)

-1 with errno set to EFAULT(error)

Page 32: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

signal blockingsignal blocking

int main(void) {signal(SIGINT, sig_int);sigemptyset(&zeromask);sigaddset(&zeromask, SIGUSR1);sigemptyset(&newmask);sigaddset(&newmask, SIGINT);sigprocmask(SIG_BLOCK, &newmask, &oldmask);

/* critical region of code */

/* pause, allowing all signals except SIGUSR1 */sigsuspend(&zeromask);sigprocmask(SIG_SETMASK, &oldmask, NULL);

exit(0);}

static void sig_int(int signo) {return;

}

Page 33: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

sending signalsending signal

send a signal to other process or a group kill UNIX command

Signal used mainly SIGHUP(1), SIGINT(2), SIGQUIT(3), SIGKILL(9), SIGTERM(15)

Ex)

kill -2 100kill –s int 100kill –s INT 100kill –INT 100

kill –s signal_name pid…kill [-signal_name] pid….kill [-signal_number] pid…

Page 34: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

sending signalsending signal

send a signal to other process or a group kill system call

#include <sys/types.h>#include <signal.h>

int kill (pid_t pid, int sig);

0 : ok-1 : errorEPERM : permissionESRCH : no such processEINVAL : sig is not valid

> 0 : to certain process= 0 : to all process in own process group= -1 : if euid = root, all process except init process if euid = user, all process with a ruid equal to euid of the sender

< 0 : to all process in |pid| process group

> 0 : certain signal= 0 : normal error checking

Page 35: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

sending signalsending signal

raise to send a signal to itself

#include <signal.h>

int raise (int sig); [ = kill(getpid(), sig); ]

#include <unistd.h>

unsigned int alarm (unsigned int secs);

0 : not setting any pervious alarm timer>0 :time remaining for any previous alarm timer

in seconds

alarm to set a timer (timer expire : SIGALRM) alarm(0) : alarm turned off Not supported multiple alarm

Page 36: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

sending signalsending signal

static void sig_alarm(int signo) {

/* nothing to do, just return to wake up the pause */return ;

}

unsigned int sleep1(unsigned int nsecs) { if(signal(SIGALRM, sig_alarm) == SIG_ERR) return (nsecs);

alarm(nsecs); /* start the timer */ pause(); /* next caught signal wakes us up */ return (alarm(0)); /* turn off timer, return unslept time */}

Simple, incomplete implementation of a sleep

Page 37: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

sigsetjmp and siglongjmpsigsetjmp and siglongjmp

When a signal is caught, the signal-catching function is entered with the current signal automatically being added to the signal mask of the process prevents subsequent occurrence of that signal from interrupting the

signal handler

If savemask is nonzero then sigsetjmp saves the current signal mask of the process in env

When siglongjmp is called, if the env argument was saved by a call to sigsetjmp with a nonzero savemask, then siglongjmp restores the saved signal mask

#include <setjmp.h>

int sigsetjmp(sigjmp_buf env, int savemask);Returns : 0 if called directly, nonzero if returning from a call to siglongjmp

void siglongjmp(sigjmp_buf env, int val);

Page 38: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

sigsetjmp and siglongjmpsigsetjmp and siglongjmp

sigsetjmp_buf position;void goback(int);

int main(void) {static struct sigaction act;.../* save current position */if(sigsetjmp(position, 1) == 0){act.sa_handler = goback;sigaction(SIGINT,&act, NULL);}

domenu();..

}

void goback(int signo) {write(2, “\nInterrupt\n”);/* go back to saved position */siglongjmp(position,1);

}

Page 39: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

sigsetjmp and siglongjmpsigsetjmp and siglongjmp

int main(void) {signal(SIGUSR1, sig_usr1);signal(SIGALRM, sig_alrm);

if(sigsetjmp(jmpbuf,1)) {exit(1);

}canjump = 1;for(;;) pause();

}

static void sig_usr1(int signo) {if(canjmp ==0) return;

alarm(3);for(;;)... /* busy wait for 3 seconds */

canjump = 0;siglongjmp(jmpbuf,1);

}

static void sig_alrm(int signo) {return;

}

Page 40: [Unix Programming] Signal and Signal Processing

2007 UNIX Programming2007 UNIX Programming

sigsetjmp and siglongjmpsigsetjmp and siglongjmp

static jmp_buf env_alrm;

static void sig_alrm(int signo) { setlongjmp(env_alrm,1);}

unsigned int sleep2(unsigned int nsecs) { if(signal(SIGALRM, sig_alrm) == SIG_ERR) return (nsecs);

if( sigsetjmp(env_alrm,1) == 0) { alarm(nsecs); pause(); } return (alarm(0));}

Another (imperfect) implementation of a sleep