1 / 13

Win32 Programming

Win32 Programming. Lesson 23: SEH That’s right… you’ll never generate an exception, will you?. Where are we?. Looked at DLLs and their many facets But we’re not very good at handling errors yet… how does Windows do it?. Imagine. Your code will never generate an error

Download Presentation

Win32 Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Win32 Programming Lesson 23: SEH That’s right… you’ll never generate an exception, will you?

  2. Where are we? • Looked at DLLs and their many facets • But we’re not very good at handling errors yet… how does Windows do it?

  3. Imagine • Your code will never generate an error • (Try really hard )

  4. SEH • “Structured Exception Handling” • Basically, lets you assume the code is “good” and deal with the errors later • Very similar to the Java/C++ exception handling mechanism but different – don’t confuse the two • Mostly handled by the Compiler not the OS – special code is written to the application

  5. So… • Introducing the Termination Handler • Guarantees that a particular block of code will be executed regardless of what happens above it • __try { // Guarded Body …} __finally { // Termination Handler …}

  6. Example • DWORD Funcenstein1() {    DWORD dwTemp;    // 1. Do any processing here.  __try {       // 2. Request permission to access       //    protected data, and then use it.       WaitForSingleObject(g_hSem, INFINITE);       g_dwProtectedData = 5;       dwTemp = g_dwProtectedData;    } __finally {       // 3. Allow others to use protected data.       ReleaseSemaphore(g_hSem, 1, NULL);    }    // 4. Continue processing.    return(dwTemp);}

  7. But… • DWORD Funcenstein1() {    DWORD dwTemp;    // 1. Do any processing here.  __try {       // 2. Request permission to access       //    protected data, and then use it.       WaitForSingleObject(g_hSem, INFINITE);       g_dwProtectedData = 5;       dwTemp = g_dwProtectedData;// Return the new value.       return(dwTemp);    } __finally {       // 3. Allow others to use protected data.       ReleaseSemaphore(g_hSem, 1, NULL);    }    // 4. Continue processing.dwTemp = 9;    return(dwTemp);}

  8. The Problem • Jumping from the __try to the __finally can be expensive in terms of CPU time • Called a local unwind

  9. A Better Example • DWORD Funcfurter1() {    DWORD dwTemp;    // 1. Do any processing here.    __try {        // 2. Request permission to access       //    protected data, and then use it.       WaitForSingleObject(g_hSem, INFINITE);       dwTemp = Funcinator(g_dwProtectedData);    } __finally {       // 3. Allow others to use protected data.       ReleaseSemaphore(g_hSem, 1, NULL);    }    // 4. Continue processing.    return(dwTemp); } • What if Funcinator throws an access violation?

  10. Quiz: What’s the output? • DWORD FuncaDoodleDoo() {    DWORD dwTemp = 0;    while (dwTemp < 10) {       _ _try {           if (dwTemp == 2)             continue;          if (dwTemp == 3)             break;       }       _ _finally {          dwTemp++;       }       dwTemp++;    }    dwTemp += 10;    return(dwTemp); }

  11. And Another… • DWORD Funcenstein4() {    DWORD dwTemp;    // 1. Do any processing here.    _ _try {       // 2. Request permission to access       //    protected data, and then use it.       WaitForSingleObject(g_hSem, INFINITE);       g_dwProtectedData = 5;       dwTemp = g_dwProtectedData;       // Return the new value.       return(dwTemp);    }  _ _finally {       // 3. Allow others to use protected data.       ReleaseSemaphore(g_hSem, 1, NULL);       return(103);    }   dwTemp = 9;    return(dwTemp); }

  12. Better Approach: __leave • Think of __leave as a normal exit that runs normally into __finally • This dramatically saves time and simplifies coding • However, it does complicate your code a little bit

  13. But we’re still not done • Can see in the __finally block why we got there… • BOOL AbnormalTermination();

More Related