Win32 Programming

Download Report

Transcript Win32 Programming

Win32 Programming
Lesson 24: More SEH
That’s right… you’ll never generate an exception, will you?
Where are we?


Looked at __finally blocks…
But you can also deal with the exception
using __except
Basic structure


__try {
//code
} __except {
//exception handler
}
Note: you can’t have __except and __finally
in the same __try block
Example

DWORD Funcmeister1() {
DWORD dwTemp;
// 1. Do any processing here.
_ try {
// 2. Perform some operation.
dwTemp = 0;
} except (EXCEPTION_EXECUTE_HANDLER) {
// Handle an exception; this never executes.
}
// 3. Continue processing.
return(dwTemp);
}
Better Example

DWORD Funcmeister2() {
DWORD dwTemp = 0;
// 1. Do any processing here.
__try {
// 2. Perform some operation(s).
dwTemp = 5 / dwTemp;
// Generates an exception
dwTemp += 10;
// Never executes
} __except (EXCEPTION_EXECUTE_HANDLER) {
// 4. Handle an exception.
MessageBeep(0);
}
// 5. Continue processing.
return(dwTemp);
}
Example

See what was new?

__except (*) where * ==



EXCEPTION_EXECUTE_HANDLER
EXCEPTION_CONTINUE_SEARCH
EXCEPTION_CONTINUE_EXECUTION
EXCEPTION_EXECUTE_HANDLER





Execute the __except block and continue after it
Very useful for getting yourself out of trouble…
char* RobustStrCpy(
char* strDestination,
const char* strSource
) {
__try {
strcpy(strDestination, strSource);
} __except (EXCEPTION_EXECUTE_HANDLER) {
// Nothing to do here
}
return(strDestination);
}
Never causes the program to exit
However, does cause a global unwind…
Global Unwind?


Essentially, the computer has to unwind _try
blocks (because the __finally clauses have to
be executed) until it gets to the handling
__except block
That’s expensive in terms of CPU cycles
Odd Errors


Of course,
EXCEPTION_CONTINUE_EXECUTION can
cause strange errors
Imagine:




*buf = ‘R’
Assembles as: mov eax, [buf];
mov [eax], ‘R’
When we continue after fixing the error, what happens
depends on the target CPU and the compiler optimizations
BE WARNED!
EXECUTE_CONTINUE_SEARCH



Go up to the previous __except block and use
that exception handler…
But doesn’t call __finally blocks
This can make code hard to follow (remember
our example from last week?)
And Another…
Deciding what to do




As we saw in the previous example, we can
decide what to do in the __except () block
with a function
Sometimes we want to know what type of
exception occurred
Done with DWORD GetExceptionCode
Values defined in winbase.h
So…

_ _try {
x = 0;
y = 4 / x;
} _
_except ((GetExceptionCode() ==
EXCEPTION_INT_DIVIDE_BY_ZERO) ?
EXCEPTION_EXECUTE_HANDLER :
EXCEPTION_CONTINUE_SEARCH)
{
// Handle divide by zero.
}
Under The Hood

When an exception occurs, the OS pushes
three structures to the calling thread’s stack




EXCEPTION_RECORD
CONTEXT
EXCEPTION_POINTERS
Can access via

PEXECEPTION_POINTERS
GetExceptionInformation()
Finally…


(Or do I mean __finally?)
Remind me what happens inside the kernel
when we start a process?
ThreadStart/ProcStart




The primary thread (and subsequent threads)
are wrapped in a __try __except block
It’s this block which ultimately cancels the
process/thread
I’m sure you’ve all seen the box
Now you know where it comes from!
Assignment


No assignment today…
Lucky ewe…