Exceptions
Exceptions
Today
Exceptional Control Flow: Exceptional Control Flow
Processes
Exceptions and Processes
Instructors:
Seth Copen Goldstein, Anthony Rowe, and Greg Kesden
1 2
5 6
code for
exception handler n‐1
Examples:
div by 0, arithmetic overflow, page fault, I/O request completes, Ctrl‐C
7 8
Carnegie Mellon Carnegie Mellon
Time
How are these Illusions maintained?
Process executions interleaved (multitasking) or run on separate cores
Address spaces managed by virtual memory system
we’ll talk about this in a couple of weeks
17 18
user code
Time
kernel code context switch
Time user code
user code
19 20
Carnegie Mellon Carnegie Mellon
23 24
Carnegie Mellon Carnegie Mellon
25 26
27 28
Carnegie Mellon Carnegie Mellon
void fork8()
Zombie void fork7()
{ Nonterminating {
if (fork() == 0) {
if (fork() == 0) { /* Child */
Example /* Child */
printf("Terminating Child, PID = %d\n", Child Example printf("Running Child, PID = %d\n",
getpid());
getpid()); while (1)
exit(0); ; /* Infinite loop */
} else { } else {
printf("Running Parent, PID = %d\n", printf("Terminating Parent, PID = %d\n",
linux> ./forks 7 & getpid()); getpid());
[1] 6639 while (1) exit(0);
Running Parent, PID = 6639 ; /* Infinite loop */ }
Terminating Child, PID = 6640 } }
} linux> ./forks 8
linux> ps
PID TTY TIME CMD Terminating Parent, PID = 6675
6585 ttyp9 00:00:00 tcsh Running Child, PID = 6676 Child process still active even
6639 ttyp9 00:00:03 forks
ps shows child process as linux> ps though parent has terminated
6640 ttyp9 00:00:00 forks <defunct> “defunct” PID TTY TIME CMD
6641 ttyp9 00:00:00 ps 6585 ttyp9 00:00:00 tcsh
linux> kill 6639 6676 ttyp9 00:00:06 forks
[1] Terminated Killing parent allows child to be 6677 ttyp9 00:00:00 ps
linux> ps reaped by init linux>
PID TTY TIME CMD
6585 ttyp9 00:00:00 tcsh
6642 ttyp9 00:00:00 ps
31 32
Carnegie Mellon Carnegie Mellon
void fork8()
Nonterminating {
if (fork() == 0) {
wait: Synchronizing with Children
/* Child */
Child Example printf("Running Child, PID = %d\n",
getpid()); Parent reaps child by calling the wait function
while (1)
; /* Infinite loop */
} else {
printf("Terminating Parent, PID = %d\n", int wait(int *child_status)
getpid());
exit(0); suspends current process until one of its children terminates
}
}
return value is the pid of the child process that terminated
linux> ./forks 8 if child_status != NULL, then the object it points to will be set
Terminating Parent, PID = 6675 to a status indicating why the child process terminated
Running Child, PID = 6676 Child process still active even
linux> ps though parent has terminated
PID TTY TIME CMD
6585 ttyp9 00:00:00 tcsh
6676 ttyp9 00:00:06 forks Must kill explicitly, or else will keep
6677 ttyp9 00:00:00 ps
running indefinitely
linux> kill 6676
linux> ps
PID TTY TIME CMD
6585 ttyp9 00:00:00 tcsh
6678 ttyp9 00:00:00 ps
33 34
waitpid(): Waiting for a Specific Process execve: Loading and Running Programs
Stack bottom
Null‐terminated
int execve( env var strings
waitpid(pid, &status, options) char *filename,
Null‐terminated
suspends current process until specific process terminates char *argv[], cmd line arg strings
various options (see textbook) char *envp[] unused
void fork11() ) envp[n] == NULL
{
pid_t pid[N];
Loads and runs in current process: envp[n‐1]
int i; Executable filename …
int child_status; envp[0] environ
With argument list argv
for (i = 0; i < N; i++) argv[argc] == NULL
if ((pid[i] = fork()) == 0) And environment variable list envp argv[argc‐1]
exit(100+i); /* Child */
for (i = N-1; i >= 0; i--) { Does not return (unless error) …
pid_t wpid = waitpid(pid[i], &child_status, 0); argv[0]
if (WIFEXITED(child_status)) Overwrites code, data, and stack Linker vars
printf("Child %d terminated with exit status %d\n", keeps pid, open files and signal context envp
wpid, WEXITSTATUS(child_status));
else Environment variables: argv
argc
}
printf("Child %d terminated abnormally\n", wpid);
“name=value” strings
Stack frame for
} getenv and putenv main
37 Stack top 38
envp[n] = NULL
envp[n‐1] “PWD=/usr/droh”
… “PRINTER=iron”
envp[0] “USER=droh”
environ
39 40
Carnegie Mellon
Summary (cont.)
Spawning processes
Call fork
One call, two returns
Process completion
Call exit
One call, no return
Reaping and waiting for processes
Call wait or waitpid
Loading and running programs
Call execve (or variant)
One call, (normally) no return
41