Section A March 14 Outline TA Kun Gao













![Receiving a signal n Default action n The process terminates [and dumps core] n Receiving a signal n Default action n The process terminates [and dumps core] n](https://slidetodoc.com/presentation_image/adc128d8d8a15dd9246430ecf82c67d7/image-14.jpg)











- Slides: 25
Section A (March 14) Outline TA: Kun Gao n Exceptions n Process n Signals n Non-local jumps Reminders n Lab 4: n Due Next Thursday Shamelessly Modified from Minglong Shao’s Recitation, Fall 2004
Exceptional control flow (ECF) n Abrupt changes in the control flow n React to changes in system state that are not captured by internal program variables and are not necessarily related to the execution of the program n Happens at all levels of a computer system n Exceptions n Concurrent processes n Signals n Non-local jumps
Exceptions n Interrupt (asynchronous exceptions) n I/O interrupt, hardware reset, software reset, etc. n Traps n System calls, breakpoint traps, etc. n Faults n Page fault, protection fault, etc. n Aborts n Parity error, machine check, etc.
Process concept n An instance of running program n Multiple processes run “concurrently” by time slicing n Context switching n n Control flow passes from one process to another Preemptive scheduler of OS n Process vs Threads (a favorite interview question) n Threads are logical flows that run in the context of a single process
Process IDs & process groups n A process has its own, unique process ID n pid_t getpid(); n A process belongs to exactly one process group n pid_t getpgrp(); n A new process belongs to which process group? n Its parent’s process group n A process can make a process group for itself and its children n setpgid(0, 0);
Create a new process n int fork(void) Create a new process that is identical to the parent process n Return 0 to child process n Return child’s pid to the parent process n n Call once, return twice n Test your understanding… n Problem 1
Problem 1 #include <unistd. h> #include <stdio. h> int cnt = 0; int main(void) { if (fork() == 0){ cnt ++; fork(); cnt++; } cnt ++; printf("%d", cnt); return 0; } Possible output: 133 313 331
Reaping child process n Child process becomes zombie when terminates n Still consume system resources n Parent performs reaping on terminated child pid_t wait(int *status) pid_t waitpid(pid_t pid, int *status, int options) n Straightforward for reaping a single child n Tricky for Shell implementation! n Multiple child processes n Both foreground and background
Signals n Section 8. 5 in text n Read at least twice … really! n A signal tells our program that some event has occurred
Important signals (Fig 8. 23) n SIGINT n Interrupt signal from terminal (ctrl-c) n SIGTSTP n Stop signal from terminal (ctrl-z) n SIGCHLD n A child process has stopped or terminated
How to Send Signals n Process n int kill(pid_t pid, int sig) n Groups n int kill(pid_t gid, int sig), where gid is negative n Process can also send a signal to itself n int alarm(unsigned int secs) to send a SIGALRM signal n Can we use signals to count events? n No n Why? Signals not queued!!
Signals: sending Process 1 Process 2 kill(pid, SIGINT) 1 blocked pending OS procedure • divide by zero: SIGFPE • ctrl-c: SIGINT • child process exit: SIGCHLD other events OS Kernel
Signals: receiving Check when schedule the process to run Process 2 0 1 blocked pending OS procedure OS Kernel
Receiving a signal n Default action n The process terminates [and dumps core] n The process stops until restarted by a SIGCONT signal (ctrl-z) n The process ignore the signal n Can modify (additional action) n “Handle the signal” -- install signal handler void sigint_handler(int sig); signal(SIGINT, sigint_handler); n An example: problem 3
Problem 3 void handler(int sig){ static int beeps = 0; printf("YOn"); if (++beeps < 2) alarm(1); /* next SIGALRM will be delivered in 1 s */ else{ printf("MAn"); kill(getpid(), SIGKILL); } } int main(){ signal(SIGALRM, handler); alarm(1); /* next SIGALRM will be delivered in 1 s */ while (1) ; printf(" is Great!n"); return 0; } 1. Output: YO YO MA 2. The program will terminate
Signals not queued int counter = 0; void handler(int sig) { counter++; sleep(1); return; } Output: sent SIGUSR 2 sent SIGUSR 2 counter = 1 int main() { int i; signal(SIGUSER 2, handler); if (fork() == 0){ for (i = 0; i < 5; i++){ kill(getppid(), SIGUSR 2); printf(“sent SIGUSR 2 to parentn”); } exit(0); } wait(NULL); printf(“counter = %dn”, counter); exit(0); } to to to parent parent
Race hazard n A data structure is shared by two pieces of code that can run concurrently n Different behaviors of program depending upon how the schedule interleaves the execution of code.
An example of race hazard sigchld_handler() { pid = waitpid(…); deletejob(pid); } eval() { pid = fork(); if(pid == 0) { /* child */ execve(…); } /* parent */ /* signal handler may run BEFORE addjob()*/ addjob(…); }
An okay schedule time Shell Signal Handler Child fork() addjob() execve() exit() sigchld_handler() deletejobs()
A problematic schedule time Shell Signal Handler Child fork() execve() exit() sigchld_handler() deletejobs() addjob() Job added to job list after the signal handler tried to delete it!
Solution: blocking signals sigchld_handler() { pid = waitpid(…); deletejob(pid); } eval() { sigprocmask(SIG_BLOCK, …) pid = fork(); if(pid == 0) { /* child */ sigprocmask(SIG_UNBLOCK, …) /* child inherits parents block set */ execve(…); } /* parent */ /* signal handler might run BEFORE addjob() */ addjob(…); sigprocmask(SIG_UNBLOCK, …) } More details 8. 5. 6 (page 633)
Non-local jump int setjmp(jmp_buf env) n Must called before longjmp n Stores current register context, stack pointer, and PC in the jump buffer env n First called, return 0 if no error void longjmp(jmp_buf env, int i) n Restores register context from jump buffer env n Jumps back to where previous setjmp is called, behaves like setjmp just completes. But this time it returns i, not 0 Can only jump to an active context n A function that has been called but not yet completed
Non-local jump (cont) int sigsetjmp(jmp_buf env) n Also saves blocked signals void siglongjmp(jmp_buf env, int i) n Restores blocked signals besides others Let’s see an example: problem 4
Problem 4 jmp_buf stuff; int foo(){ char c = getc(stdin); if (c == 'x') longjmp(stuff, 42); else return 3; return -1; } int main() { int n; n = setjmp(stuff); while ((n+=foo())<0) sleep(1); printf("%dn", n); } Answer: 1. 3 2. 45
Summary n Process n fork(), waitpid(), execve() n Reaping child processes n Signals n signal(), install handler, signals not queued n Non-local jumps n Check man page to understand the system calls better n man waitpid (fork, signal, …) n Read text book!