From 39ad820bee987fee118cef2282bd88ff96633b41 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 18 Jun 2015 23:57:59 +0200 Subject: [PATCH] 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. --- docs/changes.txt | 1 + include/wx/msw/seh.h | 4 ++-- src/msw/window.cpp | 20 ++++++++++++++++---- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 4079463a44..2696c5b934 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -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). diff --git a/include/wx/msw/seh.h b/include/wx/msw/seh.h index d00efd4962..7c3abba4e4 100644 --- a/include/wx/msw/seh.h +++ b/include/wx/msw/seh.h @@ -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__) diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 85340d781f..a29b0b75bd 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -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; }