ReactOS 0.4.16-dev-752-g47bae01
except.c
Go to the documentation of this file.
1/*
2 * msvcrt.dll exception handling
3 *
4 * Copyright 2000 Jon Griffiths
5 * Copyright 2005 Juan Lang
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 *
21 * FIXME: Incomplete support for nested exceptions/try block cleanup.
22 */
23
24#include <float.h>
25#include <signal.h>
26#include <stdarg.h>
27#include <stdbool.h>
28
29#include "ntstatus.h"
30#define WIN32_NO_STATUS
31#include "windef.h"
32#include "winbase.h"
33#include "winternl.h"
34#ifdef __REACTOS__ // FIXME: Clean up wine headers!
35#include "wine/exception.h"
36#endif // __REACTOS__
37#include "msvcrt.h"
38#include "excpt.h"
39#include "wincon.h"
40#include "wine/debug.h"
41
42#include "cppexcept.h"
43
45
46#if _MSVCR_VER>=70 && _MSVCR_VER<=71
47static MSVCRT_security_error_handler security_error_handler;
48#endif
49
50static __sighandler_t sighandlers[NSIG] = { SIG_DFL };
51
53{
54 BOOL ret = FALSE;
55
56 switch (ctrlType)
57 {
58 case CTRL_C_EVENT:
60 {
63 ret = TRUE;
64 }
65 break;
66 }
67 return ret;
68}
69
70/*********************************************************************
71 * __pxcptinfoptrs (MSVCRT.@)
72 */
74{
75 return (void**)&msvcrt_get_thread_data()->xcptinfo;
76}
77
79
80/* The exception codes are actually NTSTATUS values */
81static const struct
82{
84 int signal;
93};
94
96{
98 __sighandler_t handler;
99
100 if (!except || !except->ExceptionRecord)
102
103 switch (except->ExceptionRecord->ExceptionCode)
104 {
107 {
108 if (handler != SIG_IGN)
109 {
111
112 old_ep = *ep;
113 *ep = except;
116 *ep = old_ep;
117 }
119 }
120 break;
121 /* According to msdn,
122 * the FPE signal handler takes as a second argument the type of
123 * floating point exception.
124 */
132 if ((handler = sighandlers[SIGFPE]) != SIG_DFL)
133 {
134 if (handler != SIG_IGN)
135 {
137 unsigned int i;
138 int float_signal = _FPE_INVALID;
139
141 for (i = 0; i < ARRAY_SIZE(float_exception_map); i++)
142 {
144 except->ExceptionRecord->ExceptionCode)
145 {
146 float_signal = float_exception_map[i].signal;
147 break;
148 }
149 }
150
151 old_ep = *ep;
152 *ep = except;
153 ((float_handler)handler)(SIGFPE, float_signal);
154 *ep = old_ep;
155 }
157 }
158 break;
161 if ((handler = sighandlers[SIGILL]) != SIG_DFL)
162 {
163 if (handler != SIG_IGN)
164 {
166
167 old_ep = *ep;
168 *ep = except;
171 *ep = old_ep;
172 }
174 }
175 break;
176 }
177 return ret;
178}
179
181{
183}
184
186{
188}
189
190#ifndef __REACTOS__ // Own implementation in signal/signal.c
191/*********************************************************************
192 * signal (MSVCRT.@)
193 * Some signals may never be generated except through an explicit call to
194 * raise.
195 */
196__sighandler_t CDECL signal(int sig, __sighandler_t func)
197{
198 __sighandler_t ret = SIG_ERR;
199
200 TRACE("(%d, %p)\n", sig, func);
201
202 if (func == SIG_ERR) return SIG_ERR;
203
204 switch (sig)
205 {
206 /* Cases handled internally. Note SIGTERM is never generated by Windows,
207 * so we effectively mask it.
208 */
209 case SIGABRT:
210 case SIGFPE:
211 case SIGILL:
212 case SIGSEGV:
213 case SIGINT:
214 case SIGTERM:
215 case SIGBREAK:
216 ret = sighandlers[sig];
217 sighandlers[sig] = func;
218 break;
219 default:
220 ret = SIG_ERR;
221 }
222 return ret;
223}
224
225/*********************************************************************
226 * raise (MSVCRT.@)
227 */
228int CDECL raise(int sig)
229{
230 __sighandler_t handler;
231
232 TRACE("(%d)\n", sig);
233
234 switch (sig)
235 {
236 case SIGFPE:
237 case SIGILL:
238 case SIGSEGV:
239 handler = sighandlers[sig];
240 if (handler == SIG_DFL) _exit(3);
241 if (handler != SIG_IGN)
242 {
244
245 sighandlers[sig] = SIG_DFL;
246
247 old_ep = *ep;
248 *ep = NULL;
249 if (sig == SIGFPE)
251 else
252 handler(sig);
253 *ep = old_ep;
254 }
255 break;
256 case SIGABRT:
257 case SIGINT:
258 case SIGTERM:
259 case SIGBREAK:
260 handler = sighandlers[sig];
261 if (handler == SIG_DFL) _exit(3);
262 if (handler != SIG_IGN)
263 {
264 sighandlers[sig] = SIG_DFL;
265 handler(sig);
266 }
267 break;
268 default:
269 return -1;
270 }
271 return 0;
272}
273#endif // __REACTOS__
274
275/*********************************************************************
276 * _XcptFilter (MSVCRT.@)
277 */
279{
280 TRACE("(%08x,%p)\n", ex, ptr);
281 /* I assume ptr->ExceptionRecord->ExceptionCode is the same as ex */
283}
284
285#ifndef __REACTOS__
286/*********************************************************************
287 * _abnormal_termination (MSVCRT.@)
288 */
290{
291 FIXME("(void)stub\n");
292 return 0;
293}
294#endif /* __REACTOS__ */
295
296/******************************************************************
297 * __uncaught_exception (MSVCRT.@)
298 */
300{
301 return msvcrt_get_thread_data()->processing_throw != 0;
302}
303
304#if _MSVCR_VER>=70 && _MSVCR_VER<=71
305
306/*********************************************************************
307 * _set_security_error_handler (MSVCR70.@)
308 */
309MSVCRT_security_error_handler CDECL _set_security_error_handler(
311{
312 MSVCRT_security_error_handler old = security_error_handler;
313
314 TRACE("(%p)\n", handler);
315
316 security_error_handler = handler;
317 return old;
318}
319
320/*********************************************************************
321 * __security_error_handler (MSVCR70.@)
322 */
323void CDECL __security_error_handler(int code, void *data)
324{
325 if(security_error_handler)
326 security_error_handler(code, data);
327 else
328 FIXME("(%d, %p) stub\n", code, data);
329
330 _exit(3);
331}
332
333#endif /* _MSVCR_VER>=70 && _MSVCR_VER<=71 */
334
335#if _MSVCR_VER>=110
336/*********************************************************************
337 * __crtSetUnhandledExceptionFilter (MSVCR110.@)
338 */
340{
342}
343#endif
344
345/*********************************************************************
346 * _CreateFrameInfo (MSVCR80.@)
347 */
349{
351
352 TRACE("(%p, %p)\n", fi, obj);
353
354 fi->next = data->frame_info_head;
355 data->frame_info_head = fi;
356 fi->object = obj;
357 return fi;
358}
359
360/*********************************************************************
361 * _FindAndUnlinkFrame (MSVCR80.@)
362 */
364{
366 frame_info *cur = data->frame_info_head;
367
368 TRACE("(%p)\n", fi);
369
370 if (cur == fi)
371 {
372 data->frame_info_head = cur->next;
373 return;
374 }
375
376 for (; cur->next; cur = cur->next)
377 {
378 if (cur->next == fi)
379 {
380 cur->next = fi->next;
381 return;
382 }
383 }
384
385 ERR("frame not found, native crashes in this case\n");
386}
387
388/*********************************************************************
389 * _IsExceptionObjectToBeDestroyed (MSVCR80.@)
390 */
392{
394
395 TRACE( "%p\n", obj );
396
397 for (cur = msvcrt_get_thread_data()->frame_info_head; cur; cur = cur->next)
398 {
399 if (cur->object == obj)
400 return FALSE;
401 }
402
403 return TRUE;
404}
405
406/*********************************************************************
407 * __DestructExceptionObject (MSVCRT.@)
408 */
410{
412 void *object = (void*)rec->ExceptionInformation[1];
413
414 TRACE("(%p)\n", rec);
415
416 if (rec->ExceptionCode != CXX_EXCEPTION) return;
417#ifndef __x86_64__
418 if (rec->NumberParameters != 3) return;
419#else
420 if (rec->NumberParameters != 4) return;
421#endif
424
425 if (!info || !info->destructor)
426 return;
427
428#if defined(__i386__)
429#ifdef _MSC_VER
430 ((void(__fastcall*)(void*))info->destructor)(object);
431#else
432 __asm__ __volatile__("call *%0" : : "r" (info->destructor), "c" (object) : "eax", "edx", "memory");
433#endif
434#elif defined(__x86_64__)
435 ((void (__cdecl*)(void*))(info->destructor+rec->ExceptionInformation[3]))(object);
436#else
437 ((void (__cdecl*)(void*))info->destructor)(object);
438#endif
439}
440
441/*********************************************************************
442 * __CxxRegisterExceptionObject (MSVCRT.@)
443 */
445{
447
448 TRACE("(%p, %p)\n", ep, frame_info);
449
450 if (!ep || !ep->ExceptionRecord)
451 {
452 frame_info->rec = (void*)-1;
453 frame_info->context = (void*)-1;
454 return TRUE;
455 }
456
457 frame_info->rec = data->exc_record;
458 frame_info->context = data->ctx_record;
459 data->exc_record = ep->ExceptionRecord;
460 data->ctx_record = ep->ContextRecord;
462 return TRUE;
463}
464
465/*********************************************************************
466 * __CxxUnregisterExceptionObject (MSVCRT.@)
467 */
469{
471
472 TRACE("(%p)\n", frame_info);
473
474 if(frame_info->rec == (void*)-1)
475 return;
476
477 _FindAndUnlinkFrame(&frame_info->frame_info);
478 if(data->exc_record->ExceptionCode == CXX_EXCEPTION && !in_use
479 && _IsExceptionObjectToBeDestroyed((void*)data->exc_record->ExceptionInformation[1]))
480 __DestructExceptionObject(data->exc_record);
481 data->exc_record = frame_info->rec;
482 data->ctx_record = frame_info->context;
483}
484
486 char *what;
487 char dofree;
488};
489
490#if _MSVCR_VER>=140 || defined(__UCRTSUPPORT__)
491
492/*********************************************************************
493 * __std_exception_copy (UCRTBASE.@)
494 */
495void CDECL __std_exception_copy(const struct __std_exception_data *src,
497{
498 TRACE("(%p %p)\n", src, dst);
499
500 if(src->dofree && src->what) {
501 dst->what = _strdup(src->what);
502 dst->dofree = 1;
503 } else {
504 dst->what = src->what;
505 dst->dofree = 0;
506 }
507}
508
509/*********************************************************************
510 * __std_exception_destroy (UCRTBASE.@)
511 */
512void CDECL __std_exception_destroy(struct __std_exception_data *data)
513{
514 TRACE("(%p)\n", data);
515
516 if(data->dofree)
517 free(data->what);
518 data->what = NULL;
519 data->dofree = 0;
520}
521
522/*********************************************************************
523 * __current_exception (UCRTBASE.@)
524 */
525void** CDECL __current_exception(void)
526{
527 TRACE("()\n");
528 return (void**)&msvcrt_get_thread_data()->exc_record;
529}
530
531/*********************************************************************
532 * __current_exception_context (UCRTBASE.@)
533 */
534void** CDECL __current_exception_context(void)
535{
536 TRACE("()\n");
537 return (void**)&msvcrt_get_thread_data()->ctx_record;
538}
539
540/*********************************************************************
541 * __processing_throw (UCRTBASE.@)
542 */
543int* CDECL __processing_throw(void)
544{
545 TRACE("()\n");
546 return &msvcrt_get_thread_data()->processing_throw;
547}
548
549#endif /* _MSVCR_VER>=140 */
void _exit(int exitcode)
Definition: _exit.c:25
#define __cdecl
Definition: accygwin.h:79
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
#define except(x)
Definition: btrfs_drv.h:136
#define SIG_DFL
Definition: signal.h:47
#define SIG_ERR
Definition: signal.h:52
#define SIGINT
Definition: signal.h:23
#define SIGILL
Definition: signal.h:25
#define SIGTERM
Definition: signal.h:39
#define SIGFPE
Definition: signal.h:30
#define SIGABRT
Definition: signal.h:28
#define NSIG
Definition: signal.h:20
#define SIG_IGN
Definition: signal.h:48
#define SIGSEGV
Definition: signal.h:33
#define SIGBREAK
Definition: signal.h:40
#define free
Definition: debug_ros.c:5
#define _strdup
Definition: debug_ros.c:7
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CDECL
Definition: compat.h:29
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2109
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI DECLSPEC_HOTPATCH SetUnhandledExceptionFilter(IN LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
Definition: except.c:790
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7512
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxCollectionEntry * cur
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum func
Definition: glext.h:6028
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#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_EXPLICITGEN
Definition: float.h:109
#define _FPE_UNDERFLOW
Definition: float.h:103
#define CXX_EXCEPTION
Definition: cppexcept.h:27
#define CXX_FRAME_MAGIC_VC6
Definition: cppexcept.h:24
#define CXX_FRAME_MAGIC_VC8
Definition: cppexcept.h:26
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:92
static PVOID ptr
Definition: dispmode.c:27
#define __fastcall
Definition: sync.c:38
void(__cdecl * MSVCRT_security_error_handler)(int, void *)
Definition: msvcrt.h:89
thread_data_t * msvcrt_get_thread_data(void)
Definition: tls.c:31
long LONG
Definition: pedump.c:60
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
BOOL CDECL __uncaught_exception(void)
Definition: except.c:299
static __sighandler_t sighandlers[NSIG]
Definition: except.c:50
int CDECL raise(int sig)
Definition: except.c:228
void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
Definition: except.c:409
NTSTATUS status
Definition: except.c:83
frame_info *CDECL _CreateFrameInfo(frame_info *fi, void *obj)
Definition: except.c:348
void msvcrt_free_signals(void)
Definition: except.c:185
static LONG msvcrt_exception_filter(struct _EXCEPTION_POINTERS *except)
Definition: except.c:95
void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_use)
Definition: except.c:468
static const struct @4363 float_exception_map[]
BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_POINTERS *ep, cxx_frame_info *frame_info)
Definition: except.c:444
int CDECL __intrinsic_abnormal_termination(void)
Definition: except.c:289
int CDECL _XcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr)
Definition: except.c:278
int signal
Definition: except.c:84
void **CDECL __pxcptinfoptrs(void)
Definition: except.c:73
void(CDECL * float_handler)(int, int)
Definition: except.c:78
void msvcrt_init_signals(void)
Definition: except.c:180
void CDECL _FindAndUnlinkFrame(frame_info *fi)
Definition: except.c:363
static BOOL WINAPI msvcrt_console_handler(DWORD ctrlType)
Definition: except.c:52
BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj)
Definition: except.c:391
#define TRACE(s)
Definition: solgame.cpp:4
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
PCONTEXT ContextRecord
Definition: rtltypes.h:201
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
Definition: inflate.c:139
Definition: comerr.c:44
Definition: ps.c:97
int ret
PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER
Definition: winbase.h:1478
#define EXCEPTION_FLT_STACK_CHECK
Definition: winbase.h:347
#define EXCEPTION_FLT_UNDERFLOW
Definition: winbase.h:348
#define EXCEPTION_FLT_OVERFLOW
Definition: winbase.h:346
#define EXCEPTION_FLT_DENORMAL_OPERAND
Definition: winbase.h:342
#define EXCEPTION_FLT_INEXACT_RESULT
Definition: winbase.h:344
#define EXCEPTION_ILLEGAL_INSTRUCTION
Definition: winbase.h:353
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:337
#define EXCEPTION_FLT_INVALID_OPERATION
Definition: winbase.h:345
#define EXCEPTION_PRIV_INSTRUCTION
Definition: winbase.h:351
#define EXCEPTION_FLT_DIVIDE_BY_ZERO
Definition: winbase.h:343
#define CTRL_C_EVENT
Definition: wincon.h:68
#define WINAPI
Definition: msvc.h:6