Exemple #1
0
//
// __CxxFrameHandler - Real entry point to the runtime
//
extern "C" _CRTIMP EXCEPTION_DISPOSITION __CxxFrameHandler(
    EHExceptionRecord  *pExcept,       	// Information for this exception
    EHRegistrationNode *pFrame,        	// Dynamic information for this frame
	void			   *pContext,		// Context info
	DispatcherContext  *pDC				// More dynamic info for this frame
) {
	FuncInfo   *pFuncInfo;
	EXCEPTION_DISPOSITION result;
	PFRAMEINFO pframeinfo;
    

	if (!(IS_UNWINDING(PER_FLAGS(pExcept))) && ((unsigned long)pContext != (unsigned long)GetRTOC()) )
		{
		// we are calling catch from different CFM, re-initialize our globals
		_pFrameInfoChain =(PFRAMEINFO) pDC->pftinfo->pFrameInfo;
		_pftinfo->pFrameInfo = pDC->pftinfo->pFrameInfo;
		cNested = 0;
		pframeinfo = (PFRAMEINFO)_pftinfo->pFrameInfo;
		while (pframeinfo)
			{
			cNested++;
			pframeinfo = pframeinfo->pNext;
			}
		}
		
	pFuncInfo = (FuncInfo*)pDC->FunctionEntry->HandlerData;
	result = __InternalCxxFrameHandler( pExcept, pFrame, pContext, pDC, pFuncInfo, 0, NULL, FALSE );
	return result;
	}
Exemple #2
0
void __stdcall _UnwindNestedFrames(
    EHRegistrationNode *pRN,        // Unwind up to (but not including) this frame
    EHExceptionRecord   *pExcept    // The exception that initiated this unwind
) {
    EHTRACE_ENTER;

    void* pReturnPoint;
    EHRegistrationNode *pDispatcherRN;  // Magic!

    __asm {
        //
        // Save the dispatcher's marker node
        //
        // NOTE: RtlUnwind will trash the callee-save regs EBX, ESI, and EDI.
        // We explicitly use them here in the inline-asm so they get preserved
        // and restored by the function prologue/epilogue.
        //
        mov     esi, dword ptr FS:[0]   // use ESI
        mov     pDispatcherRN, esi
    }

    __asm mov pReturnPoint, offset ReturnPoint
    RtlUnwind(pRN, pReturnPoint, (PEXCEPTION_RECORD)pExcept, nullptr);

ReturnPoint:

    PER_FLAGS(pExcept) &= ~EXCEPTION_UNWINDING; // Clear the 'Unwinding' flag
                                                // in case exception is rethrown
    __asm {
        //
        // Re-link the dispatcher's marker node
        //
        mov     edi, dword ptr FS:[0]   // Get the current head (use EDI)
        mov     ebx, pDispatcherRN      // Get the saved head (use EBX)
        mov     [ebx], edi              // Link saved head to current head
        mov     dword ptr FS:[0], ebx   // Make saved head current head
        }

    EHTRACE_EXIT;

    return;
    }
Exemple #3
0
void _UnwindNestedFrames(
	EHRegistrationNode	*pFrame,		// Unwind up to (but not including) this frame
	EHExceptionRecord	*pExcept		// The exception that initiated this unwind
	//void				*pContext		// Context info for current exception
) {

	PPMSTACK spCur;
	PPMSTACK spCurCatch;				    
	DispatcherContext curDC;
	PFTINFO pftinfoTOC;
	PRUNTIME_FUNCTION pFunctionEntry;
	PRUNTIME_FUNCTION pFunctionEntryCatch = NULL;
	unsigned long cNestedTmp;
	PFRAMEINFO pframeinfo;

 	spCur = (PPMSTACK)GetSP();

	//Loop through the frames backwards on the stack to destroy objects until target frame
	//Assume:

	spCur = spCur->pSpBackChain;
	while (spCur < pFrame)
		{
		// we should only look the frame which hasn't been looked
		if (_pFrameInfoChain)
			{
			if ((spCur > _pFrameInfoChain->pExitContext) && (spCur < _pFrameInfoChain->pSp))
				{
				spCur = spCur->pSpBackChain;
				continue;
				}

			if (cNested > 0)
				{
				cNestedTmp = cNested;
				pframeinfo = _pFrameInfoChain;
				while (cNestedTmp-- && pframeinfo)
					{
					if ( (spCur->pSpBackChain == pframeinfo->pExitContext) )
						{
						pFunctionEntryCatch = GetFunctionEntry(spCur, &pftinfoTOC);
						spCurCatch = spCur;
						break;
						}
					pframeinfo = pframeinfo->pNext;
					}
				if (pframeinfo)
					{
					spCur = spCur->pSpBackChain;
					continue;
					}
				}

			}
		pFunctionEntry = GetFunctionEntry(spCur, &pftinfoTOC);
		if (pFunctionEntry && pFunctionEntry->ExceptionHandler != NULL)
			{
			//set unwinding flag
			//stack point, old PC(in linker register, execution point==state), Registers in Context
			PER_FLAGS(pExcept) |= EXCEPTION_UNWINDING;
			curDC.ControlPc = spCur->dwLNKreg;
			curDC.FunctionEntry = pFunctionEntry;  //what else to save?!
			curDC.EstablisherFrame = spCur;
			curDC.pftinfo = pftinfoTOC;
			if (pFunctionEntryCatch == pFunctionEntry)
				{
				// we have to  update the return address in original catch frame
				if (spCurCatch->dwLNKreg > curDC.ControlPc)
					{
					curDC.ControlPc = spCurCatch->dwLNKreg;
					}
				}
			(*pFunctionEntry->ExceptionHandler)(pExcept, spCur, NULL, &curDC);
			}
		spCur = spCur->pSpBackChain;
		}	
	//
	// clear the unwinding flag, in case exception is rethown
	//
	PER_FLAGS(pExcept) &= ~EXCEPTION_UNWINDING;
	return;
}