<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>jaredpar's WebLog : SEH</title><link>http://blogs.msdn.com/jaredpar/archive/tags/SEH/default.aspx</link><description>Tags: SEH</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Mixing SEH and C++ Exceptions</title><link>http://blogs.msdn.com/jaredpar/archive/2008/01/11/mixing-seh-and-c-exceptions.aspx</link><pubDate>Sat, 12 Jan 2008 01:18:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7080240</guid><dc:creator>Jared Parsons</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/jaredpar/comments/7080240.aspx</comments><wfw:commentRss>http://blogs.msdn.com/jaredpar/commentrss.aspx?PostID=7080240</wfw:commentRss><wfw:comment>http://blogs.msdn.com/jaredpar/rsscomments.aspx?PostID=7080240</wfw:comment><description>&lt;p&gt;Recently I had a half day adventure trying to catch a SafeIntException in code I was writing.&amp;nbsp; The particular function involved a bit of math with user controlled values.&amp;nbsp; Writing a bunch of IfFailGo's with several TryAdd style API's was getting tiresome so I decided to just use SafeInt, catch an overflow and return a failure code.&amp;nbsp; &lt;/p&gt; &lt;p&gt;After recompiling the code I got an error because I hadn't enabled C++ exception handling in the project.&amp;nbsp; Fix to support synchronous exceptions (/Ehs), recompile.&amp;nbsp; Now I get a different error because a portion of the code base is using SEH exception handling.&amp;nbsp; No problem, changed the project to support asynchronous exception handling as well (/Eha).&amp;nbsp; And yet again another error, the compiler now said that I could not use variables with a destructor in the same method that had an SEH try block.&amp;nbsp; &lt;/p&gt; &lt;p&gt;This put me in a bit of a corner.&amp;nbsp; The code base is littered with SEH exception handling and much of it is perfectly valid.&amp;nbsp; Luckily the number of places using both SEH and destructors was fairly limited.&amp;nbsp; What I needed was a way to unify the exception handling to allow me to use destructors in the same place as SEH exceptions.&lt;/p&gt; &lt;p&gt;With /Eha there is a built-in way.&amp;nbsp; You can catch all SEH exceptions using the C++ syntax "catch (...)".&amp;nbsp; However this method is limiting because you cannot access the SEH exception code and you get notified after the stack unwind occurs.&amp;nbsp; In SEH an exception filter is run before a stack unwind occurs which makes it infinitely easier to track down your bugs as you can just look down the stack trace and see the line of code that faulted.&lt;/p&gt; &lt;p&gt;After a bit of research I found a solution.&amp;nbsp; I'm chose to blog about it because many of the questions I needed answers for were either 1) undocumented or 2) documented to vaguely.&amp;nbsp; In the end I setup some experiment projects to confirm the behaviors I expected.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The magic function I was looking for was &lt;a href="http://msdn2.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx"&gt;_set_se_translator&lt;/a&gt;.&amp;nbsp; It takes a function pointer as an argument and returns the previous value.&amp;nbsp; The documentation states that when a C/SEH exception is raised this function pointer is called once per function that has a C++ try block.&amp;nbsp; It can be used to throw a C++ exception in place of a SEH exception.&amp;nbsp; So you can now translate a SEH exception into a C++ one.&lt;/p&gt; &lt;p&gt;What the documentation didn't explain (and I was very curious about) is how this interweaves with existing SEH __try/__except/__finally blocks.&amp;nbsp; After some experimentation I discovered that it works extremely well.&amp;nbsp; SEH exceptions occur in two phases&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Process the exception filters until either EXCEPTION_EXECUTE_HANDLER or EXCEPTION_CONTINUE_EXECUTION is returned&lt;/li&gt; &lt;li&gt;If EXECEPTION_EXECUTE_HANDLER is returned the stack is unwound to the point of the exception handler block and it is then executed.&amp;nbsp; &lt;/li&gt;&lt;/ol&gt; &lt;p&gt;The value passed to &lt;a href="http://msdn2.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx"&gt;_set_se_translator&lt;/a&gt; participates in phase 1 of the process.&amp;nbsp; As the CRT is looking down the stack for a SEH exception filter, if it finds a C++ try block it will also process the last value passed to &lt;a href="http://msdn2.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx"&gt;_set_se_translator&lt;/a&gt; and allow it to throw a C++ exception.&amp;nbsp; If an exception is thrown the stack is unwound to that point and then the exception is thrown.&amp;nbsp; This means that if you call into other code which uses traditional SEH handlers they will operate just as they did before you started using &lt;a href="http://msdn2.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx"&gt;_set_se_translator&lt;/a&gt;.&amp;nbsp; Most importantly __finally blocks will run and __except blocks above you in the stack still process and can handle SEH exceptions.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The next step was to write an easy to use wrapper for this functionality.&amp;nbsp; I used two classes to implement this approach.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The first class is designed to properly install a translator at a given point in the stack and ensure that it is reset to the previous value when that stack frame is popped off.&amp;nbsp; &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;extern&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; SehTranslatorFunction(&lt;span style="color: rgb(0,0,255)"&gt;unsigned&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt;, &lt;span style="color: rgb(0,0,255)"&gt;struct&lt;/span&gt; _EXCEPTION_POINTERS*);

&lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; SehGuard
{
&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt;:
    SehGuard()
    {
        m_prev = _set_se_translator(SehTranslatorFunction);
    }

    ~SehGuard()
    {
        _set_se_translator(m_prev);
    }

&lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt;:
    _se_translator_function m_prev;
};&lt;/pre&gt;
&lt;p&gt;The second part is to actually throw an exception inside of SehTranslatorFunction.&amp;nbsp; Also to add an assert so that when an SEH exception is produced I can break at the point of failure (as opposed to in the catch block where the stack will be unwound. &lt;/p&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;class&lt;/span&gt; SehException
{
&lt;span style="color: rgb(0,0,255)"&gt;public&lt;/span&gt;:
    SehException(&lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; code) : m_code(code) { }
&lt;span style="color: rgb(0,0,255)"&gt;private&lt;/span&gt;:
    &lt;span style="color: rgb(0,0,255)"&gt;unsigned&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; m_code;
};&lt;/pre&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;pre class="code"&gt;&lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; SehTranslatorFunction(&lt;span style="color: rgb(0,0,255)"&gt;unsigned&lt;/span&gt; &lt;span style="color: rgb(0,0,255)"&gt;int&lt;/span&gt; code, &lt;span style="color: rgb(0,0,255)"&gt;struct&lt;/span&gt; _EXCEPTION_POINTERS*)
{
    MyAssertFunction(&lt;span style="color: rgb(0,0,255)"&gt;false&lt;/span&gt;,&lt;span style="color: rgb(163,21,21)"&gt;"Caught an SEH exception"&lt;/span&gt;);
    &lt;span style="color: rgb(0,0,255)"&gt;throw&lt;/span&gt; SehException(code);
}&lt;/pre&gt;Now whenever I hit a point where I want to guard against SEH exceptions, I just put and instance of SehGuard on the stack and catch SehException instances.&amp;nbsp; No traditional SEH needed.&amp;nbsp; &lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7080240" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/jaredpar/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://blogs.msdn.com/jaredpar/archive/tags/SEH/default.aspx">SEH</category></item></channel></rss>