ReactOS 0.4.15-dev-7934-g1dc8d80
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 "config.h"
25#include "wine/port.h"
26
27#include <stdarg.h>
28
29#include "ntstatus.h"
30#define WIN32_NO_STATUS
31#include "windef.h"
32#include "winbase.h"
33#include "winternl.h"
34#include "wine/exception.h"
35#include "msvcrt.h"
36#include "excpt.h"
37#include "wincon.h"
38#include "wine/debug.h"
39
40#include "cppexcept.h"
41
43
44#if _MSVCR_VER>=70 && _MSVCR_VER<=71
45static MSVCRT_security_error_handler security_error_handler;
46#endif
47
49
51{
52 BOOL ret = FALSE;
53
54 switch (ctrlType)
55 {
56 case CTRL_C_EVENT:
58 {
61 ret = TRUE;
62 }
63 break;
64 }
65 return ret;
66}
67
68/*********************************************************************
69 * __pxcptinfoptrs (MSVCRT.@)
70 */
72{
73 return (void**)&msvcrt_get_thread_data()->xcptinfo;
74}
75
77
78/* The exception codes are actually NTSTATUS values */
79static const struct
80{
82 int signal;
91};
92
94{
97
98 if (!except || !except->ExceptionRecord)
100
101 switch (except->ExceptionRecord->ExceptionCode)
102 {
105 {
106 if (handler != MSVCRT_SIG_IGN)
107 {
109
110 old_ep = *ep;
111 *ep = except;
114 *ep = old_ep;
115 }
117 }
118 break;
119 /* According to msdn,
120 * the FPE signal handler takes as a second argument the type of
121 * floating point exception.
122 */
131 {
132 if (handler != MSVCRT_SIG_IGN)
133 {
135 unsigned int i;
136 int float_signal = MSVCRT__FPE_INVALID;
137
139 for (i = 0; i < ARRAY_SIZE(float_exception_map); i++)
140 {
142 except->ExceptionRecord->ExceptionCode)
143 {
144 float_signal = float_exception_map[i].signal;
145 break;
146 }
147 }
148
149 old_ep = *ep;
150 *ep = except;
151 ((float_handler)handler)(MSVCRT_SIGFPE, float_signal);
152 *ep = old_ep;
153 }
155 }
156 break;
160 {
161 if (handler != MSVCRT_SIG_IGN)
162 {
164
165 old_ep = *ep;
166 *ep = except;
169 *ep = old_ep;
170 }
172 }
173 break;
174 }
175 return ret;
176}
177
179{
181}
182
184{
186}
187
188/*********************************************************************
189 * signal (MSVCRT.@)
190 * Some signals may never be generated except through an explicit call to
191 * raise.
192 */
194{
196
197 TRACE("(%d, %p)\n", sig, func);
198
199 if (func == MSVCRT_SIG_ERR) return MSVCRT_SIG_ERR;
200
201 switch (sig)
202 {
203 /* Cases handled internally. Note SIGTERM is never generated by Windows,
204 * so we effectively mask it.
205 */
206 case MSVCRT_SIGABRT:
207 case MSVCRT_SIGFPE:
208 case MSVCRT_SIGILL:
209 case MSVCRT_SIGSEGV:
210 case MSVCRT_SIGINT:
211 case MSVCRT_SIGTERM:
212 case MSVCRT_SIGBREAK:
213 ret = sighandlers[sig];
214 sighandlers[sig] = func;
215 break;
216 default:
218 }
219 return ret;
220}
221
222/*********************************************************************
223 * raise (MSVCRT.@)
224 */
225int CDECL MSVCRT_raise(int sig)
226{
228
229 TRACE("(%d)\n", sig);
230
231 switch (sig)
232 {
233 case MSVCRT_SIGFPE:
234 case MSVCRT_SIGILL:
235 case MSVCRT_SIGSEGV:
236 handler = sighandlers[sig];
238 if (handler != MSVCRT_SIG_IGN)
239 {
241
243
244 old_ep = *ep;
245 *ep = NULL;
246 if (sig == MSVCRT_SIGFPE)
248 else
249 handler(sig);
250 *ep = old_ep;
251 }
252 break;
253 case MSVCRT_SIGABRT:
254 case MSVCRT_SIGINT:
255 case MSVCRT_SIGTERM:
256 case MSVCRT_SIGBREAK:
257 handler = sighandlers[sig];
259 if (handler != MSVCRT_SIG_IGN)
260 {
262 handler(sig);
263 }
264 break;
265 default:
266 return -1;
267 }
268 return 0;
269}
270
271/*********************************************************************
272 * _XcptFilter (MSVCRT.@)
273 */
275{
276 TRACE("(%08x,%p)\n", ex, ptr);
277 /* I assume ptr->ExceptionRecord->ExceptionCode is the same as ex */
279}
280
281#ifndef __REACTOS__
282/*********************************************************************
283 * _abnormal_termination (MSVCRT.@)
284 */
286{
287 FIXME("(void)stub\n");
288 return 0;
289}
290#endif /* __REACTOS__ */
291
292/******************************************************************
293 * __uncaught_exception (MSVCRT.@)
294 */
296{
297 return msvcrt_get_thread_data()->processing_throw != 0;
298}
299
300#if _MSVCR_VER>=70 && _MSVCR_VER<=71
301
302/*********************************************************************
303 * _set_security_error_handler (MSVCR70.@)
304 */
305MSVCRT_security_error_handler CDECL _set_security_error_handler(
307{
308 MSVCRT_security_error_handler old = security_error_handler;
309
310 TRACE("(%p)\n", handler);
311
312 security_error_handler = handler;
313 return old;
314}
315
316/*********************************************************************
317 * __security_error_handler (MSVCR70.@)
318 */
319void CDECL __security_error_handler(int code, void *data)
320{
321 if(security_error_handler)
322 security_error_handler(code, data);
323 else
324 FIXME("(%d, %p) stub\n", code, data);
325
326 MSVCRT__exit(3);
327}
328
329#endif /* _MSVCR_VER>=70 && _MSVCR_VER<=71 */
330
331#if _MSVCR_VER>=110
332/*********************************************************************
333 * __crtSetUnhandledExceptionFilter (MSVCR110.@)
334 */
335LPTOP_LEVEL_EXCEPTION_FILTER CDECL MSVCR110__crtSetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER filter)
336{
338}
339#endif
340
341/*********************************************************************
342 * _CreateFrameInfo (MSVCR80.@)
343 */
345{
347
348 TRACE("(%p, %p)\n", fi, obj);
349
350 fi->next = data->frame_info_head;
351 data->frame_info_head = fi;
352 fi->object = obj;
353 return fi;
354}
355
356/*********************************************************************
357 * _FindAndUnlinkFrame (MSVCR80.@)
358 */
360{
362 frame_info *cur = data->frame_info_head;
363
364 TRACE("(%p)\n", fi);
365
366 if (cur == fi)
367 {
368 data->frame_info_head = cur->next;
369 return;
370 }
371
372 for (; cur->next; cur = cur->next)
373 {
374 if (cur->next == fi)
375 {
376 cur->next = fi->next;
377 return;
378 }
379 }
380
381 ERR("frame not found, native crashes in this case\n");
382}
383
384/*********************************************************************
385 * _IsExceptionObjectToBeDestroyed (MSVCR80.@)
386 */
388{
390
391 TRACE( "%p\n", obj );
392
393 for (cur = msvcrt_get_thread_data()->frame_info_head; cur; cur = cur->next)
394 {
395 if (cur->object == obj)
396 return FALSE;
397 }
398
399 return TRUE;
400}
401
402/*********************************************************************
403 * __DestructExceptionObject (MSVCRT.@)
404 */
406{
408 void *object = (void*)rec->ExceptionInformation[1];
409
410 TRACE("(%p)\n", rec);
411
412 if (rec->ExceptionCode != CXX_EXCEPTION) return;
413#ifndef __x86_64__
414 if (rec->NumberParameters != 3) return;
415#else
416 if (rec->NumberParameters != 4) return;
417#endif
420
421 if (!info || !info->destructor)
422 return;
423
424#if defined(__i386__)
425#ifdef _MSC_VER
426 ((void(__fastcall*)(void*))info->destructor)(object);
427#else
428 __asm__ __volatile__("call *%0" : : "r" (info->destructor), "c" (object) : "eax", "edx", "memory");
429#endif
430#elif defined(__x86_64__)
431 ((void (__cdecl*)(void*))(info->destructor+rec->ExceptionInformation[3]))(object);
432#else
433 ((void (__cdecl*)(void*))info->destructor)(object);
434#endif
435}
436
437/*********************************************************************
438 * __CxxRegisterExceptionObject (MSVCRT.@)
439 */
441{
443
444 TRACE("(%p, %p)\n", ep, frame_info);
445
446 if (!ep || !ep->ExceptionRecord)
447 {
448 frame_info->rec = (void*)-1;
449 frame_info->context = (void*)-1;
450 return TRUE;
451 }
452
453 frame_info->rec = data->exc_record;
454 frame_info->context = data->ctx_record;
455 data->exc_record = ep->ExceptionRecord;
456 data->ctx_record = ep->ContextRecord;
458 return TRUE;
459}
460
461/*********************************************************************
462 * __CxxUnregisterExceptionObject (MSVCRT.@)
463 */
465{
467
468 TRACE("(%p)\n", frame_info);
469
470 if(frame_info->rec == (void*)-1)
471 return;
472
473 _FindAndUnlinkFrame(&frame_info->frame_info);
474 if(data->exc_record->ExceptionCode == CXX_EXCEPTION && !in_use
475 && _IsExceptionObjectToBeDestroyed((void*)data->exc_record->ExceptionInformation[1]))
476 __DestructExceptionObject(data->exc_record);
477 data->exc_record = frame_info->rec;
478 data->ctx_record = frame_info->context;
479}
480
482 char *what;
484};
485
486#if _MSVCR_VER>=140
487
488/*********************************************************************
489 * __std_exception_copy (UCRTBASE.@)
490 */
491void CDECL MSVCRT___std_exception_copy(const struct __std_exception_data *src,
493{
494 TRACE("(%p %p)\n", src, dst);
495
496 if(src->dofree && src->what) {
497 dst->what = MSVCRT__strdup(src->what);
498 dst->dofree = 1;
499 } else {
500 dst->what = src->what;
501 dst->dofree = 0;
502 }
503}
504
505/*********************************************************************
506 * __std_exception_destroy (UCRTBASE.@)
507 */
508void CDECL MSVCRT___std_exception_destroy(struct __std_exception_data *data)
509{
510 TRACE("(%p)\n", data);
511
512 if(data->dofree)
513 MSVCRT_free(data->what);
514 data->what = NULL;
515 data->dofree = 0;
516}
517
518/*********************************************************************
519 * __current_exception (UCRTBASE.@)
520 */
521void** CDECL __current_exception(void)
522{
523 TRACE("()\n");
524 return (void**)&msvcrt_get_thread_data()->exc_record;
525}
526
527/*********************************************************************
528 * __current_exception_context (UCRTBASE.@)
529 */
530void** CDECL __current_exception_context(void)
531{
532 TRACE("()\n");
533 return (void**)&msvcrt_get_thread_data()->ctx_record;
534}
535
536/*********************************************************************
537 * __processing_throw (UCRTBASE.@)
538 */
539int* CDECL __processing_throw(void)
540{
541 TRACE("()\n");
542 return &msvcrt_get_thread_data()->processing_throw;
543}
544
545#endif /* _MSVCR_VER>=140 */
#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:33
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define except(x)
Definition: btrfs_drv.h:136
#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:7482
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 EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:87
#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 MSVCRT__exit
Definition: winternl.h:310
static PVOID ptr
Definition: dispmode.c:27
#define __fastcall
Definition: sync.c:38
#define MSVCRT__FPE_INVALID
Definition: msvcrt.h:803
#define MSVCRT_SIGSEGV
Definition: msvcrt.h:791
#define MSVCRT_SIG_ERR
Definition: msvcrt.h:801
#define MSVCRT_SIG_IGN
Definition: msvcrt.h:800
void(__cdecl * MSVCRT_security_error_handler)(int, void *)
Definition: msvcrt.h:89
#define MSVCRT__FPE_DENORMAL
Definition: msvcrt.h:804
#define MSVCRT_NSIG
Definition: msvcrt.h:795
char *__cdecl MSVCRT__strdup(const char *)
#define MSVCRT_SIGTERM
Definition: msvcrt.h:792
#define MSVCRT__FPE_ZERODIVIDE
Definition: msvcrt.h:805
#define MSVCRT__FPE_EXPLICITGEN
Definition: msvcrt.h:813
void(__cdecl * MSVCRT___sighandler_t)(int)
Definition: msvcrt.h:797
#define MSVCRT_SIGILL
Definition: msvcrt.h:789
#define MSVCRT_SIGBREAK
Definition: msvcrt.h:793
#define MSVCRT_SIGFPE
Definition: msvcrt.h:790
#define MSVCRT__FPE_UNDERFLOW
Definition: msvcrt.h:807
#define MSVCRT__FPE_INEXACT
Definition: msvcrt.h:808
#define MSVCRT__FPE_OVERFLOW
Definition: msvcrt.h:806
#define MSVCRT_SIGABRT
Definition: msvcrt.h:794
#define MSVCRT_SIGINT
Definition: msvcrt.h:788
#define MSVCRT__FPE_STACKOVERFLOW
Definition: msvcrt.h:811
thread_data_t * msvcrt_get_thread_data(void)
Definition: tls.c:31
#define MSVCRT_SIG_DFL
Definition: msvcrt.h:799
long LONG
Definition: pedump.c:60
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tmov %rdx, %rbp\n" "\tjmp *%rax\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
#define MSVCRT_free
Definition: msvcrt.h:152
BOOL CDECL MSVCRT___uncaught_exception(void)
Definition: except.c:295
void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
Definition: except.c:405
NTSTATUS status
Definition: except.c:81
void **CDECL MSVCRT___pxcptinfoptrs(void)
Definition: except.c:71
static const struct @4317 float_exception_map[]
frame_info *CDECL _CreateFrameInfo(frame_info *fi, void *obj)
Definition: except.c:344
void msvcrt_free_signals(void)
Definition: except.c:183
int CDECL MSVCRT_raise(int sig)
Definition: except.c:225
static LONG msvcrt_exception_filter(struct _EXCEPTION_POINTERS *except)
Definition: except.c:93
void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_use)
Definition: except.c:464
BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_POINTERS *ep, cxx_frame_info *frame_info)
Definition: except.c:440
int CDECL _XcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr)
Definition: except.c:274
int signal
Definition: except.c:82
void(CDECL * float_handler)(int, int)
Definition: except.c:76
MSVCRT___sighandler_t CDECL MSVCRT_signal(int sig, MSVCRT___sighandler_t func)
Definition: except.c:193
int CDECL _abnormal_termination(void)
Definition: except.c:285
void msvcrt_init_signals(void)
Definition: except.c:178
static MSVCRT___sighandler_t sighandlers[MSVCRT_NSIG]
Definition: except.c:48
void CDECL _FindAndUnlinkFrame(frame_info *fi)
Definition: except.c:359
static BOOL WINAPI msvcrt_console_handler(DWORD ctrlType)
Definition: except.c:50
BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj)
Definition: except.c:387
unsigned char MSVCRT_bool
Definition: msvcrt.h:68
#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
MSVCRT_bool dofree
Definition: except.c:483
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:1453
#define EXCEPTION_FLT_STACK_CHECK
Definition: winbase.h:321
#define EXCEPTION_FLT_UNDERFLOW
Definition: winbase.h:322
#define EXCEPTION_FLT_OVERFLOW
Definition: winbase.h:320
#define EXCEPTION_FLT_DENORMAL_OPERAND
Definition: winbase.h:316
#define EXCEPTION_FLT_INEXACT_RESULT
Definition: winbase.h:318
#define EXCEPTION_ILLEGAL_INSTRUCTION
Definition: winbase.h:327
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:311
#define EXCEPTION_FLT_INVALID_OPERATION
Definition: winbase.h:319
#define EXCEPTION_PRIV_INSTRUCTION
Definition: winbase.h:325
#define EXCEPTION_FLT_DIVIDE_BY_ZERO
Definition: winbase.h:317
#define CTRL_C_EVENT
Definition: wincon.h:68
#define WINAPI
Definition: msvc.h:6