[Libreoffice-commits] Resolves: #i123747# allow treating Window's SEH events as C++ exceptions

Stephan Bergmann sbergman at redhat.com
Tue Nov 26 01:27:17 PST 2013


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 <hdu at apache.org>
> 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;
>   }
>


More information about the LibreOffice mailing list