0% found this document useful (0 votes)
3 views

Exceptions

Uploaded by

navid.panah1
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Exceptions

Uploaded by

navid.panah1
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Carnegie Mellon Carnegie Mellon

Today
Exceptional Control Flow:  Exceptional Control Flow
Processes
Exceptions and Processes 

15‐213 / 18‐213: Introduction to Computer Systems


13th Lecture, Feb 26, 2013

Instructors:
Seth Copen Goldstein, Anthony Rowe, and Greg Kesden

1 2

Carnegie Mellon Carnegie Mellon

Control Flow Altering the Control Flow


 Processors do only one thing:  Up to now: two mechanisms for changing control flow:
 From startup to shutdown, a CPU simply reads and executes  Jumps and branches
(interprets) a sequence of instructions, one at a time  Call and return
 This sequence is the CPU’s control flow (or flow of control) Both react to changes in program state

Physical control flow  Insufficient for a useful system:


Difficult to react to changes in system state
<startup>  data arrives from a disk or a network adapter
inst1  instruction divides by zero
inst2  user hits Ctrl‐C at the keyboard
Time
inst3  System timer expires

instn
<shutdown>  System needs mechanisms for “exceptional control flow”
3 4
Carnegie Mellon Carnegie Mellon

Exceptional Control Flow ECF Exists at All Levels of a System


 Exists at all levels of a computer system  Exceptions
 Low level mechanisms  Hardware and operating system kernel software
 Exceptions  Process Context Switch This Lecture
change in control flow in response to a system event
  Hardware timer and kernel software
(i.e., change in system state)
 Signals
 Combination of hardware and OS software
 Kernel software and application software
 Higher level mechanisms
 Nonlocal jumps
 Process context switch Next Lecture
 Application code
 Signals What about
 Nonlocal jumps: setjmp()/longjmp() try/catch/throw?
 Implemented by either:
 OS software (context switch and signals)
 C language runtime library (nonlocal jumps)

5 6

Carnegie Mellon Carnegie Mellon

Exceptions Exception Tables


 An exception is a transfer of control to the OS in response to
Exception
some event (i.e., change in processor state) numbers

code for  Each type of event has a


User Process OS exception handler 0 unique exception number k
Exception code for
event I_current exception Table exception handler 1  k = index into exception table
I_next exception processing 0 (a.k.a. interrupt vector)
by exception handler 1 code for almost
2 exception handler 2
• return to I_current ...  Handler k is called each time
• return to I_next
• abort
n-1 ... exception k occurs

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

Asynchronous Exceptions (Interrupts) Synchronous Exceptions


 Caused by events external to the processor  Caused by events that occur as a result of executing an
instruction:
 Indicated by setting the processor’s interrupt pin
 Traps
 Handler returns to “next” instruction
Intentional
Examples: system calls, breakpoint traps, special instructions
 Examples:  Returns control to “next” instruction
 I/O interrupts  Faults
 hitting Ctrl‐C at the keyboard  Unintentional but possibly recoverable
 arrival of a packet from a network  Examples: page faults (recoverable), protection faults
 arrival of data from a disk (unrecoverable), floating point exceptions
 Hard reset interrupt  Either re‐executes faulting (“current”) instruction or aborts
 hitting the reset button  Aborts
 Soft reset interrupt  unintentional and unrecoverable
 hitting Ctrl‐Alt‐Delete on a PC  Examples: parity error, machine check
 Aborts current program
9 10

Carnegie Mellon Carnegie Mellon

Trap Example: Opening File Fault Example: Page Fault


int a[1000];
 User calls: open(filename, options)  User writes to memory location main ()
{
 Function open executes system call instruction int
 That portion (page) of user’s memory a[500] = 13;
0804d070 <__libc_open>: is currently on disk }
. . .
804d082: cd 80 int $0x80 80483b7: c7 05 10 9d 04 08 0d movl $0xd,0x8049d10
804d084: 5b pop %ebx
. . . User Process OS
User Process OS exception: page fault
movl
exception Create page and
int
pop Different privilege returns load into memory
open file levels!
returns
 Page handler must load page into physical memory
 OS must find or create file, get it ready for reading or writing  Returns to faulting instruction Different privilege
 Returns integer file descriptor  Successful on second try levels!
11 12
Carnegie Mellon Carnegie Mellon

Fault Example: Invalid Memory Reference Exception Table IA32 (Excerpt)


int a[1000];
main ()
{ Exception Number Description Exception Class
a[5000] = 13; 0 Divide error Fault
}
13 General protection fault Fault
80483b7: c7 05 60 e3 04 08 0d movl $0xd,0x804e360 14 Page fault Fault
18 Machine check Abort
User Process OS 32‐127 OS‐defined Interrupt or trap
128 (0x80) System call Trap
exception: page fault
movl 129‐255 OS‐defined Interrupt or trap
detect invalid address
signal process
Check Table 6‐1:
 Page handler detects invalid address
http://download.intel.com/design/processor/manuals/253665.pdf
 Sends SIGSEGV signal to user process Different privilege
 User process exits with “segmentation fault” levels!
13 14

Carnegie Mellon Carnegie Mellon

Altering the Control Flow (revisited) Today


 Up to now: two mechanisms for changing control flow:  Exceptional Control Flow
 Jumps and branches
Is there an alternative?  Processes
 Call and return
- For general purpose processors?
Both react to changes in program state
- For embedded processors?
 Insufficient for a useful system:
Difficult to react to changes in system state
 data arrives from a disk or a network adapter
 instruction divides by zero
 user hits Ctrl‐C at the keyboard
 System timer expires

 System needs mechanisms for “exceptional control flow”


15 16
Carnegie Mellon Carnegie Mellon

Processes Concurrent Processes


 Definition: A process is an instance of a running program.  Two processes run concurrently (are concurrent) if their
 One of the most profound ideas in computer science flows overlap in time
 Not the same as “program” or “processor”  Otherwise, they are sequential
 Examples (running on single core):
 Process provides each program with two key abstractions:  Concurrent: A & B, A & C
 Logical control flow  Sequential: B & C
 Each program seems to have exclusive use of the CPU
 Private virtual address space Process A Process B Process C
 Each program seems to have exclusive use of main memory

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

Carnegie Mellon Carnegie Mellon

User View of Concurrent Processes Context Switching


 Processes are managed by a shared chunk of OS code
 Control flows for concurrent processes are physically
called the kernel
disjoint in time
 Important: the kernel is not a separate process, but rather runs as part
of some user process
 However, we can think of concurrent processes as  Control flow passes from one process to another via a
running in parallel with each other context switch
Process A Process B
Process A Process B Process C

user code
Time
kernel code context switch
Time user code

kernel code context switch

user code

19 20
Carnegie Mellon Carnegie Mellon

fork: Creating New Processes Understanding fork


Process n Child Process m
 int fork(void)
pid_t pid = fork(); pid_t pid = fork();
 creates a new process (child process) that is identical to the calling if (pid == 0) { if (pid == 0) {
process (parent process) printf("hello from child\n"); printf("hello from child\n");
} else { } else {
 returns 0 to the child process printf("hello from parent\n"); printf("hello from parent\n");
} }
 returns child’s pid (process id) to the parent process
pid_t pid = fork(); pid_t pid = fork();
pid_t pid = fork(); if (pid == 0) { if (pid == 0) {
if (pid == 0) { pid = m printf("hello from child\n"); pid = 0 printf("hello from child\n");
} else { } else {
printf("hello from child\n");
printf("hello from parent\n"); printf("hello from parent\n");
} else { } }
printf("hello from parent\n");
} pid_t pid = fork(); pid_t pid = fork();
if (pid == 0) { if (pid == 0) {
printf("hello from child\n"); printf("hello from child\n");
 Fork is interesting (and often confusing) because } else { } else {
printf("hello from parent\n"); printf("hello from parent\n");
it is called once but returns twice } }

hello from parent Which one is first? hello from child


21 22

Carnegie Mellon Carnegie Mellon

Fork Example #1 Fork Example #2


 Parent and child both run same code  Two consecutive forks
 Distinguish parent from child by return value from fork
void fork2()
 Start with same state, but each has private copy
{
 Including shared output file descriptor printf("L0\n"); Bye
 Relative ordering of their print statements undefined fork(); L1 Bye
printf("L1\n"); Bye
fork();
void fork1() L0 L1 Bye
{
printf("Bye\n");
int x = 1; }
pid_t pid = fork();
if (pid == 0) {
printf("Child has x = %d\n", ++x);
} else {
printf("Parent has x = %d\n", --x);
}
printf("Bye from process %d with x = %d\n", getpid(), x);
}

23 24
Carnegie Mellon Carnegie Mellon

Fork Example #3 Fork Example #4


 Three consecutive forks  Nested forks in parent
void fork3() Bye void fork4()
{ {
L2 Bye
printf("L0\n"); printf("L0\n");
fork(); Bye if (fork() != 0) {
printf("L1\n"); L1 L2 Bye printf("L1\n"); Bye
fork(); Bye if (fork() != 0) {
printf("L2\n"); L2 Bye printf("L2\n"); Bye
fork(); fork(); Bye
Bye
printf("Bye\n"); } L0 L1 L2 Bye
} L0 L1 L2 Bye }
printf("Bye\n");
}

25 26

Carnegie Mellon Carnegie Mellon

Fork Example #5 exit: Ending a process


 Nested forks in children  void exit(int status)
 exits a process
void fork5()
 Normally return with status 0
{
printf("L0\n");  atexit() registers functions to be executed upon exit
if (fork() == 0) {
printf("L1\n"); Bye
if (fork() == 0) { L2 Bye
void cleanup(void) {
printf("L2\n"); printf("cleaning up\n");
L1 Bye }
fork();
} L0 Bye
} void fork6() {
printf("Bye\n“); atexit(cleanup);
} fork();
exit(0);
}

27 28
Carnegie Mellon Carnegie Mellon

Zombies Zombie void fork7()


{
if (fork() == 0) {
 Idea Example /* Child */
printf("Terminating Child, PID = %d\n",
 When process terminates, still consumes system resources getpid());
exit(0);
 Various tables maintained by OS } else {
 Called a “zombie” linux> ./forks 7 &
printf("Running Parent, PID = %d\n",
getpid());
 Living corpse, half alive and half dead [1] 6639 while (1)
Running Parent, PID = 6639 ; /* Infinite loop */
 Reaping Terminating Child, PID = 6640 }
}
 Performed by parent on terminated child (using wait or waitpid) linux> ps
PID TTY TIME CMD
 Parent is given exit status information 6585 ttyp9 00:00:00 tcsh
 ps shows child process as
 Kernel discards process 6639 ttyp9 00:00:03 forks
6640 ttyp9 00:00:00 forks <defunct> “defunct”
 What if parent doesn’t reap? 6641 ttyp9 00:00:00 ps
linux>
 If any parent terminates without reaping a child, then child will be
reaped by init process (pid == 1)
 So, only need explicit reaping in long‐running processes
 e.g., shells and servers
29 30

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

Carnegie Mellon Carnegie Mellon

wait: Synchronizing with Children wait() Example


 If multiple children completed, will take in arbitrary order
void fork9() {  Can use macros WIFEXITED and WEXITSTATUS to get information about
int child_status;
exit status
if (fork() == 0) {
void fork10()
printf("HC: hello from child\n"); HC Bye {
}
pid_t pid[N];
else {
int i;
printf("HP: hello from parent\n"); HP CT Bye int child_status;
wait(&child_status);
for (i = 0; i < N; i++)
printf("CT: child has terminated\n");
if ((pid[i] = fork()) == 0)
}
exit(100+i); /* Child */
printf("Bye\n");
for (i = 0; i < N; i++) {
exit();
pid_t wpid = wait(&child_status);
}
if (WIFEXITED(child_status))
printf("Child %d terminated with exit status %d\n",
wpid, WEXITSTATUS(child_status));
else
printf("Child %d terminate abnormally\n", wpid);
}
}
35 36
Carnegie Mellon Carnegie Mellon

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

Carnegie Mellon Carnegie Mellon

execve Example Summary


if ((pid = Fork()) == 0) { /* Child runs user job */  Exceptions
if (execve(argv[0], argv, environ) < 0) {
 Events that require nonstandard control flow
printf("%s: Command not found.\n", argv[0]);
 Generated externally (interrupts) or internally (traps and faults)
exit(0);
}
}  Processes
 At any given time, system has multiple active processes
argv[argc] = NULL
 Only one can execute at a time on a single core, though
argv[argc‐1] “/usr/include”
… “-lt”  Each process appears to have total control of
argv[0] “ls” processor + private memory space
argv

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

You might also like