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)
23 * @brief C exception "wrapper" class for C++ try/catch
25 * @note : for the original idea, see MSDN help about _set_se_translator
26 * derive from CException::CException
27 * creator needs a flag bAutoDelete
28 * (when flag is set, exception is reserved on heap, avoid to use the stack as it may be wrecked)
29 * one single interface to catch SE_Exception and CException
30 * GetErrorMessage : avoid using CString during exception processing
37 explicit SE_Exception(unsigned long n) : nSE(n) {}
40 unsigned long getSeNumber() { return nSE; }
42 const TCHAR *getSeMessage()
44 // known exceptions (from WINNT.H)
45 #define EXCEPTION( x ) case EXCEPTION_##x: return _T(#x);
49 EXCEPTION( ACCESS_VIOLATION )
50 EXCEPTION( DATATYPE_MISALIGNMENT )
51 EXCEPTION( BREAKPOINT )
52 EXCEPTION( SINGLE_STEP )
53 EXCEPTION( ARRAY_BOUNDS_EXCEEDED )
54 EXCEPTION( FLT_DENORMAL_OPERAND )
55 EXCEPTION( FLT_DIVIDE_BY_ZERO )
56 EXCEPTION( FLT_INEXACT_RESULT )
57 EXCEPTION( FLT_INVALID_OPERATION )
58 EXCEPTION( FLT_OVERFLOW )
59 EXCEPTION( FLT_STACK_CHECK )
60 EXCEPTION( FLT_UNDERFLOW )
61 EXCEPTION( INT_DIVIDE_BY_ZERO )
62 EXCEPTION( INT_OVERFLOW )
63 EXCEPTION( PRIV_INSTRUCTION )
64 EXCEPTION( IN_PAGE_ERROR )
65 EXCEPTION( ILLEGAL_INSTRUCTION )
66 EXCEPTION( NONCONTINUABLE_EXCEPTION )
67 EXCEPTION( STACK_OVERFLOW )
68 EXCEPTION( INVALID_DISPOSITION )
69 EXCEPTION( GUARD_PAGE )
70 EXCEPTION( INVALID_HANDLE )
73 // don't localize this as we do not localize the known exceptions
74 return _T("Unknown structured exception");
76 virtual bool GetErrorMessage( TCHAR *lpszError, unsigned nMaxError, unsigned *pnHelpContext = nullptr )
78 StringCchPrintf(lpszError, nMaxError, _T("Exception %s (0x%.8x)"), getSeMessage(), static_cast<unsigned>(getSeNumber()));
82 virtual bool GetErrorMessage( TCHAR *lpszError, unsigned nMaxError, unsigned *pnHelpContext = nullptr )
92 * @brief Set the structured exception translator during the life of the object.
93 * Just add 'SE_Handler seh;' at the beginning of the function.
95 * @note May be created as a global variable. In fact, you need one instance
101 _se_translator_function fnOld;
102 static void seh_trans_func(unsigned u, EXCEPTION_POINTERS* pExp)
104 unsigned dwCode = (pExp && pExp->ExceptionRecord) ? pExp->ExceptionRecord->ExceptionCode : 0;
105 throw SE_Exception((long)dwCode);
108 SE_Handler() : fnOld{_set_se_translator(seh_trans_func)} {}
109 ~SE_Handler() { _set_se_translator(fnOld); }