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]
James Hartley says:
Thanks for this, a very detailed and helpful response.
[Reply]
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:
August 24th, 2010 at 12:06 am
@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]