msvcrt: Add support for VC7 and VC8 extensions to the C++ exception handler.

This commit is contained in:
Alexandre Julliard 2010-04-13 17:21:06 +02:00
parent 300978283a
commit 5807b5e55c
5 changed files with 29 additions and 13 deletions

View File

@ -118,8 +118,8 @@
@ cdecl __CxxDetectRethrow(ptr) msvcrt.__CxxDetectRethrow
@ stub __CxxExceptionFilter
@ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ stub __CxxFrameHandler2
@ stub __CxxFrameHandler3
@ cdecl -i386 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ cdecl -i386 -norelay __CxxFrameHandler3(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ stdcall -i386 __CxxLongjmpUnwind(ptr) msvcrt.__CxxLongjmpUnwind
@ cdecl __CxxQueryExceptionSize() msvcrt.__CxxQueryExceptionSize
@ stub __CxxRegisterExceptionObject

View File

@ -115,8 +115,8 @@
@ cdecl __CxxDetectRethrow(ptr) msvcrt.__CxxDetectRethrow
@ stub __CxxExceptionFilter
@ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ stub __CxxFrameHandler2
@ stub __CxxFrameHandler3
@ cdecl -i386 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ cdecl -i386 -norelay __CxxFrameHandler3(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ stdcall -i386 __CxxLongjmpUnwind(ptr) msvcrt.__CxxLongjmpUnwind
@ cdecl __CxxQueryExceptionSize() msvcrt.__CxxQueryExceptionSize
@ stub __CxxRegisterExceptionObject

View File

@ -138,6 +138,10 @@ static void dump_function_descr( const cxx_function_descr *descr )
ptr->type_info, dbgstr_type_info( ptr->type_info ) );
}
}
if (descr->magic <= CXX_FRAME_MAGIC_VC6) return;
TRACE( "expect list: %p\n", descr->expect_list );
if (descr->magic <= CXX_FRAME_MAGIC_VC7) return;
TRACE( "flags: %08x\n", descr->flags );
}
/* check if the exception type is caught by a given catch block, and return the type that matched */
@ -363,11 +367,16 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame
{
cxx_exception_type *exc_type;
if (descr->magic != CXX_FRAME_MAGIC)
if (descr->magic < CXX_FRAME_MAGIC_VC6 || descr->magic > CXX_FRAME_MAGIC_VC8)
{
ERR( "invalid frame magic %x\n", descr->magic );
return ExceptionContinueSearch;
}
if (descr->magic >= CXX_FRAME_MAGIC_VC8 &&
(descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
(rec->ExceptionCode != CXX_EXCEPTION))
return ExceptionContinueSearch; /* handle only c++ exceptions */
if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND))
{
if (descr->unwind_count && !nested_trylevel) cxx_local_unwind( frame, descr, -1 );
@ -379,7 +388,7 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame
{
exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
if (rec->ExceptionInformation[0] > CXX_FRAME_MAGIC &&
if (rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8 &&
exc_type->custom_handler)
{
return exc_type->custom_handler( rec, frame, context, dispatch,
@ -466,7 +475,7 @@ void CDECL _CxxThrowException( exception *object, const cxx_exception_type *type
{
ULONG_PTR args[3];
args[0] = CXX_FRAME_MAGIC;
args[0] = CXX_FRAME_MAGIC_VC6;
args[1] = (ULONG_PTR)object;
args[2] = (ULONG_PTR)type;
RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args );
@ -486,7 +495,7 @@ BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
if (rec->ExceptionCode == CXX_EXCEPTION &&
rec->NumberParameters == 3 &&
rec->ExceptionInformation[0] == CXX_FRAME_MAGIC &&
rec->ExceptionInformation[0] == CXX_FRAME_MAGIC_VC6 &&
rec->ExceptionInformation[2])
{
ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;

View File

@ -21,8 +21,10 @@
#ifndef __MSVCRT_CPPEXCEPT_H
#define __MSVCRT_CPPEXCEPT_H
#define CXX_FRAME_MAGIC 0x19930520
#define CXX_EXCEPTION 0xe06d7363
#define CXX_FRAME_MAGIC_VC6 0x19930520
#define CXX_FRAME_MAGIC_VC7 0x19930521
#define CXX_FRAME_MAGIC_VC8 0x19930522
#define CXX_EXCEPTION 0xe06d7363
typedef void (*vtable_ptr)(void);
@ -87,9 +89,14 @@ typedef struct __cxx_function_descr
const unwind_info *unwind_table; /* array of unwind handlers */
UINT tryblock_count; /* number of try blocks */
const tryblock_info *tryblock; /* array of try blocks */
UINT unknown[3];
UINT ipmap_count;
const void *ipmap;
const void *expect_list; /* expected exceptions list when magic >= VC7 */
UINT flags; /* flags when magic >= VC8 */
} cxx_function_descr;
#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs) */
typedef void (*cxx_copy_ctor)(void);
/* offsets for computing the this pointer */

View File

@ -114,8 +114,8 @@
@ cdecl __CxxDetectRethrow(ptr)
# stub __CxxExceptionFilter
@ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr)
# stub __CxxFrameHandler2
# stub __CxxFrameHandler3
@ cdecl -i386 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler
@ cdecl -i386 -norelay __CxxFrameHandler3(ptr ptr ptr ptr) __CxxFrameHandler
@ stdcall -arch=x86_64 __C_specific_handler(ptr long ptr ptr) ntdll.__C_specific_handler
@ stdcall -i386 __CxxLongjmpUnwind(ptr)
@ cdecl __CxxQueryExceptionSize()