ReactOS 0.4.16-dev-927-g467dec4
exception_filter.cpp File Reference
#include <corecrt_internal.h>
#include <float.h>
#include <signal.h>
#include <stddef.h>
Include dependency graph for exception_filter.cpp:

Go to the source code of this file.

Functions

static __crt_signal_action_t *__cdecl xcptlookup (unsigned long const xcptnum, __crt_signal_action_t *const action_table) throw ()
 
int __cdecl _seh_filter_dll (unsigned long const xcptnum, PEXCEPTION_POINTERS const pxcptinfoptrs)
 
int __cdecl _seh_filter_exe (unsigned long const xcptnum, PEXCEPTION_POINTERS const pxcptinfoptrs)
 

Variables

struct __crt_signal_action_t const __acrt_exception_action_table []
 
size_t const __acrt_signal_action_first_fpe_index = 3
 
size_t const __acrt_signal_action_fpe_count = 9
 
size_t const __acrt_signal_action_table_size = sizeof(__acrt_exception_action_table)
 
size_t const __acrt_signal_action_table_count = sizeof(__acrt_exception_action_table) / sizeof(__acrt_exception_action_table[0])
 

Function Documentation

◆ _seh_filter_dll()

int __cdecl _seh_filter_dll ( unsigned long const  xcptnum,
PEXCEPTION_POINTERS const  pxcptinfoptrs 
)

Definition at line 75 of file exception_filter.cpp.

79{
80 if (xcptnum != ('msc' | 0xE0000000))
82
83 return _seh_filter_exe(xcptnum,pxcptinfoptrs);
84}
int __cdecl _seh_filter_exe(unsigned long const xcptnum, PEXCEPTION_POINTERS const pxcptinfoptrs)
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91

◆ _seh_filter_exe()

int __cdecl _seh_filter_exe ( unsigned long const  xcptnum,
PEXCEPTION_POINTERS const  pxcptinfoptrs 
)

Definition at line 120 of file exception_filter.cpp.

124{
125 // Get the PTD and find the action for this exception. If either of these
126 // fails, return to let the handler search continue.
128 if (ptd == nullptr)
130
131 __crt_signal_action_t* const pxcptact = xcptlookup(xcptnum, ptd->_pxcptacttab);
132 if (pxcptact == nullptr)
134
135 __crt_signal_handler_t const phandler = pxcptact->_action;
136
137 // The default behavior (SIG_DFL) is not to handle the exception:
138 if (phandler == SIG_DFL)
140
141 // If the behavior is to die, execute the handler:
142 if (phandler == SIG_DIE)
143 {
144 // Reset the _action (in case of recursion) and enter the __except:
145 pxcptact->_action = SIG_DFL;
147 }
148
149 // If an exception is ignored, just ignore it:
150 if (phandler == SIG_IGN)
152
153 // The remaining exceptions all correspond to C signals which have signal
154 // handlers associated with them. For some, special setup is required
155 // before the signal handler is called. In all cases, if the signal handler
156 // returns, -1 is returned by this function to resume execution at the point
157 // where the exception occurred.
158
159 // Save the old exception pointers in case this is a nested exception/signal.
160 PEXCEPTION_POINTERS const old_pxcptinfoptrs = ptd->_tpxcptinfoptrs;
161 ptd->_tpxcptinfoptrs = pxcptinfoptrs;
162
163 // Call the user-supplied signal handler. Floating point exceptions must be
164 // handled specially since, from the C point of view, there is only one
165 // signal. The exact identity of the exception is passed in the per-thread
166 // variable _tfpecode.
167 if (pxcptact->_signal_number == SIGFPE)
168 {
169 // Reset the _action field to the default for all SIGFPE entries:
172
173 for (__crt_signal_action_t* it = first; it != last; ++it)
174 it->_action = SIG_DFL;
175
176 // Save the current _tfpecode in case this is a nested floating point
177 // exception. It's not clear that we need to support this, but it's
178 // easy to support.
179 int const old_fpecode = ptd->_tfpecode;
180
181 // Note: There are no exceptions corresponding to _FPE_UNEMULATED and
182 // _FPE_SQRTNEG. Furthermore, STATUS_FLOATING_STACK_CHECK is raised for
183 // both stack overflow and underflow, thus the exception does not
184 // distinguish between _FPE_STACKOVERFLOW and _FPE_STACKUNDERFLOW.
185 // Arbitrarily, _tfpecode is set to the formr value.
186 switch (pxcptact->_exception_number)
187 {
188 case STATUS_FLOAT_DIVIDE_BY_ZERO: ptd->_tfpecode = _FPE_ZERODIVIDE; break;
189 case STATUS_FLOAT_INVALID_OPERATION: ptd->_tfpecode = _FPE_INVALID; break;
190 case STATUS_FLOAT_OVERFLOW: ptd->_tfpecode = _FPE_OVERFLOW; break;
191 case STATUS_FLOAT_UNDERFLOW: ptd->_tfpecode = _FPE_UNDERFLOW; break;
192 case STATUS_FLOAT_DENORMAL_OPERAND: ptd->_tfpecode = _FPE_DENORMAL; break;
193 case STATUS_FLOAT_INEXACT_RESULT: ptd->_tfpecode = _FPE_INEXACT; break;
194 case STATUS_FLOAT_STACK_CHECK: ptd->_tfpecode = _FPE_STACKOVERFLOW; break;
195 case STATUS_FLOAT_MULTIPLE_TRAPS: ptd->_tfpecode = _FPE_MULTIPLE_TRAPS; break;
196 case STATUS_FLOAT_MULTIPLE_FAULTS: ptd->_tfpecode = _FPE_MULTIPLE_FAULTS; break;
197 }
198
199 // Call the SIGFPE handler. Note that we cast to the given function
200 // type to support old MS C programs whose SIGFPE handlers expect two
201 // arguments.
202 //
203 // CRT_REFACTOR TODO Can we remove this support? It's not clear that
204 // this is correct for all architectures (e.g. x64 and ARM).
205 reinterpret_cast<void (__cdecl *)(int, int)>(phandler)(SIGFPE, ptd->_tfpecode);
206
207 // Restore the stored value of _tfpecode:
208 ptd->_tfpecode = old_fpecode;
209 }
210 else
211 {
212 // Reset the _action field to the default, then call the user-
213 // supplied handler:
214 pxcptact->_action = SIG_DFL;
215 phandler(pxcptact->_signal_number);
216 }
217
218 // Restore the stored value of _pxcptinfoptrs:
219 ptd->_tpxcptinfoptrs = old_pxcptinfoptrs;
220
222}
#define __cdecl
Definition: accygwin.h:79
void(__cdecl * __crt_signal_handler_t)(int)
__acrt_ptd *__cdecl __acrt_getptd_noexit(void)
#define SIG_DFL
Definition: signal.h:47
#define SIGFPE
Definition: signal.h:30
#define SIG_IGN
Definition: signal.h:48
_In_ size_t const _In_ int _In_ bool const _In_ unsigned const _In_ __acrt_rounding_mode const _Inout_ __crt_cached_ptd_host & ptd
Definition: cvt.cpp:355
switch(r->id)
Definition: btrfs.c:3046
size_t const __acrt_signal_action_first_fpe_index
static __crt_signal_action_t *__cdecl xcptlookup(unsigned long const xcptnum, __crt_signal_action_t *const action_table)
size_t const __acrt_signal_action_fpe_count
const GLint * first
Definition: glext.h:5794
#define _FPE_INEXACT
Definition: float.h:104
#define _FPE_OVERFLOW
Definition: float.h:102
#define _FPE_ZERODIVIDE
Definition: float.h:101
#define _FPE_STACKOVERFLOW
Definition: float.h:107
#define _FPE_INVALID
Definition: float.h:99
#define _FPE_DENORMAL
Definition: float.h:100
#define _FPE_UNDERFLOW
Definition: float.h:103
#define _FPE_MULTIPLE_TRAPS
Definition: float.h:192
#define _FPE_MULTIPLE_FAULTS
Definition: float.h:193
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:92
static UINT UINT last
Definition: font.c:45
#define STATUS_FLOAT_UNDERFLOW
Definition: ntstatus.h:383
#define STATUS_FLOAT_OVERFLOW
Definition: ntstatus.h:381
#define STATUS_FLOAT_STACK_CHECK
Definition: ntstatus.h:382
#define STATUS_FLOAT_DIVIDE_BY_ZERO
Definition: ntstatus.h:378
#define STATUS_FLOAT_MULTIPLE_FAULTS
Definition: ntstatus.h:807
#define STATUS_FLOAT_MULTIPLE_TRAPS
Definition: ntstatus.h:808
#define STATUS_FLOAT_INVALID_OPERATION
Definition: ntstatus.h:380
#define STATUS_FLOAT_INEXACT_RESULT
Definition: ntstatus.h:379
#define STATUS_FLOAT_DENORMAL_OPERAND
Definition: ntstatus.h:377
unsigned long _exception_number
__crt_signal_handler_t _action

Referenced by _seh_filter_dll().

◆ xcptlookup()

static __crt_signal_action_t *__cdecl xcptlookup ( unsigned long const  xcptnum,
__crt_signal_action_t *const  action_table 
)
throw (
)
static

Definition at line 55 of file exception_filter.cpp.

59{
60 __crt_signal_action_t* const first = action_table;
62
63 // Search for the matching entry and return it if we find it:
64 for (__crt_signal_action_t* it = first; it != last; ++it)
65 if (it->_exception_number == xcptnum)
66 return it;
67
68 // Otherwise, return nullptr on failure:
69 return nullptr;
70}
size_t const __acrt_signal_action_table_count

Referenced by _seh_filter_exe().

Variable Documentation

◆ __acrt_exception_action_table

◆ __acrt_signal_action_first_fpe_index

size_t const __acrt_signal_action_first_fpe_index = 3

Definition at line 41 of file exception_filter.cpp.

Referenced by _seh_filter_exe(), and raise().

◆ __acrt_signal_action_fpe_count

size_t const __acrt_signal_action_fpe_count = 9

Definition at line 44 of file exception_filter.cpp.

Referenced by _seh_filter_exe(), and raise().

◆ __acrt_signal_action_table_count

Definition at line 50 of file exception_filter.cpp.

Referenced by siglookup(), signal(), and xcptlookup().

◆ __acrt_signal_action_table_size

size_t const __acrt_signal_action_table_size = sizeof(__acrt_exception_action_table)

Definition at line 47 of file exception_filter.cpp.

Referenced by signal().