⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frame.cpp

📁 不错的东西 请查看 WINCE OS
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/***
*frame.cpp - The frame handler and everything associated with it.
*
*
*Purpose:
*       The frame handler and everything associated with it.
*
*       Entry points:
*       _CxxFrameHandler   - the frame handler.
*
****/

#include "kernel.h"
#include "excpt.h"

#include "corecrtstorage.h"
#include "corecrt.h"
#include <mtdll.h>      // CRT internal header file
#include <ehdata.h>     // Declarations of all types used for EH
#include <trnsctrl.h>   // Routines to handle transfer of control
#include <ehstate.h>    // Declarations of state management stuff
#include <exception>    // User-visible routines for eh
#include <ehhooks.h>    // Declarations of hook variables and callbacks
#include <ehglobs.h>    // EH global variables
#include <coredll.h>    // Define debug zone information

#pragma hdrstop         // PCH is created from here

// define CC_OUTERTRY for all platforms that use smd directory
#define CC_OUTERTRY


#if defined(_X86_)
#define __OffsetToAddress(a, b, c)  OffsetToAddress(a, b)
#define DC_CONTEXTRECORD(pDC) (NULL)
#else
#define __OffsetToAddress(a, b, c)  _OffsetToAddress(a, b, c)
#define DC_CONTEXTRECORD(pDC) (pDC->ContextRecord)
#endif

////////////////////////////////////////////////////////////////////////////////
//
// Forward declaration of local functions:
//

// M00TODO: all these parameters should be declared const

extern "C" void __FrameUnwindToState(
    EHRegistrationNode *,
    PDISPATCHER_CONTEXT,
    FuncInfo *,
    __ehstate_t
    );

static BOOLEAN FindHandler(
    EHExceptionRecord *,
    EHRegistrationNode *,
    CONTEXT *,
    PDISPATCHER_CONTEXT,
    FuncInfo *,
    int
    );

static void * CallCatchBlock(
    EHExceptionRecord *,
    EHRegistrationNode *,
    CONTEXT *,
    FuncInfo *,
    void *,
    int,
    unsigned long
    );

static void BuildCatchObject(
    EHExceptionRecord *,
    EHRegistrationNode *,
    HandlerType *,
    CatchableType *
    );

static __inline int TypeMatch(
    HandlerType *,
    CatchableType *,
    ThrowInfo *
    );

static void * AdjustPointer(
    void *,
    const PMD&
    );

static int FrameUnwindFilter(
    EXCEPTION_POINTERS *
    );

static BOOLEAN CanThisExceptionObjectBeDestructed(
    EHExceptionRecord *pExcept, 
    BOOLEAN abnormalTermination
    );

////////////////////////////////////////////////////////////////////////////////
//
// __InternalCxxFrameHandler - the frame handler for all functions with C++ EH
// information.
//
// If exception is handled, this doesn't return; otherwise, it returns
// ExceptionContinueSearch.
//
//

extern "C" EXCEPTION_DISPOSITION __cdecl __InternalCxxFrameHandler(
    EHExceptionRecord  *pExcept,        // Information for this exception
    EHRegistrationNode *pRN,            // Dynamic information for this frame
    CONTEXT            *pContext,       // Context info
    PDISPATCHER_CONTEXT pDC,            // Context within subject frame
    FuncInfo           *pFuncInfo,      // Static information for this frame
    int CatchDepth                      // How deeply nested are we?
    ) 
{
    DEBUGMSG(DBGEH,(TEXT("__InternalCxxFrameHandler: ENTER\r\n")));

    DEBUGCHK(FUNC_MAGICNUM(*pFuncInfo) == EH_MAGIC_NUMBER1);

    DEBUGMSG(DBGEH,(TEXT("__InternalCxxFrameHandler: pExcept=%08x pFuncInfo=%08x  pRN=%08x  CatchDepth=%d\r\n"), 
                    pExcept, pFuncInfo, pRN, CatchDepth));
    DEBUGMSG(DBGEH,(TEXT("__InternalCxxFrameHandler:                  ExceptionCode=%08x  ExceptionFlags=%08x\r\n"),
                    pExcept->ExceptionCode, pExcept->ExceptionFlags));
    DEBUGMSG(DBGEH,(TEXT("__InternalCxxFrameHandler:                  pDC->ControlPc=%08x\r\n"),
                    pDC->ControlPc));
    DEBUGMSG(DBGEH,(TEXT("__InternalCxxFrameHandler:                  pExceptionObject=%08x pThrowInfo= %08x\r\n"),
                    PER_PEXCEPTOBJ(pExcept), PER_PTHROW(pExcept)));

    
    if (IS_UNWINDING(PER_FLAGS(pExcept)))
    {
        // We're at the unwinding stage of things.  Don't care about the
        // exception itself.

        DEBUGMSG(DBGEH,(TEXT("__InternalCxxFrameHandler: unwinding ...\r\n")));

        if ( IS_TARGET_UNWIND(PER_FLAGS(pExcept) )){

            DEBUGMSG(DBGEH,(TEXT("__InternalCxxFrameHandler: IS_TARGET_UNWIND\r\n")));

            __ehstate_t targetState = TBME_LOW(*TargetEntry);

            DEBUGMSG(DBGEH,(TEXT("__InternalCxxFrameHandler:               targetState=%d from TargetEntry=%08x\r\n"),
                            targetState, TargetEntry));

            __FrameUnwindToState(pRN, pDC, pFuncInfo, targetState);
#if defined(_X86_)
            SetState(pRN, TBME_HIGH(*TargetEntry)+1);
#endif // _X86_

            DEBUGMSG(DBGEH,(TEXT("__InternalCxxFrameHandler: after unwind, call CallCatchBlock\r\n")));

            void * continuationAddress 
                = CallCatchBlock(pExcept,
                                 pRN,
                                 pContext,
                                 pFuncInfo,
                                 (void *)CONTEXT_TO_PROGRAM_COUNTER(pContext),
                                 CatchDepth,  0x100);
            DEBUGMSG(DBGEH,(TEXT("from CallCatchBlock: continuationAddress %08x\r\n"),
                            continuationAddress));
            CONTEXT_TO_PROGRAM_COUNTER(pContext) = (ULONG)continuationAddress;
        } else if (
#ifdef _X86_
          FUNC_MAXSTATE(*pFuncInfo) != 0 && CatchDepth == 0
#else
          FUNC_MAXSTATE(*pFuncInfo) != 0
#endif // _X86_
            ) {
            // Only unwind if there's something to unwind
            DEBUGMSG(DBGEH,(TEXT("InternalCxxFrameHandler: Unwind to empty state\n")));

            __FrameUnwindToState(pRN, pDC, pFuncInfo, EH_EMPTY_STATE);
        }

    } else if (FUNC_NTRYBLOCKS(*pFuncInfo) != 0) {

        //
        //  If try blocks are present, search for a handler:
        //

        DEBUGMSG(DBGEH,(TEXT("InternalCxxFrameHandler: NTRYBLOCKS=%d\r\n"),
                        FUNC_NTRYBLOCKS(*pFuncInfo)));

        DEBUGMSG(DBGEH,(TEXT("InternalCxxFrameHandler: call FindHandler\r\n")));

        if ( FindHandler(pExcept, pRN, pContext, pDC, pFuncInfo, CatchDepth) ) {
            DEBUGMSG(DBGEH,(TEXT("InternalCxxFrameHandler: EXIT with pExcept(%08x): Handler Found %08x\n"),
                            pExcept, pDC->ControlPc));
            return ExceptionExecuteHandler;
        }

        // If it returned FALSE, we didn't have any matches.
        DEBUGMSG(DBGEH,(TEXT("InternalCxxFrameHandler: No Handler Found\r\n")));
    } 

    // We had nothing to do with it or it was rethrown.  Keep searching.
    DEBUGMSG(DBGEH,(TEXT("InternalCxxFrameHandler EXIT with pExcept(%08x): ExceptionContinueSearch\r\n"), pExcept));

    return ExceptionContinueSearch;

} // InternalCxxFrameHandler


#ifndef _X86_

//
// __CxxFrameHandler - Real entry point to the runtime
//
extern "C" _CRTIMP EXCEPTION_DISPOSITION __CxxFrameHandler(
    EHExceptionRecord  *pExcept,           // Information for this exception
    EHRegistrationNode *pRN,               // Dynamic information for this frame
    CONTEXT            *pContext,          // Context info
    PDISPATCHER_CONTEXT pDC                // More dynamic info for this frame
    ) 
{
    FuncInfo   *pFuncInfo;
    EXCEPTION_DISPOSITION result;

    pFuncInfo = (FuncInfo*)pDC->FunctionEntry->HandlerData;

    result = __InternalCxxFrameHandler(pExcept, pRN, pContext, pDC, pFuncInfo, 0);

    return result;

} // __CxxFrameHandler

#endif // ifndef _X86_



////////////////////////////////////////////////////////////////////////////////
//
// FindHandler - find a matching handler on this frame, using all means
// available.
//
// Description:
//     If the exception thrown was an MSC++ EH, search handlers for match.
//     Otherwise, if we haven't already recursed, try to translate.
//     If we have recursed (ie we're handling the translator's exception), and
//         it isn't a typed exception, call _inconsistency.
//
// Returns:
//      Returns TRUE if a handler was found
//
// Assumptions:
//      Only called if there are handlers in this function.

static BOOLEAN FindHandler(
    EHExceptionRecord  *pExcept,     // Information for this (logical) exception
    EHRegistrationNode *pRN,         // Dynamic information for subject frame
    CONTEXT            *pContext,    // Context info
    PDISPATCHER_CONTEXT pDC,         // Context within subject frame
    FuncInfo           *pFuncInfo,   // Static information for subject frame
    int                 CatchDepth   // Level of nested catch that is being checked
    )
{
    BOOLEAN Found = FALSE;

    EHExceptionRecord *pNewExcept = pExcept ;
    EHExceptionRecord *pRethrowException = NULL ;

    // Get the current state (machine-dependent)
    __ehstate_t curState = GetCurrentState(pRN, pDC, pFuncInfo);
    DEBUGMSG(DBGEH,(TEXT("FindHandler: curState=GetCurrentState=%d\r\n"), curState));

    DEBUGCHK(curState >= EH_EMPTY_STATE && curState < FUNC_MAXSTATE(*pFuncInfo));

    // Check if it's a re-throw ( ie. no new object to throw ).  
    // Use the exception we stashed away if it is.
    if (PER_IS_MSVC_EH(pExcept) && PER_PTHROW(pExcept) == NULL) {

        DEBUGMSG(DBGEH,(TEXT("FindHandler: pExcept(0x%08x) is a rethrow of _pCurrentException(0x%08x)\r\n"),
                             pExcept, _pCurrentException));

        if (_pCurrentException == NULL) {
            // Oops!  User re-threw a non-existant exception!  Let it propogate.
            return FALSE;
        }

        if ( PER_PTHROW(_pCurrentException) == NULL) {
            DEBUGMSG(DBGEH,(TEXT("FindHandler: ThrowInfo is NULL\n"))) ;
#ifdef DBGEH
            _exit (3) ;
#endif
        }

        pExcept = _pCurrentException;
        pContext = _pCurrentExContext;

        DEBUGMSG(DBGEH,(TEXT("FindHandler: reset pExcept=%08x pContext=%08x from _pCurrentException\r\n"),
                        pExcept, pContext));

        pRethrowException = pExcept;
        DEBUGMSG(DBGEH,(TEXT("FindHandler: rethrow: setting pRethrowException=%08x\r\n"),
                        pRethrowException));

        DEBUGCHK(!PER_IS_MSVC_EH(pExcept) || PER_PTHROW(pExcept) != NULL);
    }

#if !defined(_X86_)

    FRAMEINFO *pFrameInfo;

    if (pFrameInfo = FindFrameInfo(pRN))
    {
        //
        //  This frame called a catch block (after unwinding). reset curState
        //  to the state reached when the unwind occurred. NestLevel is the
        //  nesting level of the called catch block. This frame's nest level
        //  is one less.
        //

        curState = pFrameInfo->state;
        CatchDepth = pFrameInfo->NestLevel - 1;
        DEBUGMSG(DBGEH,(TEXT("FindHandler: from FindFrameInfo : curState: %d CatchDepth: %d "), 
                        curState, CatchDepth));
        DEBUGMSG(DBGEH,(TEXT(" FindHandler: pFrameInfo->pRN : %8.8x pFrameInfo->pCatchRN : %8.8lx\r\n"),
                        pFrameInfo->pRN, pFrameInfo->pCatchRN));

    } else if ( pFrameInfo = FindCatchFrameInfo(pRN))
    {
        //
        //  This frame is a catch block which called a nested catch block.
        //  Dispatch based on the nested block's level.
        //

        CatchDepth = pFrameInfo->NestLevel;
        DEBUGMSG(DBGEH,(TEXT("FindHandler: from FindCatchFrameInfo: curState: %d CatchDepth: %d "), 
                        curState, CatchDepth));
        DEBUGMSG(DBGEH,(TEXT("FindHandler:  pFrameInfo->pRN : %8.8x pFrameInfo->pCatchRN : %8.8lx\r\n"),
                        pFrameInfo->pRN, pFrameInfo->pCatchRN));
    } else 
    {
        DEBUGMSG(DBGEH,(TEXT("FindHandler: ====Couldn't find FrameInfo/CatchFrameInfo from pFrameInfoChain(%08x)\r\n"), pFrameInfoChain));
        DEBUGMSG(DBGEH,(TEXT("FindHandler: with pRN=%8.8x CatchDepth=%d curState=%d===\r\n"), 
                        pRN, CatchDepth, curState));
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -