Win32 Programming

Document Sample
Win32 Programming Powered By Docstoc
					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.
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…

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:0
posted:3/18/2013
language:English
pages:17