From a37a5a73c54c0e120f0a35fc02e3ac4b600a42ff Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
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 <unistd.h>
@@ -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 <unistd.h>
@@ -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 <signal.h>
+
+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.50.0

