views:

362

answers:

5

What important points about Structured Exceptions should every C++ developer know?

+11  A: 

They should know that they are not part of Standard C++ - they are Microsoft invention and can be used in languages other than C++.

anon
+6  A: 

They are the Win32 equivalent to Unix signals, and let you catch CPU exceptions such as access violation, illegal instruction, divide by zero.

With the right compiler options (/EHa for Visual C++), C++ exceptions use the same mechanism as stack unwinding works properly for both C++ (user) exceptions and SEH (OS) exceptions.

Unlike C++ exceptions, SEH are not typed but all share the same data structure which has an exception code (the cause) and additional information on what code faulted and what the CPU registers held at the time of the fault. See GetExceptionCode and GetExceptionInformation for more details on this.

Also, SEH has "first-chance" handling, which allows you to log or otherwise handle the exception before unwinding destroys all the local variables.

Ben Voigt
Note though that the default was changed away from handling SEH exceptions like C++ exceptions because SEH exceptions are not safe to handle like C++ exceptions. SEH exceptions are usually things like access violations, and attempting to do C++ unwinding under such conditions is not possible and can cause the program to terminate.
Billy ONeal
There's nothing inherently unsafe about unwinding an access violation. Of course, if the access violation was caused by corruption of internal data structures (especially stack overflows which affect the call stack information) then unwinding is likely to fail, but many, if not the majority, of SEH exceptions don't actually reflect stack corruption.
Ben Voigt
+5  A: 

There is nothing about them them every C++ programmer really needs to know. They're specific to Windows, so programmers who don't work on Windows don't normally need to know anything about them unless they're porting code from Windows that uses them.

People who do program on Windows should probably know that their capabilities are almost entirely different from the capabilities of C++ exception handling. Where C++ exceptions are (should be) used only in truly unusual or unexpected circumstances, structured exceptions are often used to deal with situations that are quite common and expected.

They should probably also know that structure exception handling is obsolescent -- unless you need to work with older versions of Windows (i.e., prior to XP), you normally want to use Vectored Exception Handling instead (although vectored exception handling is pretty much a superset of SEH, so it's not like you'd ignore SEH, but that you should be aware of the capabilities of VEH that aren't provided by SEH).

Jerry Coffin
Structured exceptions are common/expected? I think you might have that backward.
Ben Voigt
Yes, structured exceptions are common and expected. Just for example, any time you access memory that's not present (i.e., has been paged out) there's a structured exception that's handled by paging the data back in.
Jerry Coffin
@Jerry: page faults are not serviced by SEH. page faults are handled in the kernel, the only time process mode SEH would see a page fault would be if a protected page or unallocated VA address is touched, ie. when the kernel decide to raise an exception in the process.
Remus Rusanu
@Remus: Sorry, but you're simply wrong. Just for example, it's quite normal to see first-chance exceptions when you run a program under the debugger. Jeffrey Richter long ago demonstrated handling virtual allocation yourself via SEH -- a search for vmalloc.c should turn up example source code.
Jerry Coffin
I'm pretty sure he was handling AVs (http://en.wikipedia.org/wiki/General_protection_fault), not page faults (http://en.wikipedia.org/wiki/Translation_lookaside_buffer#Miss). A page fault, even a hard one (paging in the content from disk), is invisible to the process, SEH never sees it.
Remus Rusanu
@Remus: I apologize -- you're right. Normal page faults don't go through SEH. Nonetheless, the point I was trying to make, that it's fairly routine to see structured exceptions handled and raised remains correct.
Jerry Coffin
Stack page guards trigger SE's, though. This makes it possible for user-space code to break the stack.
MSalters
+3  A: 

A Crash Course on the Depths of Win32™ Structured Exception Handling

That article is the reference on getting up to speed with SEH. 13 years later, is still the best there is.

There is a dedicated topic on MSDN for SEH vs. C++ Exception Handling Differences.

Some things a C++ developer should know if SEH is being discussed:

Writing C/C++ SEH Exception Handlers:

__try 
{
   // guarded code
}
__except ( expression )
{
   // exception handler code
}

This is not C++ exception handling, is the MS specific extensions for hooking straight inot SEH. It works very differently from your run-of-the-mill C++ exceptions. You need a good understanding of SEH to use these.

Writing C/C++ SEH Termination Handlers:

__try {
   // guarded code
}
__finally ( expression ) {
   // termination code
}

Same as with the SEH handler, do not confuse this with C++ exception semantics. You need a good understanding of SEH.

_set_se_trasnlator: this is the function that translates SEH exceptions into C++ type exceptions when asynchronous exceptions are used /EHa.

And finally, a personal opinion: should a C++ developer know SEH? After your first rookie .ecxr you'll understand that when the push come to shove C++ exceptions are just an illusion provided for your convenience. The only thing going on is SEH.

Remus Rusanu
A: 

Although this question is from 5 months ago, I recently had a problem which was caused indirectly by SEH, specifically because of one feature of SEH which I think every developer should be aware of:

When SEH is used destructors are not called, so if you have cleanup code in your destructor it will not be cleaned up.

Our problem was caused by a Critical Section that was wrapped by an object with Lock in the constructor and Unlock in the destructor.

We had a deadlock situation and couldn't figure out why, and after about a week of digging through the code and dumps and debugging we finally understood it was because there was an exception that was handled by COM and causing the Critical section to stay locked. We changed a compilation flag in VS in the project properties which tell it to run destructors even for SEH and that solved the problem.

So even though you may not use SEH in your code, you may be using a library that does (like COM) and that can cause unexpected behaviour.

Tidhar