win32 console app catch block not catching the Access Violation exception – Why SEH(Structured Exception Handling) not working in a win32 C++ app

Description

I created a simple win32 console application using visual studio 2008, below is the code

class Person
{
private:
char* m_szFirstName;
char* m_szMiddleInitial;
public:
Person(char* szFirstName, char* szMiddleInitial)

{

m_szFirstName = szFirstName;m_szMiddleInitial = szMiddleInitial

}
char* FirstName(){return m_szFirstName;}
char* MiddleInitial(){return m_szMiddleInitial;}
};

int _tmain(int argc, _TCHAR* argv[])
{
Person* pPerson = new Person(“David”,NULL);
char msg[100];
try
{
sprintf_s(msg,”First Name = %s, Middle Initial = %s\n”, pPerson->FirstName(), pPerson->MiddleInitial());
}
catch(…)
{
sprintf_s(msg,”Exception Occured\n”);
}
printf(msg);
delete pPerson;
printf(“press key to exit”);
char* key;
scanf_s(“%c”, key);
return 0;
}

When I run this app, it crashes with Unhandled Exception – Access Violation, although I do have a catch all exception block – catch(…)

Analysis

I disassembled main function and below is what I noticed

Section .text (0×00401000)
;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
; SYM:wmain <Int>
0×401000: 83EC6C                 SUB         ESP,0x6C           ; <==0×00401207(*+0×207)
0×401003: A100304000         MOV         EAX,DWORD PTR [__security_cookie <UInt>]; (0×403000); .data:0x4E 0xE6 0×40 0xBB
0×401008: 33C4                     XOR         EAX,ESP
0x40100A: 89442468             MOV         DWORD PTR [ESP+0x68],EAX
0x40100E: 56                          PUSH        ESI
0x40100F: 57                          PUSH        EDI
0×401010: 6A08                      PUSH        0×8
0×401012: E88F000000           CALL        __imp_??2@YAPAXI@Z ; (0x4010A6) ; operator new

In case you don’t know the internals of Win32 Structured Exception handling(SEH), please read A Crash Course on the Depths of Win32™ Structured Exception Handling by Matt Pietrek. You will notice the missing instruction to move DWORD pointer from FS:[0x0] register. FS:[0x00] -  4 bytes points to the current Structured Exception Handling (SEH) frame for each thread. Win32 SEH works on a per thread basis with each thread having its own exception handler callback function. On Intel machine, FS register points to the current TEB(Thread Environment Block). That’s why in SEH code, you will have a instruction to move DWORD ptr from FS:[0] register because that’s where you have a pointer to an EXCEPTION_REGISTRATION structure.

Why is it MISSING???

It turns out, visual studio 2008 default settings compiles with “Enable C++ Exception /EHsc” switch which will catch only c++ exceptions also called synchronous exceptions. More information on Exception handling model here http://msdn.microsoft.com/en-us/library/1deeycx5(VS.80).aspx Once you change the compiler switch to /EHa, everything is good as shown below

0×401000: 55                       PUSH        EBP                ; <==0×00401267(*+0×267)
0×401001: 8BEC                   MOV         EBP,ESP
0×401003: 6AFF                   PUSH        0xFF
0×401005: 681B194000       PUSH        __CxxFrameHandler3 + 0x001D; (0x40191B); .text:0x8B 0×54 0×24 0×08
0x40100A: 64A100000000  MOV         EAX,DWORD PTR FS:[0x0]

  • Anonymous says:

    t

    [Reply]

    August 9, 2009 at 4:22 am
  • James Hartley says:

    Thanks for this, a very detailed and helpful response.

    [Reply]

    August 18, 2009 at 2:16 am
  • KenGartner says:

    I am confused about themper-thread nature of the SEH code.

    I write my DLL using /EHa and am loaded dynamically inside an EXE container that was *not* coded to use /EHa. When the container creates a thread (presumably there is no SEH mechanism established) and calls the registered callback offered by my DLL, then my code will run without the benefit of catch(…) working.

    How can I temporarily set the thread handler to my advantage inside my DLL so I get the benefit of catch(…) without disturbing the EXE container. Is there a programmatic way of setting SEH up and later tearing it down?

    Regards,

    Ken Gartner

    [Reply]

    prashant Reply:

    @KenGartner, It depends on where are you trying to use SEH. Is it inside your exe? or is it inside a DLL? For example, once you call LoadLibrary and get the function pointer, You can use catch(..) in that dll and the function, does that make sense?

    [Reply]

    August 18, 2010 at 8:58 pm
  • Janine says:

    If I coummnciaetd I could thank you enough for this, I’d be lying.

    [Reply]

    December 16, 2011 at 3:55 pm

Your email address will not be published. Required fields are marked *

*