Your New Jekyll Site

home

From Exception to Crash

09 May 2011

What happens when my application crashes?

How does a division by zero or null pointer reference get translated into a dialog box?

Hardware faults

There are certain kinds of faults that can happen at the lowest machine level, e.g. division by zero, writing to protected memory, referencing non-existing memory, or simply executing machine code instructions that are not part of the valid instruction set.

When this happens an interrupt or exception occurs.

The correct response by the CPU is defined by a preconfigured list of subroutines. This table of routines which maps a certain event/exception to a response is called the Interrupt Descriptor Table (IDT). It is triggered by hardware interrupts, software interrupts, and processor exceptions.

Interrupt Description 
0x00 Division by zero 
0x01 Debugger 
0x02 NMI 
0x03 Breakpoint 
0x04 Overflow 
0x05 Bounds 
0x06 Invalid OP code 
0x07 Coprocessor not available 
0x08 Double fault 
0x09 Coprocessor Segment Overrun (386 or earlier only) 
0x0A Invalid Task State Segment 
0x0B Segment not present 
0x0C Stack Fault 
0x0D General Protection 
0x0E Page Fault 
0x0F reserved 
0x10 Math Fault 
0x11 Alignment Check 
0x12 Machine Check 
0x13 SIMD Floating-Point Exception

Raise Exception

Depending on the configuration a certain error can be ignored or handled. A page fault is generally considered a very bad thing and is escalated with a call to RaiseException to operating system level. At this point the OS can package the exception in a struct or class, and forward it to the process. Low-level exceptions are called Windows Structured Exception Handling (SEH). Other types or errors/exceptions can be communicated back with error codes.

Structured Exception Handlers

Below is a C++ example of SEH.

__try
{
   int result = 4 / 0;
}
__except (filter(GetExceptionCode(), GetExceptionInformation())
{
   // Error Handling
}

Other Exception Handlers

Most programming languages has their own language runtime.

In the C++ runtime, the C++ Exception handling is implemented. It is a construct to handle exceptions in the control flow. You generally test for some value, if it is not the expected, you throw an exception, which jumps back in the call stack until someone catches it. At this level you can display an error to the user, and continue the execution from a safe point.

try
{
   throw new MyCustomException();
}
catch (MyCustomException e)
{

}

First chance Exceptions

When debugging you can sometimes hear of first chance exceptions and second chance exceptions. First chance exceptions are triggered before any exception handling code. If you have a debugger attached to your process, it will stop here.

Absence of Exception Handlers

An exception, will travel back in the call stack until it is caught by an exception handler, in case it is not caught a second chance exception will occur. A debugger will catch a second chance exception, and break the execution.

In case no debugger is attached, the operating system catches the exception. The default behavior is to terminate the application displaying a crash dialog box to the user.

Image of windbg

But this can be altered by a registry tweak.

On my own machine I automatically take a memory dump of the crashing process.