Errors and Exception Handling Tim Bisson. Outline for Today Kernel Development Debugging, error...

Post on 16-Dec-2015

240 views 1 download

Tags:

Transcript of Errors and Exception Handling Tim Bisson. Outline for Today Kernel Development Debugging, error...

Errors and Exception Handling

Tim Bisson

Outline for Today

Kernel Development Debugging, error handling, and virtual machines

Userspace C 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 Run on live system

Serial Debugging 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 Just reboot the virtual machines (like restarting an app)

Speeds up kernel development 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 open-source kernel development

Contribute to an open source kernel project: Linux, FreeBSD, NetBSD, DragonFlyBSD “Microsoft isn't evil, they just make really crappy operating

systems.” - Linus Torvalds

Tons of cool projects to work on 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

Debugger can trace the error to source (gdb) Kernel faults can often be fatal for the whole system

Drivers are typically responsible for OS failures 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#define SIZE 10

int main() { char buf[SIZE]; int ret, fd;

ret = read(fd,buf, SIZE); if (ret != SIZE) { perror("Read Error"); exit(1); } return 0;}

bisson root # gcc this.c && a.outRead Error: Bad file descriptor

Why does the program fail?

Read(2) sets errno value to EBADF

Perror(3) describes EBADF

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