Download presentation
Presentation is loading. Please wait.
Published byLucinda Sanders Modified over 8 years ago
1
號誌 (Signals)
2
What is “signal” 2 user land kernel land system call signal (up call) hardware/software events kernel service
3
What is “signal” 3 time register a call back function my_sig_handler eventfunc div by 0default seg. faultdefault alarmmy_sig_handler ctr+cterminate ctr+/terminate
4
What is “signal” 4 time register a call back function my_sig_handler eventfunc div by 0default seg. faultdefault alarmmy_sig_handler ctr+cterminate ctr+/terminate
5
What is “signal” 5
6
UNIX Signals (BSD) 6
7
signal and process management 7 http://linux.vbird.org/linux_basic/0440processcontrol.php
8
Lab 1 列印所有可註冊的 signal 8 1.#include 2.#include 3.#include 4.void sighandler(int signumber) { 5. printf("get a signal named '%d', '%s'\n", signumber, 6. sys_siglist[signumber]); 7.} 8.int main(int argc, char **argv) { 9. int sig_exist[100]; 10. int idx = 0; 11. for (idx = 0; idx < 100; idx++) { 12. if (signal(idx, sighandler) == SIG_ERR) {
9
Lab 1 列印所有可註冊的 signal 9 1. sig_exist[idx] = 0; 2. } else { 3. sig_exist[idx] = 1; 4. } 5. } 6. for (idx = 0; idx < 100; idx++) { 7. if (sig_exist[idx] == 1) 8. printf("%2d %s\n", idx, sys_siglist[idx]); 9. } 10. printf("my pid is %d\n", getpid()); 11. printf("press any key to resume\n"); 12. getchar(); 13.}
10
Lab 1: results (MAC OS X) 1 Hangup 2 Interrupt 3 Quit 4 Illegal instruction 5 Trace/BPT trap 6 Abort trap 7 EMT trap 8 Floating point exception 10 Bus error 11 Segmentation fault 12 Bad system call 13 Broken pipe 14 Alarm clock 15 Terminated 16 Urgent I/O condition 18 Suspended 19 Continued 20 Child exited 21 Stopped (tty input) 22 Stopped (tty output) 23 I/O possible 24 Cputime limit exceeded 25 Filesize limit exceeded 26 Virtual timer expired 27 Profiling timer expired 28 Window size changes 29 Information request 30 User defined signal 1 31 User defined signal 2 10
11
Lab 1: results (Linux) 1 Hangup 2 Interrupt 3 Quit 4 Illegal instruction 5 Trace/breakpoint trap 6 Aborted 7 Bus error 8 Floating point exception 10 User defined signal 1 11 Segmentation fault 12 User defined signal 2 13 Broken pipe 14 Alarm clock 15 Terminated 16 Stack fault 17 Child exited 18 Continued 20 Stopped 21 Stopped (tty input) 22 Stopped (tty output) 23 Urgent I/O condition 24 CPU time limit exceeded 25 File size limit exceeded 26 Virtual timer expired 27 Profiling timer expired 28 Window changed 29 I/O possible 30 Power failure 31 Bad system call 11
12
Lab 1: results (Linux) 試試看 1.kill -4 pid 2.resize your terminal window 12
13
Lab2: segmentation fault 試試看 ” 故意存取錯誤的記 憶體 ” 13
14
14 Interrupted System Calls A process is blocked in a “ slow ” device (a system call) The process receives a signal The system call is interrupted and returns an error ( errno = EINTR ) May be something happened that should wake up the blocked system call
15
Interrupted System Calls System calls divided into 2 categories: slow: reads from or writes to files that can block caller forever (pipes, terminals, network devs) opens of files that block until some condition occurs (terminal waiting on modem answer) pause, wait some ioctl operations interprocessor communication all others: disk I/O, etc. 15
16
Why? 16 rdyQ running interruptible uninterruptible fork()_exit()
17
Lab1: strace a.out rt_sigaction(SIGHUP, {0x4006ec, [HUP], SA_RESTORER|SA_RESTART, 0x7fa1045af4a0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGINT, {0x4006ec, [INT], SA_RESTORER|SA_RESTART, 0x7fa1045af4a0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGQUIT, {0x4006ec, [QUIT], SA_RESTORER|SA_RESTART, 0x7fa1045af4a0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGILL, {0x4006ec, [ILL], SA_RESTORER|SA_RESTART, 0x7fa1045af4a0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGTRAP, {0x4006ec, [TRAP], SA_RESTORER|SA_RESTART, 0x7fa1045af4a0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGABRT, {0x4006ec, [ABRT], SA_RESTORER|SA_RESTART, 0x7fa1045af4a0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGBUS, {0x4006ec, [BUS], SA_RESTORER|SA_RESTART, 0x7fa1045af4a0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGFPE, {0x4006ec, [FPE], SA_RESTORER|SA_RESTART, 0x7fa1045af4a0}, {SIG_DFL, [], 0}, 8) = 0 rt_sigaction(SIGKILL, {0x4006ec, [KILL], SA_RESTORER| SA_RESTART, 0x7fa1045af4a0}, {SIG_DFL, [], 0}, 8) = -1 EINVAL (Invalid argument) 17
18
18 Reentrant Functions 1.Process is executing 2.Signal arrives and is caught 3.Signal handler starts executing 4.Signal handler returns 5.Process resumes execution summary: signal is an asynchronous event. so... Any problems?
19
19 time register a call back function my_sig_handler eventfunc div by 0default seg. faultdefault alarmmy_sig_handler ctr+cterminate ctr+/terminate
20
20 Reentrant Functions What if process was in the middle of malloc(), signal handler starts executing and also calls malloc()? malloc() maintains a linked list of all allocated areas process may have been in the middle of updating the linked list!
21
21 Reentrant Functions Signal handlers should only call reentrant functions! “ errno variable” updated by reentrant functions such as read(), wait(), etc. signal handler should save errno, and restore it on exit
22
SIGCLD Semantics signal(SIGCLD, SIG_IGN) no zombie processes for children subsequent wait() will block until all children terminated and returns -1 with errno = ECHILD different from SIG_DFL (also ignore, but without the above semantics) signal(SIGCLD, handler) kernel checks for child to be waited for if there is, kernel calls SIGCLD handler 22
23
SIGCHLD Semantics POSIX.1 Does not specify what happens when SIGCHLD is ignored Single UNIX Specification (XSI extension) Same as for SIGCLD 4.4BSD and FreeBSD 5.2.1 Always generates zombies if SIGCHLD ignored SVR4, Solaris 9, Linux, Mac OS X 10.3 signal(SIGCHLD, SIG_IGN) zombies never generated 23
24
Lab5 #include void sighandler(int signumber) { printf("get a signal named '%d', '%s'\n", signumber, sys_siglist[signumber]); if (signumber == SIGINT) exit(0); } int main(int argc, char **argv) { int sig_exist[100]; sigset_t sigset; int idx = 0; for (idx = 0; idx < 100; idx++) { if (signal(idx, sighandler) == SIG_ERR) { sig_exist[idx] = 0; } else { sig_exist[idx] = 1; } for (idx = 0; idx < 100; idx++) { if (sig_exist[idx] == 1) printf("%2d %s\n", idx, sys_siglist[idx]); } printf("my pid is %d\n", getpid()); sigfillset(&sigset); sigprocmask(SIG_SETMASK, &sigset, NULL); printf("sleep 10sec\n"); for(idx=0; idx<10; idx++) { sleep(1); write(1, "*", 1); } printf("\n"); sigemptyset(&sigset); sigprocmask(SIG_SETMASK, &sigset, NULL); while (1) { pause(); } 24
25
Lab5: results... 63 (null) 64 (null) my pid is 7276 sleep 10sec *^\^\^\^\*^\^\^\^\**^\*^\***** get a signal named '3', 'Quit' ^Cget a signal named '2', 'Interrupt' 25
26
kill and raise functions kill: To send a signal to a process or a process group #include int kill(pid_t pid, int signo); Both return: 0 if OK, -1 on error 26
27
kill(pid_t pid, int signo) pid > 0: sent to PID==pid pid < 0: sent to PGID==|pid| pid == 0: sent to all processes with PGID == PGID of sender (with perm) pid == -1: all processes on the system for which the sender has permission to send signal (excluding system processes) 27
28
kill function Permission to send signals: Superuser: to any process Others: real/effective ID of sender must be equal to real/effective ID of receiver 28
29
Figure 10.10: read with timeout 1.#include “apue.h" 2. 3.static void sig_alrm(int); 4. 5.int main(void) 6.{ 7. int n; 8. char line[MAXLINE]; 9. 10. if (signal(SIGALRM, sig_alrm) == SIG_ERR) 11. err_sys("signal(SIGALRM) error"); 12. alarm(10); 13. if ( (n = read(STDIN_FILENO, line, MAXLINE)) < 0) 14. err_sys("read error"); 15. alarm(0); 16. 17. write(STDOUT_FILENO, line, n); 18. 19. exit(0); 20.} 29 race condition between alarm and read, set minute- long time delay to circumvent race read not interrupted if interrupted system calls are automatically restarted 比較好的寫法應該 是用 sigaction 並且 『不』使用 SA_RESTART 參數
30
Figure 10.10: read with timeout 1.static void 2.sig_alrm(int signo) 3.{ 4. /* nothing to do, just return to interrupt the read */ 5.} 30
31
lab 5 void sighandler(int signumber) { printf("get a signal named '%d', '%s'\n", signumber, sys_siglist[signumber]); if (signumber == SIGINT) exit(0); } int main(int argc, char **argv) { int sig_exist[100]; sigset_t sigset; int idx = 0; for (idx = 0; idx < 100; idx++) { if (signal(idx, sighandler) == SIG_ERR) { sig_exist[idx] = 0; } else { sig_exist[idx] = 1; } for (idx = 0; idx < 100; idx++) { if (sig_exist[idx] == 1) printf("%2d %s\n", idx, sys_siglist[idx]); } printf("my pid is %d\n", getpid()); /* 終止所有的 signal*/ sigfillset(&sigset); sigprocmask(SIG_SETMASK, &sigset, NULL); /* 睡 10 秒鐘 */ printf("sleep 10sec\n"); for(idx=0; idx<10; idx++) { sleep(1); /* 使用 write 避免 buffering*/ write(1, "*", 1); } printf("\n"); /* 重新啓動所有的 signal*/ sigemptyset(&sigset); sigprocmask(SIG_SETMASK, &sigset, NULL); while (1) { pause(); } 31
32
lab 5: results sleep 10sec *****^\*^\^\*^\*^\**/* 送出 5 個 ctr+\*/ get a signal named ‘3’, ‘Quit’/* 只收到一個 ctr+\*/ 32
33
33 sigaction Examine or modify a signal action Reliable Signals! #include int sigaction(int signo, const struct sigaction *act, struct sigaction *oact); Returns: 0 if OK, -1 on error nonnull modify action nonnull return action
34
34 sigaction 1.struct sigaction { 2./*addr of signal handler or SIG_IGN or SIG_DFL */ 3.void (*sa_handler)(int); 4./* additional signals to block */ 5.sigset_t sa_mask; 6./* signal options*/ 7.int sa_flags; 8./* alternate handler */ 9.void (*sa_sigaction)(int, siginfo_t *, void *); 10.};
35
35 sa_flags Check Figure 10.16 for sa_flags SA_INTERRUPT (not in standard, Linux only) SA_NOCLDSTOP (POSIX.1, all 4 platforms) SA_NOCLDWAIT (XSI, all 4 platforms) SA_NODEFER (XSI, all 4 platforms) SA_ONSTACK (XSI, all 4 platforms) SA_RESETHAND (XSI, all 4 platforms) SA_RESTART (XSI, all 4 platforms) SA_SIGINFO (POSIX.1, all 4 platforms)
36
36 sigsetjmp, siglongjmp Similar to setjmp and longjmp Difference: saves mask and restores it #include int sigsetjmp(sigjmp_buf env, int savemask); void siglongjmp(sigjmp_buf env, int val); Returns: 0 if called directly, nonzero if returning from siglongjmp
37
Figure 10.20: jmp functions 1.#include 2.#include 3.#include “apue.h" 4.static void sig_usr1(int), sig_alrm(int); 5.static sigjmp_buf jmpbuf; 6.static volatile sig_atomic_t canjump; 7. 8.int main(void) { 9. if (signal(SIGUSR1, sig_usr1) == SIG_ERR) 10. err_sys("signal(SIGUSR1) error"); 11. if (signal(SIGALRM, sig_alrm) == SIG_ERR) 12. err_sys("signal(SIGALRM) error"); 13. pr_mask("starting main: "); 14. 15. if (sigsetjmp(jmpbuf, 1)) { 16. pr_mask("ending main: "); 17. exit(0); } 18. canjump = 1; /* now sigsetjmp() is OK */ 19. for ( ; ; ) pause(); 20.} 37 Defined by ISO C Guaranteed atomic write (1)Does not extend across page boundaries (2)Accessed with a single machine instruction (3)volatile: accessed by 2 threads: main and signal handler Defined by ISO C Guaranteed atomic write (1)Does not extend across page boundaries (2)Accessed with a single machine instruction (3)volatile: accessed by 2 threads: main and signal handler
38
Figure 10.20: jmp functions 1.static void sig_usr1(int signo) { 2. time_t starttime; 3. 4. if (canjump == 0) 5. return; /* unexpected signal, ignore */ 6. 7. pr_mask("starting sig_usr1: "); 8. 9. alarm(3); /* SIGALRM in 3 seconds */ 10. 11. starttime = time(NULL); 12. for ( ; ; ) * busy wait for 5 seconds */ 13. if (time(NULL) > starttime + 5) break; 14. pr_mask("finishing sig_usr1: "); 15. 16. canjump = 0; 17. siglongjmp(jmpbuf, 1);/* jump back to main, don't return */ 18.} 38
39
Time line for Figure 10.20 Slides©2006 Pao-Ann Hsiung, Dept of CSIE, National Chung Cheng University, Taiwan 39 SIGUSR1 & SIGALRM
40
sigsuspend Function To protect critical section by blocking a signal 1.sigset_t newmask, oldmask; 2.sigemptyset(&newmask); 3.sigaddset(&newmask, SIGINT); 4.if(sigprocmask(SIG_BLOCK, &newmask, &oldmask), 0) 5. err_sys(“SIG_BLOCK error”); 6./* CRITICAL REGION OF CODE */ 7.if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) 8. err_sys(“SIG_SETMASK error”); 9. 10. 11.pause(); 40 What if signal occurs HERE?
41
41 sigsuspend Function Reset signal mask & put process to sleep for a signal (1 atomic operation) #include int sigsuspend(const sigset_t *sigmask); Returns: -1 with errno set to EINTR No successful return
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.