1 /////////////////////////////////////////////////////////////////////////////
2 // WinMerge: an interactive diff/merge utility
3 // Copyright (C) 1997-2000 Thingamahoochie Software
5 // SPDX-License-Identifier: GPL-2.0-or-later
6 /////////////////////////////////////////////////////////////////////////////
10 * @brief Exceptions handlers (currently, only SE handler for try/catch)
21 #include "utils/ctchar.h"
25 * @brief C exception "wrapper" class for C++ try/catch
27 * @note : for the original idea, see MSDN help about _set_se_translator
28 * derive from CException::CException
29 * creator needs a flag bAutoDelete
30 * (when flag is set, exception is reserved on heap, avoid to use the stack as it may be wrecked)
31 * one single interface to catch SE_Exception and CException
32 * GetErrorMessage : avoid using CString during exception processing
39 explicit SE_Exception(unsigned long n) : nSE(n) {}
40 ~SE_Exception() = default;
42 unsigned long getSeNumber() { return nSE; }
44 const tchar_t *getSeMessage()
46 // known exceptions (from WINNT.H)
47 #define EXCEPTION( x ) case EXCEPTION_##x: return _T(#x);
51 EXCEPTION( ACCESS_VIOLATION )
52 EXCEPTION( DATATYPE_MISALIGNMENT )
53 EXCEPTION( BREAKPOINT )
54 EXCEPTION( SINGLE_STEP )
55 EXCEPTION( ARRAY_BOUNDS_EXCEEDED )
56 EXCEPTION( FLT_DENORMAL_OPERAND )
57 EXCEPTION( FLT_DIVIDE_BY_ZERO )
58 EXCEPTION( FLT_INEXACT_RESULT )
59 EXCEPTION( FLT_INVALID_OPERATION )
60 EXCEPTION( FLT_OVERFLOW )
61 EXCEPTION( FLT_STACK_CHECK )
62 EXCEPTION( FLT_UNDERFLOW )
63 EXCEPTION( INT_DIVIDE_BY_ZERO )
64 EXCEPTION( INT_OVERFLOW )
65 EXCEPTION( PRIV_INSTRUCTION )
66 EXCEPTION( IN_PAGE_ERROR )
67 EXCEPTION( ILLEGAL_INSTRUCTION )
68 EXCEPTION( NONCONTINUABLE_EXCEPTION )
69 EXCEPTION( STACK_OVERFLOW )
70 EXCEPTION( INVALID_DISPOSITION )
71 EXCEPTION( GUARD_PAGE )
72 EXCEPTION( INVALID_HANDLE )
75 // don't localize this as we do not localize the known exceptions
76 return _T("Unknown structured exception");
78 virtual bool GetErrorMessage(tchar_t *lpszError, unsigned nMaxError, unsigned *pnHelpContext = nullptr)
80 StringCchPrintf(lpszError, nMaxError, _T("Exception %s (0x%.8x)"), getSeMessage(), static_cast<unsigned>(getSeNumber()));
84 virtual bool GetErrorMessage(tchar_t *lpszError, unsigned nMaxError, unsigned *pnHelpContext = nullptr)
93 * @brief Set the structured exception translator during the life of the object.
94 * Just add 'SE_Handler seh;' at the beginning of the function.
96 * @note May be created as a global variable. In fact, you need one instance
102 _se_translator_function fnOld;
103 static void seh_trans_func(unsigned u, EXCEPTION_POINTERS* pExp)
105 unsigned dwCode = (pExp && pExp->ExceptionRecord) ? pExp->ExceptionRecord->ExceptionCode : 0;
106 throw SE_Exception((long)dwCode);
109 SE_Handler() : fnOld{_set_se_translator(seh_trans_func)} {}
110 ~SE_Handler() { _set_se_translator(fnOld); }