From 39ea2103cdaadd61974b9746cac2315183ef6720 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 26 Apr 2006 18:04:15 +0000 Subject: [PATCH] handle fatal exceptions in the other threads (based on patch 1459813 by Carl-Friedrich Braun) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38929 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- build/bakefiles/files.bkl | 1 + include/wx/msw/seh.h | 74 +++++++++++++++++++++++++++++++++++++++ src/msw/main.cpp | 29 ++++----------- src/msw/window.cpp | 2 +- 4 files changed, 82 insertions(+), 24 deletions(-) create mode 100644 include/wx/msw/seh.h diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index f0e81c39f4..30d4d975e5 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -119,6 +119,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/msw/private.h wx/msw/regconf.h wx/msw/registry.h + wx/msw/seh.h wx/msw/stackwalk.h wx/msw/stdpaths.h wx/msw/winundef.h diff --git a/include/wx/msw/seh.h b/include/wx/msw/seh.h new file mode 100644 index 0000000000..b9d26b7b67 --- /dev/null +++ b/include/wx/msw/seh.h @@ -0,0 +1,74 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/msw/seh.h +// Purpose: declarations for SEH (structured exceptions handling) support +// Author: Vadim Zeitlin +// Created: 2006-04-26 +// RCS-ID: $Id$ +// Copyright: (c) 2006 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MSW_SEH_H_ +#define _WX_MSW_SEH_H_ + +#if wxUSE_ON_FATAL_EXCEPTION + + // the exception handler which should be called from the exception filter + // + // it calsl wxApp::OnFatalException() if possible + extern unsigned long wxGlobalSEHandler(EXCEPTION_POINTERS *pExcPtrs); + + // helper macro for wxSEH_HANDLE +#if defined(__VISUALC__) && (__VISUALC__ <= 1200) + // some compilers don't understand that this code is unreachable and warn + // about no value being returned from the function without it, so calm them + // down + #define wxSEH_DUMMY_RETURN(rc) return rc; +#else + #define wxSEH_DUMMY_RETURN(rc) +#endif + + // macros which allow to avoid many #if wxUSE_ON_FATAL_EXCEPTION in the code + // which uses them + #define wxSEH_TRY __try + #define wxSEH_IGNORE __except ( EXCEPTION_EXECUTE_HANDLER ) { } + #define wxSEH_HANDLE(rc) \ + __except ( wxGlobalSEHandler(GetExceptionInformation()) ) \ + { \ + /* use the same exit code as abort() */ \ + ::ExitProcess(3); \ + \ + wxSEH_DUMMY_RETURN(rc) \ + } + +#else // wxUSE_ON_FATAL_EXCEPTION + #define wxSEH_TRY + #define wxSEH_IGNORE + #define wxSEH_HANDLE(rc) +#endif // wxUSE_ON_FATAL_EXCEPTION + +#if defined(__VISUALC__) && !defined(__WXWINCE__) + #include + + // C++ exception to structured exceptions translator: we need it in order + // to prevent VC++ from "helpfully" translating structured exceptions (such + // as division by 0 or access violation) to C++ pseudo-exceptions + extern void wxSETranslator(unsigned int code, EXCEPTION_POINTERS *ep); + + // up to VC 7.1 this warning ("calling _set_se_translator() requires /EHa") + // is harmless and it's easier to suppress it than use different makefiles + // for VC5 and 6 (which don't support /EHa at all) and VC7 (which does + // accept it but it seems to change nothing for it anyhow) + #if __VISUALC__ <= 1310 + #pragma warning(disable: 4535) + #endif + + // note that the SE translator must be called wxSETranslator! + #define DisableAutomaticSETranslator() _set_se_translator(wxSETranslator) +#else // !__VISUALC__ + // the other compilers do nothing as stupid by default so nothing to do for + // them + #define DisableAutomaticSETranslator() +#endif // __VISUALC__/!__VISUALC__ + +#endif // _WX_MSW_SEH_H_ diff --git a/src/msw/main.cpp b/src/msw/main.cpp index 712dc72347..c86c0909eb 100644 --- a/src/msw/main.cpp +++ b/src/msw/main.cpp @@ -30,14 +30,11 @@ #include "wx/scopeguard.h" #include "wx/msw/private.h" +#include "wx/msw/seh.h" #if wxUSE_ON_FATAL_EXCEPTION #include "wx/datetime.h" #include "wx/msw/crashrpt.h" - - #ifdef __VISUALC__ - #include - #endif // __VISUALC__ #endif // wxUSE_ON_FATAL_EXCEPTION #ifdef __WXWINCE__ @@ -118,16 +115,11 @@ unsigned long wxGlobalSEHandler(EXCEPTION_POINTERS *pExcPtrs) wxGlobalSEInformation = pExcPtrs; // give the user a chance to do something special about this - __try + wxSEH_TRY { wxTheApp->OnFatalException(); } - __except ( EXCEPTION_EXECUTE_HANDLER ) - { - // nothing to do here, just ignore the exception inside the - // exception handler - ; - } + wxSEH_IGNORE // ignore any exceptions inside the exception handler wxGlobalSEInformation = NULL; @@ -140,7 +132,7 @@ unsigned long wxGlobalSEHandler(EXCEPTION_POINTERS *pExcPtrs) #ifdef __VISUALC__ -static void wxSETranslator(unsigned int WXUNUSED(code), EXCEPTION_POINTERS *ep) +void wxSETranslator(unsigned int WXUNUSED(code), EXCEPTION_POINTERS *ep) { switch ( wxGlobalSEHandler(ep) ) { @@ -208,20 +200,11 @@ int wxEntry(int& argc, wxChar **argv) { DisableAutomaticSETranslator(); - __try + wxSEH_TRY { return wxEntryReal(argc, argv); } - __except ( wxGlobalSEHandler(GetExceptionInformation()) ) - { - wxFatalExit(); - -#if !defined(_MSC_VER) || defined(__WXDEBUG__) || (defined(_MSC_VER) && _MSC_VER <= 1200) - // this code is unreachable but put it here to suppress warnings in some compilers - // and disable for others to supress warnings too - return -1; -#endif // !__VISUALC__ in release build - } + wxSEH_HANDLE(-1) } #else // !wxUSE_ON_FATAL_EXCEPTION diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 2591047c61..c71dc34bff 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -1970,7 +1970,7 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y) #if defined(__WXWINCE__) UINT flags = 0; #else - UINT flags = TPM_RIGHTBUTTON | TPM_RECURSE; + UINT flags = TPM_RIGHTBUTTON; #endif ::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL); -- 2.45.2