From a37a5a73c54c0e120f0a35fc02e3ac4b600a42ff Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 17 Mar 2000 16:55:34 +0000 Subject: [PATCH] wxHandleFatalExceptions() added, documented git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6802 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/app.tex | 17 +++++++++ docs/latex/wx/function.tex | 8 +++++ include/wx/utils.h | 3 ++ src/common/wincmn.cpp | 1 + src/gtk/app.cpp | 6 ++-- src/gtk1/app.cpp | 6 ++-- src/unix/utilsunx.cpp | 74 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 107 insertions(+), 8 deletions(-) diff --git a/docs/latex/wx/app.tex b/docs/latex/wx/app.tex index b5e7d31340..ac6b3fb0a8 100644 --- a/docs/latex/wx/app.tex +++ b/docs/latex/wx/app.tex @@ -233,6 +233,23 @@ If you use this member, you can selectively consume keypress events by calling\r \helpref{wxKeyEvent}{wxkeyevent}, \helpref{wxWindow::OnChar}{wxwindowonchar},\rtfsp \helpref{wxWindow::OnCharHook}{wxwindowoncharhook}, \helpref{wxDialog::OnCharHook}{wxdialogoncharhook} +\membersection{wxApp::OnFatalException}\label{wxapponfatalexception} + +\func{void}{OnFatalException}{\void} + +This function may be called if something fatal happens: an unhandled +exception under Win32 or a a fatal signal under Unix, for example. However, +this will not happen by default: you have to explicitly call +\helpref{wxHandleFatalExcetions}{wxhandlefatalexcetions} to enable this. + +Generally speaking, this function should only show a message to the user and +return. You may attempt to save unsaved data but this is not guaranteed to +work and, in fact, probably won't. + +\wxheading{See also} + +\helpref{wxHandleFatalExcetions}{wxhandlefatalexcetions} + \membersection{wxApp::OnIdle}\label{wxapponidle} \func{void}{OnIdle}{\param{wxIdleEvent\& }{event}} diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex index 776ed77822..587d32e6e6 100644 --- a/docs/latex/wx/function.tex +++ b/docs/latex/wx/function.tex @@ -1057,6 +1057,14 @@ The clipboard must have previously been opened for this call to succeed. \section{Miscellaneous functions}\label{miscellany} +\membersection{wxHandleFatalExcetions}\label{wxhandlefatalexcetions} + +\func{bool}{wxHandleFatalExcetions}{\param{bool }{doIt = TRUE}} + +Enables or disables handling of fatal program exceptions. If {\it doIt} is +TRUE, \helpref{wxApp::OnFatalException}{wxapponfatalexception} will be called +before the program crashes. Otherwise, the default behaviour will be restored. + \membersection{::wxNewId} \func{long}{wxNewId}{\void} diff --git a/include/wx/utils.h b/include/wx/utils.h index 09ac220a9e..2eec7b1c11 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -193,6 +193,9 @@ WXDLLEXPORT void wxUsleep(unsigned long milliseconds); // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) WXDLLEXPORT long wxGetFreeMemory(); +// should wxApp::OnFatalException() be called? +WXDLLEXPORT bool wxHandleFatalExceptions(bool doit = TRUE); + // ---------------------------------------------------------------------------- // Network and username functions. // ---------------------------------------------------------------------------- diff --git a/src/common/wincmn.cpp b/src/common/wincmn.cpp index 0bc84593e1..c8885cb0c4 100644 --- a/src/common/wincmn.cpp +++ b/src/common/wincmn.cpp @@ -41,6 +41,7 @@ #include "wx/settings.h" #include "wx/dialog.h" #include "wx/msgdlg.h" + #include "wx/statusbr.h" #endif //WX_PRECOMP #if wxUSE_CONSTRAINTS diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index 17732ceb90..84f625014f 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -29,7 +29,7 @@ #include "wx/image.h" #if wxUSE_THREADS -#include "wx/thread.h" + #include "wx/thread.h" #endif #include @@ -651,9 +651,7 @@ void wxEntryCleanup() int wxEntry( int argc, char *argv[] ) { - int err; - - err = wxEntryStart(argc, argv); + int err = wxEntryStart(argc, argv); if (err) return err; diff --git a/src/gtk1/app.cpp b/src/gtk1/app.cpp index 17732ceb90..84f625014f 100644 --- a/src/gtk1/app.cpp +++ b/src/gtk1/app.cpp @@ -29,7 +29,7 @@ #include "wx/image.h" #if wxUSE_THREADS -#include "wx/thread.h" + #include "wx/thread.h" #endif #include @@ -651,9 +651,7 @@ void wxEntryCleanup() int wxEntry( int argc, char *argv[] ) { - int err; - - err = wxEntryStart(argc, argv); + int err = wxEntryStart(argc, argv); if (err) return err; diff --git a/src/unix/utilsunx.cpp b/src/unix/utilsunx.cpp index fb8c58bc90..a3f3641c03 100644 --- a/src/unix/utilsunx.cpp +++ b/src/unix/utilsunx.cpp @@ -20,6 +20,7 @@ #include "wx/intl.h" #include "wx/log.h" +#include "wx/app.h" #include "wx/utils.h" #include "wx/process.h" @@ -785,6 +786,79 @@ wxString wxGetOsDescription() #endif } +// ---------------------------------------------------------------------------- +// signal handling +// ---------------------------------------------------------------------------- + +#if wxUSE_ON_FATAL_EXCEPTION + +#include + +static void wxFatalSignalHandler(int signal) +{ + if ( wxTheApp ) + { + // give the user a chance to do something special about this + wxTheApp->OnFatalException(); + } + + abort(); +} + +bool wxHandleFatalExceptions(bool doit) +{ + // old sig handlers + static bool s_savedHandlers = FALSE; + static struct sigaction s_handlerFPE, + s_handlerILL, + s_handlerBUS, + s_handlerSEGV; + + bool ok = TRUE; + if ( doit && !s_savedHandlers ) + { + // install the signal handler + struct sigaction act; + + // some systems extend it with non std fields, so zero everything + memset(&act, 0, sizeof(act)); + + act.sa_handler = wxFatalSignalHandler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + + ok &= sigaction(SIGFPE, &act, &s_handlerFPE) == 0; + ok &= sigaction(SIGILL, &act, &s_handlerILL) == 0; + ok &= sigaction(SIGBUS, &act, &s_handlerBUS) == 0; + ok &= sigaction(SIGSEGV, &act, &s_handlerSEGV) == 0; + if ( !ok ) + { + wxLogDebug(_T("Failed to install our signal handler.")); + } + + s_savedHandlers = TRUE; + } + else if ( s_savedHandlers ) + { + // uninstall the signal handler + ok &= sigaction(SIGFPE, &s_handlerFPE, NULL) == 0; + ok &= sigaction(SIGILL, &s_handlerILL, NULL) == 0; + ok &= sigaction(SIGBUS, &s_handlerBUS, NULL) == 0; + ok &= sigaction(SIGSEGV, &s_handlerSEGV, NULL) == 0; + if ( !ok ) + { + wxLogDebug(_T("Failed to uninstall our signal handler.")); + } + + s_savedHandlers = FALSE; + } + //else: nothing to do + + return ok; +} + +#endif // wxUSE_ON_FATAL_EXCEPTION + // ---------------------------------------------------------------------------- // error and debug output routines (deprecated, use wxLog) // ---------------------------------------------------------------------------- -- 2.45.2