Win32 Programming Lesson 24: More SEH That’s right… you’ll never generate an exception, will...
-
Upload
cathleen-ryan -
Category
Documents
-
view
212 -
download
0
Transcript of Win32 Programming Lesson 24: More SEH That’s right… you’ll never generate an exception, will...
Win32 ProgrammingLesson 24: More SEHThat’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…