繁体   English   中英

Windows 64位VectoredExceptionHandler中的C ++ RTTI,MS Visual Studio 2015

[英]C++ RTTI in a Windows 64-bit VectoredExceptionHandler, MS Visual Studio 2015

我正在研究小型Windows异常处理引擎,试图从系统中收集最大的信息,包括C ++异常RTTI。

在MSVS 2015编译的32位VectoredExceptionHandler中,我成功地获取了std :: type_info指针,指向抛出类型的RTTI。 它很容易找到((_ThrowInfo*) ExceptionPointers->ExceptionRecord->ExceptionInformation[2])->pCatchableTypeArray->arrayOfCatchableTypes[0] (参见Raymond Chen的经典文章, MS的ehdata.h文件中的一些定义以及许多其他文件)。 此方法基于获取由编译器构建的MSVC内置_ThrowInfo结构数据的pCatchableTypeArray成员。

但是在64位环境中, _ThrowInfo包含直接RTTI:遗憾的是, pCatchableTypeArray为NULL。 在反汇编窗口中,我看到它甚至在调用_CxxThrowException ,主MS throw-handler之前就是NULL。 我搜索了一些关于MSVC中使用的新64位异常处理机制的文章,但是没有关于RTTI的信息。 但也许我错过了什么。

有没有办法获得在64位MSVC环境中工作的向量异常处理程序中抛出的C ++异常的std :: type_info(或简单类型名称)?

这是转储32位和64位异常信息的输出:

32位(RTTI成功):

VectoredExceptionHandler(): Start

exc->ExceptionCode               = 0xE06D7363
exc->ExceptionAddress            = 0x74E2C54F
exc->NumberParameters            = 3
exc->ExceptionInformation[0]     = 0x19930520 (sig)
exc->ExceptionInformation[1]     = 0x004FFD9C (object)
exc->ExceptionInformation[2]     = 0x003AD85C (throwInfo)
exc->ExceptionInformation[3]     = 0x005B18F8 (module)

throwInfo->attributes            = 0x00000000
throwInfo->pmfnUnwind            = 0x00000000
throwInfo->pForwardCompat        = 0x00000000
throwInfo->pCatchableTypeArray   = 0x003AD870

object    = 0x004FFD9C
throwInfo = 0x003AD85C
module    = 0x00000000

throwInfo->pCatchableTypeArray   = 0x003AD870
cArray                           = 0x003AD870

cArray->arrayOfCatchableTypes[0] = 0x003AD878
cType                            = 0x003AD878

cType->pType                     = 0x003AFA70
type                             = 0x003AFA70

type->name()                     = "struct `int __cdecl main(void)'::`2'::meow_exception"
cType->sizeOrOffset              = 4

VectoredExceptionHandler(): End

main(): catch (meow_exception { 3 })

64位(RTTI故障)

VectoredExceptionHandler(): Start

exc->ExceptionCode               = 0xE06D7363
exc->ExceptionAddress            = 0x000007FEFCE0A06D
exc->NumberParameters            = 4
exc->ExceptionInformation[0]     = 0x0000000019930520 (sig)
exc->ExceptionInformation[1]     = 0x000000000025FBE0 (object)
exc->ExceptionInformation[2]     = 0x000000013FC52AB0 (throwInfo)
exc->ExceptionInformation[3]     = 0x000000013FBE0000 (module)

module                           = 0x000000013FBE0000

throwInfo->attributes            = 0x00000000
throwInfo->pmfnUnwind            = 0x0000000000000000
throwInfo->pForwardCompat        = 0x0000000000072AD0
throwInfo->pCatchableTypeArray   = 0x0000000000000000

VectoredExceptionHandler(): End

main(): catch (meow_exception { 3 })

用于获取这些转储的代码:

#include <stdio.h>
#include <typeinfo>
#include <windows.h>

//--------------------------------------------------------------------------------------------------

const unsigned EXCEPTION_CPP_MICROSOFT                  = 0xE06D7363,  // '?msc'
               EXCEPTION_CPP_MICROSOFT_EH_MAGIC_NUMBER1 = 0x19930520,  // '?msc' version magic, see ehdata.h

               EXCEPTION_OUTPUT_DEBUG_STRING            = 0x40010006,  // OutputDebugString() call
               EXCEPTION_THREAD_NAME                    = 0x406D1388;  // Passing name of thread to the debugger

void OutputDebugPrintf (const char* format, ...);

//--------------------------------------------------------------------------------------------------

long WINAPI VectoredExceptionHandler (EXCEPTION_POINTERS* pointers)
    {
    const EXCEPTION_RECORD* exc = pointers->ExceptionRecord;

    if (exc->ExceptionCode == EXCEPTION_OUTPUT_DEBUG_STRING ||
        exc->ExceptionCode == EXCEPTION_THREAD_NAME)
        return EXCEPTION_CONTINUE_SEARCH;

    OutputDebugPrintf ("\n%s(): Start\n\n", __func__);

    OutputDebugPrintf ("exc->ExceptionCode    = 0x%X\n", exc->ExceptionCode);
    OutputDebugPrintf ("exc->ExceptionAddress = 0x%p\n", exc->ExceptionAddress);

    if (exc->ExceptionInformation[0] == EXCEPTION_CPP_MICROSOFT_EH_MAGIC_NUMBER1 && 
        exc->NumberParameters >= 3)
        {
        OutputDebugPrintf ("exc->NumberParameters = %u\n", exc->NumberParameters);

        OutputDebugPrintf ("exc->ExceptionInformation[0] = 0x%p (sig)\n",       (void*) exc->ExceptionInformation[0]);
        OutputDebugPrintf ("exc->ExceptionInformation[1] = 0x%p (object)\n",    (void*) exc->ExceptionInformation[1]);
        OutputDebugPrintf ("exc->ExceptionInformation[2] = 0x%p (throwInfo)\n", (void*) exc->ExceptionInformation[2]);
        OutputDebugPrintf ("exc->ExceptionInformation[3] = 0x%p (module)\n",    (void*) exc->ExceptionInformation[3]);
        OutputDebugPrintf ("\n");

        HMODULE module = (exc->NumberParameters >= 4)? (HMODULE) exc->ExceptionInformation[3] : NULL;

        if (module)
            {
            OutputDebugPrintf ("module = 0x%p\n", module);
            OutputDebugPrintf ("\n");
            }

        const _ThrowInfo* throwInfo = (const _ThrowInfo*) exc->ExceptionInformation[2];

        if (throwInfo)
            {
            OutputDebugPrintf ("throwInfo->attributes          = 0x%08X\n", throwInfo->attributes);
            OutputDebugPrintf ("throwInfo->pmfnUnwind          = 0x%p\n",   throwInfo->pmfnUnwind);
            OutputDebugPrintf ("throwInfo->pForwardCompat      = 0x%p\n",   throwInfo->pForwardCompat);
            OutputDebugPrintf ("throwInfo->pCatchableTypeArray = 0x%p\n",   throwInfo->pCatchableTypeArray);
            OutputDebugPrintf ("\n");
            }

        if (throwInfo && throwInfo->pCatchableTypeArray)
            {              
            #define RVA_TO_VA_(type, addr)  ( (type) ((uintptr_t) module + (uintptr_t) (addr)) )

            OutputDebugPrintf ("object    = 0x%p\n", (void*) exc->ExceptionInformation[1]);
            OutputDebugPrintf ("throwInfo = 0x%p\n", (void*) throwInfo);
            OutputDebugPrintf ("module    = 0x%p\n", (void*) module);
            OutputDebugPrintf ("\n");

            const _CatchableTypeArray* cArray = RVA_TO_VA_(const _CatchableTypeArray*, throwInfo->pCatchableTypeArray);

            OutputDebugPrintf ("throwInfo->pCatchableTypeArray = 0x%p\n",   (void*) throwInfo->pCatchableTypeArray);
            OutputDebugPrintf ("cArray                         = 0x%p\n\n", (void*) cArray);

            const _CatchableType* cType = RVA_TO_VA_(const _CatchableType*, cArray->arrayOfCatchableTypes[0]);

            OutputDebugPrintf ("cArray->arrayOfCatchableTypes[0] = 0x%p\n",   (void*) cArray->arrayOfCatchableTypes[0]);
            OutputDebugPrintf ("cType                            = 0x%p\n\n", (void*) cType);

            const std::type_info* type = RVA_TO_VA_(const std::type_info*, cType->pType);

            OutputDebugPrintf ("cType->pType = 0x%p\n",   (void*) cType->pType);
            OutputDebugPrintf ("type         = 0x%p\n\n", (void*) type);

            OutputDebugPrintf ("type->name()        = \"%s\"\n", type->name());
            OutputDebugPrintf ("cType->sizeOrOffset = %zu\n\n",  (size_t) cType->sizeOrOffset);

            #undef RVA_TO_VA_
            }
        }

    OutputDebugPrintf ("%s(): End\n", __func__);
    return EXCEPTION_CONTINUE_SEARCH;
    }

//--------------------------------------------------------------------------------------------------

void OutputDebugPrintf (const char* format, ...)
    {
    static char buf [1024] = "";

    va_list arg; va_start (arg, format);
    _vsnprintf_s (buf, sizeof (buf) - 1, _TRUNCATE, format, arg);
    va_end (arg);

    OutputDebugString (buf);
    printf ("%s", buf);
    }

//--------------------------------------------------------------------------------------------------

int main()
    {    
    OutputDebugPrintf ("\n%s(): Start\n", __func__);

    AddVectoredExceptionHandler (1, VectoredExceptionHandler);

    struct meow_exception { int code = 3; };

    try
        {
        throw meow_exception();
        }

    catch (const meow_exception& e)
        {
        OutputDebugPrintf ("\n%s(): catch (meow_exception { %d })\n", __func__, e.code);
        }

    catch (...)
        {
        OutputDebugPrintf ("\n%s(): catch (...)\n", __func__);
        }

    OutputDebugPrintf ("\n%s(): End\n", __func__);
    return 0;
    }

构建选项:

// Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24213.1 (part of VS 2015 SP3)

cl   /c code.cpp /EHsc /W4
link    code.obj kernel32.lib /machine:x86 /subsystem:console /debug

提前感谢您的答案和建议。

为了解决这个问题,我深入研究并发现了一些有关MSVC 64位模式的有趣事情。 我发现在64位模式下我们不能依赖内部编译器预定义类型,因为它们中的一些是错误的。

我比较了编译器预定义的一些内部结构的定义,例如_ThrowInfo_CatchableType ,以及编译器使用/FAs命令行开关运行生成的程序集列表。

以下是从汇编文件中提取的这些结构的实例(以下是MSVC 2015 64位版本):

;---------------------------------------------------------------------------------------
; Listing generated by Microsoft Optimizing Compiler Version 19.00.24213.1 
; Simplified: many lines skipped, some sections reordered etc -- Ded
;---------------------------------------------------------------------------------------

main proc

;   struct meow_exception { int code = 3; };
;   
;   try
;       {
;       throw meow_exception();

    ...
    lea  rdx, OFFSET FLAT:_TI1?AUmeow_exception@?1??main@@YAHXZ@  ; lea &_ThrowInfo
    lea  rcx, QWORD PTR $T1[rsp]
    call _CxxThrowException

;---------------------------------------------------------------------------------------
_TI1?AUmeow_exception@?1??main@@YAHXZ@                            ; _ThrowInfo
    DD  0
    DD  0
    DD  0
    DD  imagerel _CTA1?AUmeow_exception@?1??main@@YAHXZ@          ; &_CatchableTypeArray

;---------------------------------------------------------------------------------------
_CTA1?AUmeow_exception@?1??main@@YAHXZ@                           ; _CatchableTypeArray
    DD  1
    DD  imagerel _CT??_R0?AUmeow_exception@?1??main@@YAHXZ@@84    ; &_CatchableType

;---------------------------------------------------------------------------------------
_CT??_R0?AUmeow_exception@?1??main@@YAHXZ@@84                     ; _CatchableType
    DD  0
    DD  imagerel ??_R0?AUmeow_exception@?1??main@@YAHXZ@@8        ; &_TypeDescriptor
    DD  0
    DD  0ffffffffh
    ORG $+4
    DD  04h
    DD  0

;---------------------------------------------------------------------------------------
??_R0?AUmeow_exception@?1??main@@YAHXZ@@8         ; _TypeDescriptor (aka std::type_info)
    DQ  FLAT:??_7type_info@@6B@
    DQ  0
    DB  '.?AUmeow_exception@?1??main@@YAHXZ@', 0  ; Mangled type name

;---------------------------------------------------------------------------------------

的这些结构的32位版本的二进制布局类似于64位,有一些小的差异( FLAT改性剂代替imagerel在地址字段和DD代替DQ_TypeDescriptor )。

然后,让我们将此列表与从ehdata.h文件中获取的预定义类型进行比较(fe,请参阅Geoff ChappellC:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\crt\\src\\ehdata.h文件在MSVC 2013中;遗憾的是,该文件在MSVC 2015运行时源中不存在):

typedef const struct _s__ThrowInfo
    {
    unsigned int         attributes;
    _PMFN                pmfnUnwind;            // this is a pointer!
    int (__cdecl        *pForwardCompat) (...); // this is a pointer too!
    _CatchableTypeArray *pCatchableTypeArray;   // this is a pointer too!
    }
    _ThrowInfo;

typedef const struct _s__CatchableType
    {
    unsigned int     properties;
    _TypeDescriptor *pType;                     // this is a pointer too!
    _PMD             thisDisplacement;
    int              sizeOrOffset;
    _PMFN            copyFunction;              // this is a pointer too!
    }
    _CatchableType;

在32位模式下,一切正常,因为指针是32位,并且预定义的结构内部定义与汇编列表相对应。

在64位模式中,这些结构中的指针是从模块的图像库测量的RVAs(相对虚拟地址)。 这是已知且记录良好的特征; 它真正对应于上面的汇编程序列表。 请注意imagerel地址修饰符,这些修饰符指的是RVAs。 这些RVA是32位并定义为32位DD关键字。

但在64位模式下,从C ++端,相应的指针被认为是64位。 因此,包含指针的内部编译器结构的C ++二进制布局 (例如上面的_ThrowInfo_CatchableType与Assembler二进制布局不对应。 从C ++方面来看,这些结构的大小更大,而字段偏移也是错误的。

为了测试这个,我定义了自己的自定义结构,使用相同的字段表示为32位整数类型而不是指针:

namespace CORRECT
    {
    struct ThrowInfo
        {
        __int32 attributes;
        __int32 pmfnUnwind;           // now this is 32-bit RVA
        __int32 pForwardCompat;       // now this is 32-bit RVA
        __int32 pCatchableTypeArray;  // now this is 32-bit RVA
        };

    struct CatchableType
        {
        __int32 properties;
        __int32 pType;                // now this is 32-bit RVA
        _PMD    thisDisplacement;
        __int32 sizeOrOffset;
        __int32 copyFunction;         // now this is 32-bit RVA
        };
    }

然后我使用内部定义和我自己的定义转储了_ThrowInfo_CatchableType的内容。 这是结果(MSVC 2015 64位):

exc->ExceptionCode               = 0xE06D7363
exc->ExceptionAddress            = 0x000007FEFD69A06D
exc->NumberParameters            = 4
exc->ExceptionInformation[0]     = 0x0000000019930520 (sig)
exc->ExceptionInformation[1]     = 0x00000000002BF8B0 (object)
exc->ExceptionInformation[2]     = 0x000000013F9C4210 (throwInfo)
exc->ExceptionInformation[3]     = 0x000000013F950000 (module)

Built-in: _ThrowInfo, size 28
_throwInfo->attributes           = 0x00000000 [ofs:  0, size: 4, type: unsigned int]
_throwInfo->pmfnUnwind           = 0x00000000 [ofs:  4, size: 8, type: void (__cdecl*)(void * __ptr64)]
_throwInfo->pForwardCompat       = 0x00074230 [ofs: 12, size: 8, type: int (__cdecl*)(void)]
_throwInfo->pCatchableTypeArray  = 0x00000000 [ofs: 20, size: 8, type: struct _s__CatchableTypeArray const * __ptr64]

Custom: CORRECT::ThrowInfo, size 16
throwInfo->attributes            = 0x00000000 [ofs:  0, size: 4, type: int]
throwInfo->pmfnUnwind            = 0x00000000 [ofs:  4, size: 4, type: int]
throwInfo->pForwardCompat        = 0x00000000 [ofs:  8, size: 4, type: int]
throwInfo->pCatchableTypeArray   = 0x00074230 [ofs: 12, size: 4, type: int]

throwInfo->pCatchableTypeArray   = 0x0000000000074230
cArray                           = 0x000000013F9C4230

Built-in: _CatchableType, size 36
_cType->properties               = 0x00000000 [ofs:  0, size: 4, type: unsigned int]
_cType->pType                    = 0x00075D58 [ofs:  4, size: 8, type: struct _TypeDescriptor * __ptr64]
_cType->thisDisplacement.mdisp   = 0xFFFFFFFF [ofs: 12, size: 4, type: int]
_cType->thisDisplacement.pdisp   = 0x00000000 [ofs: 16, size: 4, type: int]
_cType->thisDisplacement.vdisp   = 0x00000004 [ofs: 20, size: 4, type: int]
_cType->sizeOrOffset             = 0x00000000 [ofs: 24, size: 4, type: int]
_cType->copyFunction             = 0x00000000 [ofs: 28, size: 8, type: void (__cdecl*)(void * __ptr64)]

Custom: CORRECT::CatchableType, size 28
cType->properties                = 0x00000000 [ofs:  0, size: 4, type: int]
cType->pType                     = 0x00075D58 [ofs:  4, size: 4, type: int]
cType->thisDisplacement.mdisp    = 0x00000000 [ofs:  8, size: 4, type: int]
cType->thisDisplacement.pdisp    = 0xFFFFFFFF [ofs: 12, size: 4, type: int]
cType->thisDisplacement.vdisp    = 0x00000000 [ofs: 16, size: 4, type: int]
cType->sizeOrOffset              = 0x00000004 [ofs: 20, size: 4, type: int]
cType->copyFunction              = 0x00000000 [ofs: 24, size: 4, type: int]

cArray->arrayOfCatchableTypes[0] = 0x0000000000074240
cType                            = 0x000000013F9C4240

cType->pType                     = 0x0000000000075D58
type                             = 0x000000013F9C5D58

type->name()                     = "struct `int __cdecl main(void)'::`2'::meow_exception"
cType->sizeOrOffset              = 4

查看指针成员(8对4字节)和错误偏移的整个结构(28对16字节,36对28字节)的大小差异。

使用CORRECT:: definitions时,很容易获得所需的正确RTTI。

来自MSVC 2013运行时源的原始C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\crt\\src\\ehdata.h文件包含条件预处理程序指令#ifdef _EH_RELATIVE_OFFSETS ,它将指针替换为__int32偏移量。 但预定义的内部编译器类型始终包含64位错误指针。

因此, 在64位模式下使用RTTI结构的内部定义是不可靠的。 应该使用自己的定义,其中指针成员表示为32位整数 (或#define _EH_RELATIVE_OFFSETS并使用ehdata.h提到的ehdata.h )。 之后,不要忘记通过像往常一样添加ImageBase地址手动将ImageBase转换为常见的C ++指针。 但是, 在这样的结构和包含这样的指针的定义中, 人们不 应该信任指针成员,因为它们不能反映真正的64位二进制布局。

我用MSVC 2010测试了它得到了相同的结果。

以下是在64位MSVC环境中获取正确RTTI的代码:

#include <stdio.h>
#include <typeinfo>
#include <stdexcept>
#include <windows.h>

//------------------------------------------------------------------------------------------------------------------------------
//! These definitions are based on assembly listings produded by the compiler (/FAs) rather than built-in ones
//! @{

#pragma pack (push, 4)

namespace CORRECT
    {

    struct CatchableType
        {
        __int32 properties;
        __int32 pType;
        _PMD    thisDisplacement;
        __int32 sizeOrOffset;
        __int32 copyFunction;
        };

    struct ThrowInfo
        {
        __int32 attributes;
        __int32 pmfnUnwind;
        __int32 pForwardCompat;
        __int32 pCatchableTypeArray;
        };

    }

#pragma pack (pop)

//! @}
//------------------------------------------------------------------------------------------------------------------------------

const unsigned EXCEPTION_CPP_MICROSOFT                  = 0xE06D7363,  // '?msc'
               EXCEPTION_CPP_MICROSOFT_EH_MAGIC_NUMBER1 = 0x19930520,  // '?msc' version magic, see ehdata.h

               EXCEPTION_OUTPUT_DEBUG_STRING            = 0x40010006,  // OutputDebugString() call
               EXCEPTION_THREAD_NAME                    = 0x406D1388;  // Passing name of thread to the debugger

void OutputDebugPrintf (const char* format, ...);

//------------------------------------------------------------------------------------------------------------------------------

long WINAPI VectoredExceptionHandler (EXCEPTION_POINTERS* pointers)
    {
    const EXCEPTION_RECORD* exc = pointers->ExceptionRecord;

    if (exc->ExceptionCode == EXCEPTION_OUTPUT_DEBUG_STRING ||
        exc->ExceptionCode == EXCEPTION_THREAD_NAME)
        return EXCEPTION_CONTINUE_SEARCH;

    OutputDebugPrintf ("\n%s(): Start\n\n", __FUNCTION__);

    OutputDebugPrintf         ("exc->ExceptionCode               = 0x%X\n", exc->ExceptionCode);
    OutputDebugPrintf         ("exc->ExceptionAddress            = 0x%p\n", exc->ExceptionAddress);

    if (exc->ExceptionInformation[0] == EXCEPTION_CPP_MICROSOFT_EH_MAGIC_NUMBER1 && 
        exc->NumberParameters >= 3)
        {
        OutputDebugPrintf     ("exc->NumberParameters            = %u\n", exc->NumberParameters);

        OutputDebugPrintf     ("exc->ExceptionInformation[0]     = 0x%p (sig)\n",       (void*) exc->ExceptionInformation[0]);
        OutputDebugPrintf     ("exc->ExceptionInformation[1]     = 0x%p (object)\n",    (void*) exc->ExceptionInformation[1]);
        OutputDebugPrintf     ("exc->ExceptionInformation[2]     = 0x%p (throwInfo)\n", (void*) exc->ExceptionInformation[2]);

        if (exc->NumberParameters >= 4)
            OutputDebugPrintf ("exc->ExceptionInformation[3]     = 0x%p (module)\n",    (void*) exc->ExceptionInformation[3]);

        OutputDebugPrintf ("\n");

        HMODULE module = (exc->NumberParameters >= 4)? (HMODULE) exc->ExceptionInformation[3] : NULL;

        #define RVA_TO_VA_(type, addr)  ( (type) ((uintptr_t) module + (uintptr_t) (addr)) )

        const         _ThrowInfo* _throwInfo = (const         _ThrowInfo*) exc->ExceptionInformation[2];
        const CORRECT::ThrowInfo*  throwInfo = (const CORRECT::ThrowInfo*) exc->ExceptionInformation[2];

        #define DUMP_(var, struc, field)  OutputDebugPrintf ("%-32s = 0x%08X [ofs: %2u, size: %u, type: %s]\n",  \
                                                             #var "->" #field, (var)->field,                 \
                                                             offsetof (struc, field), sizeof ((var)->field), \
                                                             typeid ((var)->field) .name());
        if (_throwInfo)
            {
            OutputDebugPrintf ("Built-in: _ThrowInfo, size %u\n", sizeof (_ThrowInfo));
            DUMP_ (_throwInfo, _ThrowInfo, attributes);
            DUMP_ (_throwInfo, _ThrowInfo, pmfnUnwind);
            DUMP_ (_throwInfo, _ThrowInfo, pForwardCompat);
            DUMP_ (_throwInfo, _ThrowInfo, pCatchableTypeArray);
            OutputDebugPrintf ("\n");
            }
        else
            OutputDebugPrintf ("_throwInfo is NULL\n");

        if (throwInfo)
            {
            OutputDebugPrintf ("Custom: CORRECT::ThrowInfo, size %u\n", sizeof (CORRECT::ThrowInfo));
            DUMP_ ( throwInfo, CORRECT::ThrowInfo, attributes);
            DUMP_ ( throwInfo, CORRECT::ThrowInfo, pmfnUnwind);
            DUMP_ ( throwInfo, CORRECT::ThrowInfo, pForwardCompat);
            DUMP_ ( throwInfo, CORRECT::ThrowInfo, pCatchableTypeArray);
            OutputDebugPrintf ("\n");
            }
        else
            OutputDebugPrintf ("throwInfo is NULL\n");

        if (throwInfo)
            {              
            const _CatchableTypeArray* cArray = RVA_TO_VA_(const _CatchableTypeArray*, throwInfo->pCatchableTypeArray);

            OutputDebugPrintf ("throwInfo->pCatchableTypeArray   = 0x%p\n",   (void*)(ptrdiff_t) throwInfo->pCatchableTypeArray);
            OutputDebugPrintf ("cArray                           = 0x%p\n\n", (void*)            cArray);

            const         _CatchableType* _cType = RVA_TO_VA_(const         _CatchableType*, cArray->arrayOfCatchableTypes[0]);
            const CORRECT::CatchableType*  cType = RVA_TO_VA_(const CORRECT::CatchableType*, cArray->arrayOfCatchableTypes[0]);

            OutputDebugPrintf ("Built-in: _CatchableType, size %u\n", sizeof (_CatchableType));
            DUMP_ (_cType, _CatchableType, properties);
            DUMP_ (_cType, _CatchableType, pType);
            DUMP_ (_cType, _CatchableType, thisDisplacement.mdisp);
            DUMP_ (_cType, _CatchableType, thisDisplacement.pdisp);
            DUMP_ (_cType, _CatchableType, thisDisplacement.vdisp);
            DUMP_ (_cType, _CatchableType, sizeOrOffset);
            DUMP_ (_cType, _CatchableType, copyFunction);
            OutputDebugPrintf ("\n");

            OutputDebugPrintf ("Custom: CORRECT::CatchableType, size %u\n", sizeof (CORRECT::CatchableType));
            DUMP_ ( cType, CORRECT::CatchableType, properties);
            DUMP_ ( cType, CORRECT::CatchableType, pType);
            DUMP_ ( cType, CORRECT::CatchableType, thisDisplacement.mdisp);
            DUMP_ ( cType, CORRECT::CatchableType, thisDisplacement.pdisp);
            DUMP_ ( cType, CORRECT::CatchableType, thisDisplacement.vdisp);
            DUMP_ ( cType, CORRECT::CatchableType, sizeOrOffset);
            DUMP_ ( cType, CORRECT::CatchableType, copyFunction);
            OutputDebugPrintf ("\n");

            OutputDebugPrintf ("cArray->arrayOfCatchableTypes[0] = 0x%p\n",   (void*) cArray->arrayOfCatchableTypes[0]);
            OutputDebugPrintf ("cType                            = 0x%p\n\n", (void*) cType);

            const std::type_info* type = RVA_TO_VA_(const std::type_info*, cType->pType);

            OutputDebugPrintf ("cType->pType                     = 0x%p\n",   (void*)(ptrdiff_t) cType->pType);
            OutputDebugPrintf ("type                             = 0x%p\n\n", (void*)            type);

            OutputDebugPrintf ("type->name()                     = \"%s\"\n", type->name());
            OutputDebugPrintf ("cType->sizeOrOffset              = %u\n\n",   (unsigned) cType->sizeOrOffset);

            }

        #undef DUMP_
        #undef RVA_TO_VA_
        }

    OutputDebugPrintf ("%s(): End\n", __FUNCTION__);
    return EXCEPTION_CONTINUE_SEARCH;
    }

//------------------------------------------------------------------------------------------------------------------------------

void OutputDebugPrintf (const char* format, ...)
    {
    static char buf [1024] = "";

    va_list arg; va_start (arg, format);
    _vsnprintf_s (buf, sizeof (buf) - 1, _TRUNCATE, format, arg);
    va_end (arg);

    OutputDebugString (buf);
    printf ("%s", buf);
    }

//------------------------------------------------------------------------------------------------------------------------------

int main()
    {    
    OutputDebugPrintf ("\nCompiled with MSVC %d, %d-bit\n", _MSC_VER, 8 * sizeof (void*));
    OutputDebugPrintf ("\n%s(): Start\n", __FUNCTION__);

    AddVectoredExceptionHandler (1, VectoredExceptionHandler);

    struct meow_exception { int code; meow_exception() : code (3) {} };

    try
        {
        throw meow_exception();
        }

    catch (const meow_exception& e)
        {
        OutputDebugPrintf ("\n%s(): catch (meow_exception { %d })\n", __FUNCTION__, e.code);
        }

    catch (...)
        {
        OutputDebugPrintf ("\n%s(): catch (...)\n", __FUNCTION__);
        }

    OutputDebugPrintf ("\n%s(): End\n", __FUNCTION__);
    return 0;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM