Add a test of throwing an exception from wxYield() to except sample.
This demonstrates that under 64 bit Windows exceptions may not propagate through the kernel code and throwing from inside wxYield() results in either an immediate abort, even if the code calling wxYield() tries to handle the exception, or, even more surprisingly, is just completely ignored. See http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/ for more information. Moreover, independently of Windows weirdness, throwing from wxYield() also results in a difficult to debug crash when using wxGTK because C++ exceptions can't propagate through C GTK+ code in this case. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@77465 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -47,6 +47,8 @@
|
||||
#include "wx/thread.h"
|
||||
#endif
|
||||
|
||||
#include "wx/uiaction.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// resources
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -117,6 +119,7 @@ public:
|
||||
void OnThrowString(wxCommandEvent& event);
|
||||
void OnThrowObject(wxCommandEvent& event);
|
||||
void OnThrowUnhandled(wxCommandEvent& event);
|
||||
void OnThrowFromYield(wxCommandEvent& event);
|
||||
|
||||
void OnCrash(wxCommandEvent& event);
|
||||
void OnTrap(wxCommandEvent& event);
|
||||
@@ -187,6 +190,7 @@ enum
|
||||
Except_ThrowString,
|
||||
Except_ThrowObject,
|
||||
Except_ThrowUnhandled,
|
||||
Except_ThrowFromYield,
|
||||
Except_Crash,
|
||||
Except_Trap,
|
||||
#if wxUSE_ON_FATAL_EXCEPTION
|
||||
@@ -217,6 +221,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||
EVT_MENU(Except_ThrowString, MyFrame::OnThrowString)
|
||||
EVT_MENU(Except_ThrowObject, MyFrame::OnThrowObject)
|
||||
EVT_MENU(Except_ThrowUnhandled, MyFrame::OnThrowUnhandled)
|
||||
EVT_MENU(Except_ThrowFromYield, MyFrame::OnThrowFromYield)
|
||||
EVT_MENU(Except_Crash, MyFrame::OnCrash)
|
||||
EVT_MENU(Except_Trap, MyFrame::OnTrap)
|
||||
#if wxUSE_ON_FATAL_EXCEPTION
|
||||
@@ -354,6 +359,8 @@ MyFrame::MyFrame()
|
||||
menuFile->Append(Except_ThrowObject, wxT("Throw an &object\tCtrl-O"));
|
||||
menuFile->Append(Except_ThrowUnhandled,
|
||||
wxT("Throw &unhandled exception\tCtrl-U"));
|
||||
menuFile->Append(Except_ThrowFromYield,
|
||||
wxT("Throw from wx&Yield()\tCtrl-Y"));
|
||||
menuFile->Append(Except_Crash, wxT("&Crash\tCtrl-C"));
|
||||
menuFile->Append(Except_Trap, "&Trap\tCtrl-T",
|
||||
"Break into the debugger (if one is running)");
|
||||
@@ -446,6 +453,29 @@ void MyFrame::OnThrowUnhandled(wxCommandEvent& WXUNUSED(event))
|
||||
throw UnhandledException();
|
||||
}
|
||||
|
||||
void MyFrame::OnThrowFromYield(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
#if wxUSE_UIACTIONSIMULATOR
|
||||
// Simulate selecting the "Throw unhandled" menu item, its handler will be
|
||||
// executed from inside wxYield(), so we may not be able to catch the
|
||||
// exception here under Win64 even in spite of an explicit catch.
|
||||
try
|
||||
{
|
||||
wxUIActionSimulator sim;
|
||||
sim.Char('U', wxMOD_CONTROL);
|
||||
wxYield();
|
||||
}
|
||||
catch ( UnhandledException& )
|
||||
{
|
||||
wxLogMessage("Caught unhandled exception inside wxYield().");
|
||||
}
|
||||
#else // !wxUSE_UIACTIONSIMULATOR
|
||||
wxLogError("Can't trigger an exception inside wxYield() "
|
||||
"without wxUIActionSimulator, please rebuild "
|
||||
"with wxUSE_UIACTIONSIMULATOR=1.");
|
||||
#endif // wxUSE_UIACTIONSIMULATOR/!wxUSE_UIACTIONSIMULATOR
|
||||
}
|
||||
|
||||
void MyFrame::OnCrash(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
DoCrash();
|
||||
|
Reference in New Issue
Block a user