Errors and Exception Handling

Download Report

Transcript Errors and Exception Handling

Errors and Exception
Handling
Tim Bisson
Outline for Today

Kernel Development


Userspace C


Debugging, error handling, and virtual machines
Exception handling?
C++ and Exception handling
Kernel Development

Implement abstract functionality to leverage physical
devices



Optimize physical resources (disk, memory, power)
File Systems can optimize I/O access for mechanical
nature of disks
Debugging/developing OS functionality traditionally
involved pressing the power-switch 100s of times
per day

Very time-consuming
Kernel Debugging

Printk - kernel-level printing




Message classification
KERN_DEBUG, KERN_CRIT, KERN_INFO, …
printk(KERN_CRIT “Bug On\n");
Current process usually faults


Drivers are usually the culprit, so process using that driver
dies
If your lucky, the system won’t panic
Kernel Debugging

KDB


Serial Debugging




Run on live system
Two machines: test and development
Communicate over gdb through serial port
Many systems companies have some form of this
infrastructure
Core dumps

Analyze stack trace off-line
Kernel Development with
Virtual Machines

Virtual machines as test systems - when the break,
they don’t panic the host system


Speeds up kernel development





Just reboot the virtual machines (like restarting an app)
Booting is akin to application start-up
Debugging is easier (run debugger on virtual machine)
Useful for networking, fs, etc development
Parallels, Xen
UML

Run Linux Kernel as a process in Linux
Example using UML

UML uses SIGSEGV to fault pages into the
UML kernel

handle SIGSEGV pass nostop noprint

To ignore such signals when debugging a UML
kernel
Why get involved with opensource kernel development

Contribute to an open source kernel project:



Tons of cool projects to work on



Linux, FreeBSD, NetBSD, DragonFlyBSD
“Microsoft isn't evil, they just make really crappy operating
systems.” - Linus Torvalds
http://www.netbsd.org/contrib/projects.html
http://wiki.dragonflybsd.org/index.cgi/ProjectsPage
Looks really good on your resume…

Apply to SoC ‘07 and get paid to work on an open-source
kernel project for the summer
Kernel Error Handling

A difference between application and kernel programming is
error handling

Application segmentation faults are harmless



Kernel faults can often be fatal for the whole system
Drivers are typically responsible for OS failures



Debugger can trace the error to source (gdb)
They run in kernel address space
Their quality is questionable
Core OS subsystems have error handling too
File System Error Handling

Ext4 - new file system for Linux with many new features



Extents allocation, preallocation, defragmentation, etc…
Sets error code numbers: EIO, ENOMEM, ENOSPC
Some error handlers




Ext4_warning()
Ext4-_error()
 Report failure conditions such as inconsistencies or read I/O
failures
Ext4_abort
 unrecoverable failures such as journal I/O or ENOMEM
 Unconditionally force file system into read-only mode or panic
Ext4_decode_error() - errno values and return string
File System Error Handling (2)

ext4_warning()


ext4_orphan_get() - error handling for bad orphan
inodes
ext4_handle_error()


ext4_get_inode_block() - ensure selected block group
< total block groups
ext4_abort()

ext4_journal_start_sb() - journalling aborted
Goto

Goto is also useful for
aggregating error
handling

Free() is only called from
one place
int function() {
int ret_val = -;
char * data = (char * ) malloc (100);
/* do some work */
if (error) {
ret_val = error1;
goto end;
}
/* do some more work */
if (error) {
ret_val = error;
goto end;
}
end:
/* clean up*/
free (data);
return ret_val;
}
Userland C and exception
handling

C doesn’t support exception handling

It supports supports other functionality




Assert
Goto
Signals
Return/reason codes
System Call/Library Errors

When system call or library errors occur, the
errno variable gets set

Take a look at errno.h (“man errno”) for a list
of possible numbers:



EPERM Operation not permitted (POSIX.1)
EIO Input/output error (POSIX.1)
…
Perror()

Prints a message of describing last error that
occurred

Translates errors into human readable format
Example



Why does the program
fail?
#define SIZE 10
int main() {
char buf[SIZE];
int ret, fd;
Read(2) sets errno
value to EBADF
Perror(3) describes
EBADF
ret = read(fd,buf, SIZE);
if (ret != SIZE) {
perror("Read Error");
exit(1);
}
return 0;
}
bisson root # gcc this.c && a.out
Read Error: Bad file descriptor
Signal Handling

The OS delivers an exception in the form of a
software interrupt to an executing process

process must handle event immediately

Signals are defined by a number

Processes may define signal handlers for a
particular signals


Function called when process receives that signal
Asynchronous execution
What good are signals for

Report errors - invalid memory address
reference

Report asynchronous events


Ctrl-c, ctrl-z, fg
Alternative is event polling
Example - srtgen

A synthetic soft real-time
application generator

Use SIGINT (ctrl-c) to
process current frame,
dump stats, then exit

atexit(3) - register a
function to be called at
normal process
termination
Int bool = 0;
void sig_int (int s) {
fprintf(stderr, “CTRL-C detected, aborting after this
frame\n”);
quit = 1;
}
void dumpstats() {
/*prints application statistics*/
….
}
int main (int argc, char **argv) {
signal (SIGINT, sig_int);
atexit(dumpstats);
do {
…
}while(++numsamples < NUMSAMPLES && !quit);
C++ and Exception Handling

Try-Catch-Throw model

Deals with synchronous and asynchronous errors


Synchronous error example - divide by zero
Put code that may generate an exception in a try
block
try {
//code that might throw an exception
}
Throwing an Exception

Indicates an exception occurred




Specify one operand
Exception object, if operand thrown is an object
Exception caught by closest handler from try block in which
exception thrown
Control transferred to handler
if (denominator == 0)
throw DivideByZeroException();

Exception handler need not terminate program, but block where
exception occurred is terminated
Catching an Exception

Exception handlers are the catch block

Caught if argument type matches throw type

If not, terminate (abort) called
catch (DivideByZeroException ex) {
cout << “Exception occurred: “ << ex.what() << endl;
}

Use catch(…) to catch all exceptions
Simple Example
int main () {
char myarray[10];
try {
for (int n=0; n<=10; n++) {
if (n>9) throw "Out of range";
myarray[n]='z';
}
}
catch (char * str) {
cout << "Exception: " << str << endl;
}
return 0;
}
Re-throwing an Exception

Exception handler can handle some of the
exception, then throw it to the calling function

Uses throw;
void throwException() {
try { // Throw an exception and immediately catch it.
cout << "Function throwException\n";
throw exception();
}
catch( exception e ) {
cout << "Exception handled in function throwException\n";
throw; // re-throw exception for further processing
}
cout << “This should not be print\n”; //control never gets here
}
void main( ) {
try {
throwException();
cout << “This should not be print\n”; //exception will be thrown
}
catch ( exception e ) {
cout << "Exception handled in main" << endl;
}
cout << "Program control continues after catch in main" << endl;
}
Output:
Function throwException
Exception handled in function throwException
Exception handled in main
Program control continues after catch in main