Title: Section A March 14
1Section A (March 14)
- Outline
- Exceptions
- Process
- Signals
- Non-local jumps
- Reminders
- Lab4
- Due Next Thursday
- TA Kun Gao
- Shamelessly
- Modified from
- Minglong Shaos
- Recitation, Fall 2004
2Exceptional control flow (ECF)
- Abrupt changes in the control flow
- 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 - Happens at all levels of a computer system
- Exceptions
- Concurrent processes
- Signals
- Non-local jumps
3Exceptions
- Interrupt (asynchronous exceptions)
- I/O interrupt, hardware reset, software reset,
etc. - Traps
- System calls, breakpoint traps, etc.
- Faults
- Page fault, protection fault, etc.
- Aborts
- Parity error, machine check, etc.
4Process concept
- An instance of running program
- Multiple processes run concurrently by time
slicing - Context switching
- Control flow passes from one process to another
- Preemptive scheduler of OS
- Process vs Threads (a favorite interview
question) - Threads are logical flows that run in the context
of a single process
5Process IDs process groups
- A process has its own, unique process ID
- pid_t getpid()
- A process belongs to exactly one process group
- pid_t getpgrp()
- A new process belongs to which process group?
- Its parents process group
- A process can make a process group for itself and
its children - setpgid(0, 0)
6Create a new process
- int fork(void)
- Create a new process that is identical to the
parent process - Return 0 to child process
- Return childs pid to the parent process
- Call once, return twice
- Test your understanding
- Problem 1
7Problem 1
include ltunistd.hgt include ltstdio.hgt int cnt
0 int main(void) if (fork() 0) cnt
fork() cnt cnt
printf("d", cnt) return 0
Possible output 133 313 331
8Reaping child process
- Child process becomes zombie when terminates
- Still consume system resources
- Parent performs reaping on terminated child
- pid_t wait(int status)
- pid_t waitpid(pid_t pid, int status, int
options) - Straightforward for reaping a single child
- Tricky for Shell implementation!
- Multiple child processes
- Both foreground and background
9Signals
- Section 8.5 in text
- Read at least twice really!
- A signal tells our program that some event has
occurred
10Important signals (Fig 8.23)
- SIGINT
- Interrupt signal from terminal (ctrl-c)
- SIGTSTP
- Stop signal from terminal (ctrl-z)
- SIGCHLD
- A child process has stopped or terminated
11How to Send Signals
- Process
- int kill(pid_t pid, int sig)
- Groups
- int kill(pid_t gid, int sig), where gid is
negative - Process can also send a signal to itself
- int alarm(unsigned int secs) to send a SIGALRM
signal - Can we use signals to count events?
- No
- Why? Signals not queued!!
12Signals sending
Process 2
1
OS procedure
- divide by zero SIGFPE
- ctrl-c SIGINT
- child process exit SIGCHLD
OS Kernel
13Signals receiving
Process 2
Check when schedule the process to run
0
1
OS procedure
OS Kernel
14Receiving a signal
- Default action
- The process terminates and dumps core
- The process stops until restarted by a SIGCONT
signal (ctrl-z) - The process ignore the signal
- Can modify (additional action)
- Handle the signal -- install signal handler
- void sigint_handler(int sig)
- signal(SIGINT, sigint_handler)
- An example problem 3
15Problem 3
void handler(int sig) static int beeps 0
printf("YO\n") if (beeps lt 2) alarm(1)
/ next SIGALRM will be delivered in 1s /
else printf("MA\n") kill(getpid(),
SIGKILL) int main() signal(SIGALRM,
handler) alarm(1) / next SIGALRM will be
delivered in 1s / while (1)
printf(" is Great!\n") return 0
1. Output YO YO MA 2. The program will terminate
16Signals not queued
int counter 0 void handler(int sig)
counter sleep(1) return int
main() int i signal(SIGUSER2,
handler) if (fork() 0) for (i
0 i lt 5 i) kill(getppid(),
SIGUSR2) printf(sent SIGUSR2 to
parent\n) exit(0)
wait(NULL) printf(counter d\n,
counter) exit(0)
Output sent SIGUSR2 to parent sent SIGUSR2 to
parent sent SIGUSR2 to parent sent SIGUSR2 to
parent sent SIGUSR2 to parent counter 1
17Race hazard
- A data structure is shared by two pieces of code
that can run concurrently - Different behaviors of program depending upon how
the schedule interleaves the execution of code.
18An 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()
19An okay schedule
Shell
Signal Handler
Child
time
fork() addjob()
execve() exit()
sigchld_handler() deletejobs()
20A problematic schedule
Shell
Signal Handler
Child
time
fork()
execve() exit()
sigchld_handler() deletejobs()
addjob()
Job added to job list after the signal handler
tried to delete it!
21Solution 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)
22Non-local jump
- int setjmp(jmp_buf env)
- Must called before longjmp
- Stores current register context, stack pointer,
and PC in the jump buffer env - First called, return 0 if no error
- void longjmp(jmp_buf env, int i)
- Restores register context from jump buffer env
- 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
- A function that has been called but not yet
completed
23Non-local jump (cont)
- int sigsetjmp(jmp_buf env)
- Also saves blocked signals
- void siglongjmp(jmp_buf env, int i)
- Restores blocked signals besides others
Lets see an example problem 4
24Problem 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 ((nfoo())lt0) sleep(1)
printf("d\n", n)
Answer 1. 3 2. 45
25Summary
- Process
- fork(), waitpid(), execve()
- Reaping child processes
- Signals
- signal(), install handler, signals not queued
- Non-local jumps
- Check man page to understand the system calls
better - man waitpid (fork, signal, )
- Read text book!