Is this sound? I am no expert with Windows SEH, does it actually guarantee that the low-level process state is also a valid state at the higher-level C++ semantics when a SEH exception is thrown? (That would be a prerequisite for this patch, and e.g. the missing guarantee about that consistency for C/POSIX signals is the reason why we cannot automatically translate such signals into C++ exceptions.)

Stephan

On 11/25/2013 03:26 PM, Herbert Dürr wrote:
commit e79af02bb0e8de14c881f5071a519f6fadedc828
Author: Herbert Dürr <[email protected]>
Date:   Mon Nov 25 13:29:47 2013 +0000

     Resolves: #i123747# allow treating Window's SEH events as C++ exceptions

     The crash reporter facility can provide much better details about crashes.
     But if that facility is disabled then handling SEH events such as 
div-by-zero
     as C++ exceptions is a worthwhile alternative. It can provide a few 
interesting
     details and it allows a graceful shutdown of the application.

     (cherry picked from commit c9d10b167b37a9cb0bb310cafc8e80b6cce8ea7a)

     Conflicts:
        sal/osl/w32/signal.cxx

     Change-Id: I25324d6e02ab8acd8fd2b036b77039aac87cf262

diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index ee3b4d5..79fdc50 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -1488,11 +1488,8 @@ int Desktop::Main()

          // set static variable to enabled/disable crash reporter
          retrieveCrashReporterState();
-        if ( !isCrashReporterEnabled() )
-        {
-            osl_setErrorReporting( sal_False );
-            // disable stack trace feature
-        }
+        const bool bCrashReporterEnabled = isCrashReporterEnabled();
+        osl_setErrorReporting( !bCrashReporterEnabled );

          // create title string
          LanguageTag aLocale( LANGUAGE_SYSTEM);
diff --git a/sal/osl/w32/signal.cxx b/sal/osl/w32/signal.cxx
index f13a78a..51e08bc 100644
--- a/sal/osl/w32/signal.cxx
+++ b/sal/osl/w32/signal.cxx
@@ -33,6 +33,8 @@
  #include <errorrep.h>
  #include <systools/win32/uwinapi.h>
  #include <sal/macros.h>
+#include <eh.h>
+#include <stdexcept>

  typedef struct _oslSignalHandlerImpl
  {
@@ -398,11 +400,50 @@ oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 
UserSignal, void* UserData)
  
/*****************************************************************************/
  /* osl_setErrorReporting */
  
/*****************************************************************************/
+
+void win_seh_translator( unsigned nSEHCode, _EXCEPTION_POINTERS* pExcPtrs)
+{
+    const char* pSEHName = NULL;
+    switch( nSEHCode) {
+        case EXCEPTION_ACCESS_VIOLATION:         pSEHName = "SEH Exception: ACCESS 
VIOLATION"; break;
+        case EXCEPTION_DATATYPE_MISALIGNMENT:    pSEHName = "SEH Exception: 
DATATYPE MISALIGNMENT"; break;
+//      case EXCEPTION_BREAKPOINT:               pSEHName = "SEH Exception: 
BREAKPOINT"; break;
+//      case EXCEPTION_SINGLE_STEP:              pSEHName = "SEH Exception: SINGLE 
STEP"; break;
+        case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:    pSEHName = "SEH Exception: ARRAY 
BOUNDS EXCEEDED"; break;
+        case EXCEPTION_FLT_DENORMAL_OPERAND:     pSEHName = "SEH Exception: 
DENORMAL FLOAT OPERAND"; break;
+        case EXCEPTION_FLT_DIVIDE_BY_ZERO:       pSEHName = "SEH Exception: FLOAT 
DIVIDE_BY_ZERO"; break;
+        case EXCEPTION_FLT_INEXACT_RESULT:       pSEHName = "SEH Exception: FLOAT 
INEXACT RESULT"; break;
+        case EXCEPTION_FLT_INVALID_OPERATION:    pSEHName = "SEH Exception: INVALID 
FLOAT OPERATION"; break;
+        case EXCEPTION_FLT_OVERFLOW:             pSEHName = "SEH Exception: FLOAT 
OVERFLOW"; break;
+        case EXCEPTION_FLT_STACK_CHECK:          pSEHName = "SEH Exception: FLOAT 
STACK_CHECK"; break;
+        case EXCEPTION_FLT_UNDERFLOW:            pSEHName = "SEH Exception: FLOAT 
UNDERFLOW"; break;
+        case EXCEPTION_INT_DIVIDE_BY_ZERO:       pSEHName = "SEH Exception: INTEGER 
DIVIDE_BY_ZERO"; break;
+        case EXCEPTION_INT_OVERFLOW:             pSEHName = "SEH Exception: INTEGER 
OVERFLOW"; break;
+        case EXCEPTION_PRIV_INSTRUCTION:         pSEHName = "SEH Exception: 
PRIVILEDGED INSTRUCTION"; break;
+        case EXCEPTION_IN_PAGE_ERROR:            pSEHName = "SEH Exception: 
IN_PAGE_ERROR"; break;
+        case EXCEPTION_ILLEGAL_INSTRUCTION:      pSEHName = "SEH Exception: ILLEGAL 
INSTRUCTION"; break;
+        case EXCEPTION_NONCONTINUABLE_EXCEPTION: pSEHName = "SEH Exception: 
NONCONTINUABLE EXCEPTION"; break;
+        case EXCEPTION_STACK_OVERFLOW:           pSEHName = "SEH Exception: STACK 
OVERFLOW"; break;
+        case EXCEPTION_INVALID_DISPOSITION:      pSEHName = "SEH Exception: INVALID 
DISPOSITION"; break;
+        case EXCEPTION_GUARD_PAGE:               pSEHName = "SEH Exception: GUARD 
PAGE"; break;
+        case EXCEPTION_INVALID_HANDLE:           pSEHName = "SEH Exception: INVALID 
HANDLE"; break;
+//      case EXCEPTION_POSSIBLE_DEADLOCK:        pSEHName = "SEH Exception: 
POSSIBLE DEADLOCK"; break;
+        default:                                 pSEHName = "Unknown SEH 
Exception"; break;
+    }
+    throw std::runtime_error( pSEHName);
+}
+
  sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
  {
      sal_Bool bOld = bErrorReportingEnabled;
      bErrorReportingEnabled = bEnable;

+    if( !bEnable) // if the crash reporter is disabled
+    {
+        // fall back to handle Window's SEH events as C++ exceptions
+        _set_se_translator( win_seh_translator);
+    }
+
      return bOld;
  }

_______________________________________________
LibreOffice mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/libreoffice

Reply via email to