Check for Win32 exceptions inside our WindowProc().

Don't let unhandled Win32 (i.e. structured) exceptions escape from wxWndProc()
as they can just disappear into thin air when running under WOW64 as 32 bit
exceptions can't propagate through 64 bit kernel. So catch them immediately
and pass them to the global handler while we have the chance to do it, as
we're never going to get it in the outer __try/__catch block in wxEntry() in
src/msw/main.cpp.

In particular, this allows to catch crashes in wxEVT_PAINT handlers, such as
the one in debughlp sample, again.

Closes #16656.
This commit is contained in:
Vadim Zeitlin 2015-06-18 23:57:59 +02:00
parent 6ae8145e9d
commit 39ad820bee
3 changed files with 19 additions and 6 deletions

View File

@ -133,6 +133,7 @@ wxMSW:
- Make default wxSizer border DPI-aware.
- Improve wxMimeTypesManager open command detection (Eric Jensen).
- Make wxFILTER_INCLUDE_LIST in wxTextValidator actually usable.
- Fix handling crashes in wxEVT_PAINT event handlers.
- Fix appearance of toggled wxToggleButtons with bitmap (tm).
- Fix setting menu item bitmaps after appending them (Artur Wieczorek).
- Fix setting label of submenu items (Artur Wieczorek).

View File

@ -14,8 +14,8 @@
// the exception handler which should be called from the exception filter
//
// it calsl wxApp::OnFatalException() if possible
extern unsigned long wxGlobalSEHandler(EXCEPTION_POINTERS *pExcPtrs);
// it calls wxApp::OnFatalException() if wxTheApp object exists
WXDLLIMPEXP_BASE unsigned long wxGlobalSEHandler(EXCEPTION_POINTERS *pExcPtrs);
// helper macro for wxSEH_HANDLE
#if defined(__BORLANDC__)

View File

@ -82,6 +82,7 @@
#include "wx/msw/private.h"
#include "wx/msw/private/keyboard.h"
#include "wx/msw/dcclient.h"
#include "wx/msw/seh.h"
#include "wx/private/textmeasure.h"
#if wxUSE_TOOLTIPS
@ -2757,10 +2758,21 @@ wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT rc;
if ( wnd && wxGUIEventLoop::AllowProcessing(wnd) )
rc = wnd->MSWWindowProc(message, wParam, lParam);
else
rc = ::DefWindowProc(hWnd, message, wParam, lParam);
// We have to catch unhandled Win32 exceptions here because otherwise they
// would be simply lost if we're called from a kernel callback (as it
// happens when we process WM_PAINT, for example under WOW64: the 32 bit
// exceptions can't pass through the 64 bit kernel in this case and so are
// mostly just suppressed, although the exact behaviour differs across
// Windows versions, see the "Remarks" section of WindowProc documentation
// at https://msdn.microsoft.com/en-us/library/ms633573.aspx
wxSEH_TRY
{
if ( wnd && wxGUIEventLoop::AllowProcessing(wnd) )
rc = wnd->MSWWindowProc(message, wParam, lParam);
else
rc = ::DefWindowProc(hWnd, message, wParam, lParam);
}
wxSEH_HANDLE(0)
return rc;
}