The wxWidgets sample crashes because it tries to throw the exception through the Windows runtime from a callback to the wxWidgets event handler. This is not supported with DW2 exception unwinding. Your test case doesn't throw through a Windows callback, which is why it works as it should under mingw-builds and MinGW.org; it exhibits a bug specific to TDM-GCC.
-John E. / TDM
Thanks, I know that exception can not propagate through a non-mingw build frame, but what the wxWidgets' except sample do is:
1, write a overload function the MyFrame::ProcessEvent, and write a try block there:
bool MyFrame::ProcessEvent(wxEvent& event)
{
try
{
return wxFrame::ProcessEvent(event);
}
catch ( const wxChar *msg )
{
wxLogMessage(_T("Caught a string \"%s\" in MyFrame"), msg);
return true;
}
}
2, I think all the function up to the MyFrame::ProcessEvent is all build from the same MinGW compiler, see the call stack:
[debug]#18 0x0040233b in MyFrame::OnThrowInt (this=0xb25cd0) at D:\exception\aaa\aaaMain.cpp:417
[debug]#19 0x627015f1 in wxAppConsole::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const () from E:\code\wx\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#20 0x6276a07e in wxEvtHandler::ProcessEventIfMatches(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) () from E:\code\wx\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#21 0x6276a14a in wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*) () from E:\code\wx\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#22 0x6276a545 in wxEvtHandler::ProcessEvent(wxEvent&) () from E:\code\wx\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#23 0x004021dc in MyFrame::ProcessEvent (this=0xb25cd0, event=...) at D:\exception\aaa\aaaMain.cpp:382
[debug]#24 0x62804dc7 in wxFrameBase::ProcessCommand(int) () from E:\code\wx\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#25 0x627b9d64 in wxFrame::HandleCommand(unsigned short, unsigned short, void*) () from E:\code\wx\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#26 0x627ba173 in wxFrame::MSWWindowProc(unsigned int, unsigned int, long) () from E:\code\wx\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#27 0x627a0cee in wxWndProc(HWND__*, unsigned int, unsigned int, long)@16 () from E:\code\wx\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#28 0x7e418734 in USER32!GetDC () from C:\WINDOWS\system32\user32.dll
[debug]#29 0x000a0528 in ?? ()
You see, the call back is infact the function wxWndProc (#27), and in #23 0x004021dc in MyFrame::ProcessEvent, there is a try catch block. So, I think there is not chance that the exception will go up to the Windows call back function, which is #27 0x627a0cee in wxWndProc.
Am I right?
EDIT: the code below works correctly, my question is: it looks like exception can not propagate up cross the event handler function.void f()
{
throw 1;
}
void MyFrame::OnThrowInt(wxCommandEvent& WXUNUSED(event))
{
//throw -17;
try
{
f();
}
catch ( int i )
{
wxLogWarning(_T("Caught an int %d in MyApp."), i);
}
}
EDIT2@John, you are right. I have a mistake, because the original try catch block
can not catch int type.
bool MyFrame::ProcessEvent(wxEvent& event)
{
try
{
return wxFrame::ProcessEvent(event);
}
catch ( const wxChar *msg )
{
wxLogMessage(_T("Caught a string \"%s\" in MyFrame"), msg);
return true;
}
}
If I add one catch clause (catch ( int i )) here
bool MyFrame::ProcessEvent(wxEvent& event)
{
try
{
return wxFrame::ProcessEvent(event);
}
catch ( int i )
{
wxLogWarning(_T("Caught an int %d in MyFrame."), i);
return true;
}
catch ( const wxChar *msg )
{
wxLogMessage(_T("Caught a string \"%s\" in MyFrame"), msg);
return true;
}
}
then I can correctly catch this int type exception.
I see that the except sample code do have another level of try/catch block in the app level.
bool MyApp::OnExceptionInMainLoop()
{
try
{
throw;
}
catch ( int i )
{
wxLogWarning(_T("Caught an int %d in MyApp."), i);
}
catch ( MyException& e )
{
wxLogWarning(_T("Caught MyException(%s) in MyApp."), e.what());
}
catch ( ... )
{
throw;
}
return true;
}
This try block is far up in the call stack train (cross the Windows call back function call), so exception(build with gcc-dw2) can not go there.
Sorry about the noise.