Excep&onal Control Flow
15-213: Introduc7on to Computer Systems Recita7on 9: Monday, October 26th, 2015
Copyright By PowCoder代写 加微信 powcoder
Adapted from slides by
¢ Midterm Wrap-Up
¢ Excep7onal Control Flow
¢ Processes
¢ Signals
¢ Shell lab
Midterm Wrap-Up
¢ Midterms scores are on Autolab
¢ View exams during OH in 5207
¢ Regrade requests – in wri7ng (hardcopy only)
Excep&onal Control Flow
¢ Up to now: two mechanisms for changing control flow: § Jumps and branches
§ Call and return
Both react to changes in program state
¢ Insufficient for a useful system:
Difficult to react to changes in system state
§ data arrives from a disk or a network adapter § instruc7on divides by zero
§ user hits Ctrl-C at the keyboard
§ System 7mer expires
¢ System needs mechanisms for “excep7onal control flow”
Asynchronous Excep&ons (Interrupts)
¢ Caused by events external to the processor § Indicated by se`ng the processor’s interrupt pin § Handler returns to “next” instruc7on
¢ Examples:
§ I/O interrupts
§ hi`ng Ctrl-C at the keyboard
§ arrival of a packet from a network § arrival of data from a disk
§ Hard reset interrupt
§ hi`ng the reset bucon
§ Sod reset interrupt
§ hi`ng Ctrl-Alt-Delete on a PC
Synchronous Excep&ons
¢ Caused by events that occur as a result of execu7ng an instruc7on:
§ Inten7onal
§ Examples: system calls, breakpoint traps, special instruc7ons
§ Returns control to “next” instruc7on § Faults
§ Uninten7onal but possibly recoverable
§ Examples: page faults (recoverable), protec7on faults
(unrecoverable), floa7ng point excep7ons
§ Either re-executes faul7ng (“current”) instruc7on or aborts
§ uninten7onal and unrecoverable
§ Examples: parity error, machine check § Aborts current program
¢ What is a program?
§ A bunch of data and instruc7ons stored in an executable binary file
§ Wricen according to a specifica7on that tells users what it is supposed to do
§ Stateless since binary file is sta7c
¢ Defini7on: A process is an instance of a running program.
¢ Process provides each program with two key abstrac7ons: § Logical control flow
§ Each program seems to have exclusive use of the CPU § Private virtual address space
§ Each program seems to have exclusive use of main memory § Gives the running program a state
¢ How are these Illusions maintained?
§ Process execu7ons interleaved (mul7tasking) or run on separate
§ Address spaces managed by virtual memory system
§ Just know that this exists for now; we’ll talk about it soon
¢ Four basic States § Running
§ Execu7ng instruc7ons on the CPU
§ Number bounded by number of CPU cores § Runnable
§ Wai7ng to be running § Blocked
§ Wai7ng for an event, maybe input from STDIN
§ Not runnable § Zombie
§ Terminated, not yet reaped
¢ Four basic process control func7on families: § fork()
§ And other variants such as execve()
§ exit() § wait()
§ And variants like waitpid()
¢ Standard on all UNIX-based systems
¢ Don’t be confused:
Fork(), Exit(), Wait() are all wrappers provided by CS:APP
¢ int fork(void)
§ creates a new process (child process) that is iden7cal to the calling
process (parent process)
§ OS creates an exact duplicate of parent’s state:
§ Virtual address space (memory), including heap and stack § Registers, except for the return value (%eax/%rax)
§ File descriptors but files are shared
§ ResultàEqual but separate state
§ Fork is interes7ng (and oden confusing) because it is called once but returns twice
¢ int fork(void)
§ returns 0 to the child process
§ returns child’s pid (process id) to the parent process § Usually used like:
pid_t pid = fork();
if (pid == 0) {
// pid is 0 so we can detect child
printf(“hello from child\n”);
// pid = child’s assigned pid
printf(“hello from parent\n”);
¢ int exec()
§ Replaces the current process’s state and context
§ But keeps PID, open files, and signal context
§ Provides a way to load and run another program
§ Replaces the current running memory image with that of new program
§ Set up stack with arguments and environment variables
§ Start execu7on at the entry point
§ Never returns on successful execu7on
§ The newly loaded program’s perspec7ve: as if the previous program has not been run before
§ More useful variant is int execve()
§ More informa7on? man 3 exec
¢ void exit(int status)
§ Normally return with status 0 (other numbers indicate an error)
§ Terminates the current process
§ OS frees resources such as heap memory and open file descriptors and so on…
§ Reduce to a zombie state
§ Must wait to be reaped by the parent process (or the init
process if the parent died)
§ Signal is sent to the parent process no7fying of death § Reaper can inspect the exit status
¢ int wait(int *child_status)
§ suspends current process un7l one of its children terminates
§ return value is the pid of the child process that terminated
§ When wait returns a pid > 0, child process has been reaped
§ All child resources freed
§ if child_status != NULL, then the object it points to will be set to a
status indica7ng why the child process terminated
§ More useful variant is int waitpid()
§ For details: man 2 wait
Process Examples
pid_t child_pid = fork();
if (child_pid == 0){
/* only child comes here */
printf(“Child!\n”);
exit(0); }
printf(“Parent!\n”);
¢ What are the possible output (assuming fork succeeds) ?
§ Child! Parent!
§ Parent! Child!
¢ How to get the child to always print first?
Process Examples
int status;
pid_t child_pid = fork();
if (child_pid == 0){
/* only child comes here */
printf(“Child!\n”);
exit(0); }
printf(“Parent!\n”);
¢ Waits 7l the child has terminated.
Parent can inspect exit status of
child using ‘status’ § WEXITSTATUS(status)
¢ Output always: Child!
waitpid(child_pid, &status, 0);
Process Examples
¢ char* argv[] = {“/bin/ls”, “-l”, NULL};¢
An example of something useful.
Why is the first arg “/bin/ls”? Will child reach here?
int status;
pid_t child_pid = fork();
char* env[] = {…, NULL};
if (child_pid == 0){
/* only child comes here */
execve(“/bin/ls”, argv, env);
/* will child reach here? */
waitpid(child_pid, &status, 0);
… parent continue execution…
Process Examples
¢ Unix Process Hierarchy:
[0] init [1] Login shell
Daemon e.g. httpd
Grandchild
Child Child Grandchild
¢ A signal is a small message that no7fies a process that an event of some type has occurred in the system
§ akin to excep7ons and interrupts (asynchronous)
§ sent from the kernel (some7mes at the request of another process) to a
§ signal type is iden7fied by small integer ID’s (1-30)
§ only informa7on in a signal is its ID and the fact that it arrived
11 SIGSEGV
14 SIGALRM
17 SIGCHLD
Default Action
Terminate & Dump
Corresponding Event
Interrupt (e.g., ctl-c from keyboard)
Kill program (cannot override or ignore)
Segmentation violation
Timer signal
Child stopped or terminated
¢ Kernel sends (delivers) a signal to a des2na2on process by upda7ng some state in the context of the des7na7on process
¢ Kernel sends a signal for one of the following reasons:
§ Kernel has detected a system event such as Ctrl-C (SIGINT), divide-
by-zero (SIGFPE), or the termina7on of a child process (SIGCHLD) § Another program called the kill() func7on
§ The user used a kill u7lity
¢ A des7na7on process receives a signal when it is forced by the kernel to react in some way to the delivery of the signal
¢ Receiving a signal is non-queuing
§ There is only one bit in the context per signal
§ Receiving 1 or 300 SIGINTs looks the same to the process
¢ Signals are received at a context switch
¢ Three possible ways to react:
§ Ignore the signal (do nothing)
§ Terminate the process (with op7onal core dump)
§ Catch the signal by execu7ng a user-level func7on called signal
§ Akin to a hardware excep7on handler being called in response to an asynchronous interrupt
¢ A des7na7on process receives a signal when it is forced by the kernel to react in some way to the delivery of the signal
¢ Blocking signals
§ Some7mes code needs to run through a sec7on that can’t be
interrupted
§ Implemented with sigprocmask()
¢ Wai7ng for signals
§ Some7mes, we want to pause execu7on un7l we get a specific
§ Implemented with sigsuspend()
¢ Can’t modify behavior of SIGKILL and SIGSTOP
¢ Signal handlers
§ Can be installed to run when a signal is received
§ The form is void handler(int signum){ … }
§ Separate flow of control in the same process
§ Resumes normal flow of control upon returning
§ Can be called any&me when the appropriate signal is fired
¢ int sigsuspend(const sigset_t *mask)
§ Can’t use wait() twice – use sigsuspend!
§ Temporarily replaces the signal mask of the calling process with the mask given
§ Suspends the process un7l delivery of a signal whose ac7on is to invoke a signal handler or terminate a process
§ Returns if the signal is caught
§ Signal mask restored to the previous state
§ Use sigaddset(), sigemptyset(), etc. to create the mask
Signal Examples
¢ Every process belongs to exactly one process group
¢ Process groups can be used to distribute signals easily
¢ A forked process becomes a member of the parent’s
process group
Fore- pgid=20 ground
Back- ground job #1
Background process group 32
Return process group of current process
Change process group of a process
Back- ground job #2
Background process group 40
Foreground process group 20
Signal Examples
// sigchld handler installed
pid_t child_pid = fork();
if (child_pid == 0){
/* child comes here */
execve(……);
void sigchld_handler(int signum)
int status;
pid_t child_pid =
waitpid(-1, &status, WNOHANG);
if (WIFEXITED(status))
remove_job(child_pid);
¢ Does add_job or remove_job() come first?
¢ Where can we block signals in this code to guarantee correct execu7on?
add_job(child_pid);
Signal Examples
// sigchld handler installed
Block SIGCHLD
pid_t child_pid = fork();
if (child_pid == 0){
/* child comes here */
void sigchld_handler(int signum)
execve(……);
Unblock SIGCHLD
int status;
pid_t child_pid =
waitpid(-1, &status, WNOHANG);
if (WIFEXITED(status))
remove_job(child_pid);
add_job(child_pid);
Unblock SIGCHLD
¢ Does add_job or remove_job() come first?
¢ Where can we block signals in this code to guarantee correct execu7on?
¢ Shell Lab is out!
¢ Due Tuesday, November 3rd at 11:59pm
¢ Read the code we’ve given you
§ There’s a lot of stuff you don’t need to write yourself; we gave you
quite a few helper func7ons
§ It’s a good example of the code we expect from you!
¢ Don’t be afraid to write your own helper func7ons; this is not a simple assignment
¢ Read man pages. You may find the following func7ons helpful:
§ sigemptyset() § sigaddset() § sigprocmask() § sigsuspend() § waitpid()
§ setpgid() § kill()
¢ Please do not use sleep() to solve synchroniza7on issues.
¢ Hazards
§ Race condi7ons
§ Hard to debug so start early (and think carefully) § Reaping zombies
§ Race condi7ons
§ Handling signals correctly § Wai7ng for foreground job
§ Think carefully about what the right way to do this is
Shell Lab Tes&ng
¢ Run your shell
§ This is the fun part!
§ How should the shell behave?
¢ runtrace
§ Each trace tests one feature.
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com