ReactOS  0.4.15-dev-1177-g6cb3b62
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
45 static 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 */
79 static const struct
80 {
82  int signal;
83 } float_exception_map[] = {
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  */
225 int 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  */
305 MSVCRT_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  */
319 void 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  */
335 LPTOP_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 {
389  frame_info *cur;
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
419  rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8) return;
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;
457  _CreateFrameInfo(&frame_info->frame_info, (void*)ep->ExceptionRecord->ExceptionInformation[1]);
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  */
491 void CDECL MSVCRT___std_exception_copy(const struct __std_exception_data *src,
492  struct __std_exception_data *dst)
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  */
508 void 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  */
521 void** 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  */
530 void** 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  */
539 int* CDECL __processing_throw(void)
540 {
541  TRACE("()\n");
542  return &msvcrt_get_thread_data()->processing_throw;
543 }
544 
545 #endif /* _MSVCR_VER>=140 */
#define MSVCRT__FPE_DENORMAL
Definition: msvcrt.h:804
GLenum func
Definition: glext.h:6028
#define EXCEPTION_FLT_UNDERFLOW
Definition: winbase.h:319
Definition: comerr.c:44
static MSVCRT___sighandler_t sighandlers[MSVCRT_NSIG]
Definition: except.c:48
#define MSVCRT__FPE_EXPLICITGEN
Definition: msvcrt.h:813
#define MSVCRT_SIGINT
Definition: msvcrt.h:788
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define MSVCRT_free
Definition: msvcrt.h:152
#define __cdecl
Definition: accygwin.h:79
#define CXX_FRAME_MAGIC_VC6
Definition: cppexcept.h:26
#define __fastcall
Definition: sync.c:38
#define TRUE
Definition: types.h:120
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:308
int CDECL _XcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr)
Definition: except.c:274
LONG NTSTATUS
Definition: precomp.h:26
#define MSVCRT_SIG_ERR
Definition: msvcrt.h:801
#define CTRL_C_EVENT
Definition: wincon.h:68
void msvcrt_init_signals(void)
Definition: except.c:178
#define EXCEPTION_FLT_INVALID_OPERATION
Definition: winbase.h:316
void(__cdecl * MSVCRT___sighandler_t)(int)
Definition: msvcrt.h:797
int CDECL MSVCRT_raise(int sig)
Definition: except.c:225
int CDECL _abnormal_termination(void)
Definition: except.c:285
#define MSVCRT_SIG_DFL
Definition: msvcrt.h:799
void msvcrt_free_signals(void)
Definition: except.c:183
#define MSVCRT_SIGBREAK
Definition: msvcrt.h:793
#define MSVCRT__FPE_INEXACT
Definition: msvcrt.h:808
GLsizei GLsizei GLuint * obj
Definition: glext.h:6042
#define MSVCRT__FPE_INVALID
Definition: msvcrt.h:803
DWORD ExceptionCode
Definition: compat.h:208
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define CXX_FRAME_MAGIC_VC8
Definition: cppexcept.h:28
int signal
Definition: except.c:82
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
void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
Definition: except.c:405
#define MSVCRT_SIGSEGV
Definition: msvcrt.h:791
#define FALSE
Definition: types.h:117
void(CDECL * float_handler)(int, int)
Definition: except.c:76
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI DECLSPEC_HOTPATCH SetUnhandledExceptionFilter(IN LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
Definition: except.c:792
__asm__("\t.globl GetPhys\n" "GetPhys:\t\n" "mflr 0\n\t" "stwu 0,-16(1)\n\t" "mfmsr 5\n\t" "andi. 6,5,0xffef\n\t" "mtmsr 6\n\t" "isync\n\t" "sync\n\t" "lwz 3,0(3)\n\t" "mtmsr 5\n\t" "isync\n\t" "sync\n\t" "lwz 0,0(1)\n\t" "addi 1,1,16\n\t" "mtlr 0\n\t" "blr")
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2111
#define FIXME(fmt,...)
Definition: debug.h:111
static PVOID ptr
Definition: dispmode.c:27
WINE_DEFAULT_DEBUG_CHANNEL(seh)
BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj)
Definition: except.c:387
smooth NULL
Definition: ftsmooth.c:416
frame_info *CDECL _CreateFrameInfo(frame_info *fi, void *obj)
Definition: except.c:344
void CDECL _FindAndUnlinkFrame(frame_info *fi)
Definition: except.c:359
static const struct @4040 float_exception_map[]
char *__cdecl MSVCRT__strdup(const char *)
PCONTEXT ContextRecord
Definition: rtltypes.h:201
#define CXX_EXCEPTION
Definition: cppexcept.h:29
#define TRACE(s)
Definition: solgame.cpp:4
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
MSVCRT_bool dofree
Definition: except.c:483
#define EXCEPTION_FLT_DIVIDE_BY_ZERO
Definition: winbase.h:314
#define MSVCRT_SIG_IGN
Definition: msvcrt.h:800
#define WINAPI
Definition: msvc.h:6
void(__cdecl * MSVCRT_security_error_handler)(int, void *)
Definition: msvcrt.h:89
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MSVCRT__FPE_OVERFLOW
Definition: msvcrt.h:806
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define MSVCRT__FPE_STACKOVERFLOW
Definition: msvcrt.h:811
int ret
#define EXCEPTION_FLT_DENORMAL_OPERAND
Definition: winbase.h:313
#define MSVCRT_SIGTERM
Definition: msvcrt.h:792
#define MSVCRT_SIGFPE
Definition: msvcrt.h:790
#define except(x)
Definition: btrfs_drv.h:139
PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER
Definition: winbase.h:1419
GLenum src
Definition: glext.h:6340
static BOOL WINAPI msvcrt_console_handler(DWORD ctrlType)
Definition: except.c:50
#define MSVCRT__FPE_UNDERFLOW
Definition: msvcrt.h:807
Definition: inflate.c:139
thread_data_t * msvcrt_get_thread_data(void)
Definition: tls.c:31
BOOL CDECL MSVCRT___uncaught_exception(void)
Definition: except.c:295
#define MSVCRT_SIGILL
Definition: msvcrt.h:789
#define ERR(fmt,...)
Definition: debug.h:110
#define MSVCRT__exit
Definition: winternl.h:310
void **CDECL MSVCRT___pxcptinfoptrs(void)
Definition: except.c:71
#define CDECL
Definition: compat.h:29
NTSTATUS status
Definition: except.c:81
#define MSVCRT_NSIG
Definition: msvcrt.h:795
#define ARRAY_SIZE(a)
Definition: main.h:24
#define EXCEPTION_FLT_OVERFLOW
Definition: winbase.h:317
GLenum GLenum dst
Definition: glext.h:6340
#define EXCEPTION_FLT_STACK_CHECK
Definition: winbase.h:318
unsigned char MSVCRT_bool
Definition: msvcrt.h:68
#define EXCEPTION_ILLEGAL_INSTRUCTION
Definition: winbase.h:324
#define MSVCRT_SIGABRT
Definition: msvcrt.h:794
BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_POINTERS *ep, cxx_frame_info *frame_info)
Definition: except.c:440
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7786
DWORD NumberParameters
Definition: compat.h:212
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
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
void * object
Definition: jmemsys.h:48
#define EXCEPTION_PRIV_INSTRUCTION
Definition: winbase.h:322
#define EXCEPTION_FLT_INEXACT_RESULT
Definition: winbase.h:315
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define MSVCRT__FPE_ZERODIVIDE
Definition: msvcrt.h:805
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:87
MSVCRT___sighandler_t CDECL MSVCRT_signal(int sig, MSVCRT___sighandler_t func)
Definition: except.c:193
Definition: ps.c:97