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

📄 kdtrap.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//
/*++


Module Name:

    kdtrap.c

Abstract:

    This module contains code to implement the target side of the portable
    kernel debugger.

--*/

#include "kdp.h"

//#define NON_BLOCKING_KDSTUB // Uncomment this to allow KDSTUB to be non blocking until the KDBG stream is established
// Note: The drawback of non-blocking kdstub is that we may miss instanciation of defered BP on first modules (until KDBG connects)

CRITICAL_SECTION csDbg;

BOOL g_fForceReload = TRUE;
CONTEXT *g_pctxException;
DWORD g_dwExceptionCode = 0;
SAVED_THREAD_STATE g_svdThread = {0};

void FlushDCache(void);

ULONG
KdpTrap (
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN CONTEXT *pContextRecord,
    IN BOOLEAN SecondChance
    )

/*++

Routine Description:

    This routine is called whenever a exception is dispatched and the kernel
    debugger is active.

Arguments:

    ExceptionRecord - Supplies a pointer to an exception record that
        describes the exception.

    pContextRecord - Supplies the context at the time of the exception.

    PreviousMode - Supplies the previous processor mode.

    SecondChance - Supplies a boolean value that determines whether this is
        the second chance (TRUE) that the exception has been raised.

Return Value:

    A value of TRUE is returned if the exception is handled. Otherwise a
    value of FALSE is returned.

--*/

{
    BOOLEAN fExceptionHandledByKD = TRUE;
    ULONG OldFir;
    KD_EXCEPTION_INFO kei;
    BOOL fHostDbgConnected = FALSE;
    PUCHAR pucDummy;
    SAVED_THREAD_STATE svdThread;
    HRESULT hrOsAxsT0 = E_FAIL;
    HRESULT hrOsAxsT1 = E_FAIL;
    PCONTEXT pContextSaveOsAxsT0=NULL;
    PCONTEXT pContextSaveOsAxsT1=NULL;
    SAVED_THREAD_STATE *psvdThreadSaveOsAxsT0=NULL;
    SAVED_THREAD_STATE *psvdThreadSaveOsAxsT1=NULL;

    // WARNING: Global variable initialization must be done after the Critical Section & InterlockedIncrement below
    
    if (!g_fDbgConnected)
        return FALSE; // KDInit not called yet - Ignore exception

    DEBUGGERMSG (KDZONE_TRAP, (L"++KdTrap v%i.1\r\n", CUR_KD_VER));

    SWITCHKEY (svdThread.aky, 0xffffffff);

    KDEnableInt (FALSE, &svdThread); // Disable interupts, set thread prio / quantum to real-time, save current

    if (!InSysCall())
    {
        DEBUGGERMSG(KDZONE_TRAP, (TEXT("  KdTrap: ++ EnterCriticalSection\r\n")));
        EnterCriticalSection(&csDbg);
        DEBUGGERMSG(KDZONE_TRAP, (TEXT("  KdTrap: -- EnterCriticalSection\r\n")));
    }

    if (InterlockedIncrement(&kdpKData->dwInDebugger) > 1)
    { // Recursion in KdStub: attempt to recover
        // temporarily suspend a breakpoint if it was known and hit during exception processing
        if ((STATUS_BREAKPOINT == ExceptionRecord->ExceptionCode) &&
            KdpSuspendBreakpointIfHitByKd ((VOID*) CONTEXT_TO_PROGRAM_COUNTER (pContextRecord)))
        { // Hit BP while in KDStub and succeeded to remove it (likely to be in KITL or Kernel code)
            fExceptionHandledByKD = TRUE;
            DEBUGGERMSG(KDZONE_TRAP, (TEXT("  KdTrap: Suspended breakpoints\r\n")));
        }
        else
        {
            DEBUGGERMSG(KDZONE_ALERT, (TEXT("  KdTrap: Exception in debugger, Addr=0x%08X - "),ExceptionRecord->ExceptionAddress));

            if (SecondChance)
            {
                DEBUGGERMSG(KDZONE_ALERT, (TEXT(" unable to recover\r\n")));
            }
            else
            {
                DEBUGGERMSG(KDZONE_ALERT, (TEXT(" attempting to recover\r\n")));
            }
            fExceptionHandledByKD = FALSE;
        }

        goto exit;
    }

    if (CAPTUREDUMPFILEONDEVICE_CALLED(ExceptionRecord, *g_kdKernData.ppCaptureDumpFileOnDevice) && (!SecondChance))
    {
        // We ignore these in Kernel Debugger for 1st chance, used for Watson support
        DEBUGGERMSG(KDZONE_TRAP, (TEXT("  KdTrap: CaptureDumpFileOnDevice 1st chance exception, passing on to OsAxs ... \r\n")));
        fExceptionHandledByKD = FALSE;
        goto exit;
    }

    // Global variable initialization must be done after the Critical Section & InterlockedIncrement to prevent changing by re-entrancy
    g_svdThread = svdThread;
    g_pctxException = pContextRecord;
    
    // initialize stackwalk variables to represent valid state
    if (pCurThread)
    {
        pStk        = pCurThread->pcstkTop;
        pLastProc   = pCurProc;
        pWalkThread = pCurThread;
    }
    g_pFocusProcOverride = NULL;

    if (!g_fKdbgRegistered)
    { // We never registered KDBG service
        // Check if KITL has started or JIT
        BOOL fKitlStarted = g_kdKernData.pKITLIoCtl(IOCTL_EDBG_IS_STARTED, NULL, 0, NULL, 0, NULL);
        if (fKitlStarted || SecondChance)
        {
            // Don't activate KITL because of HDStub's breakpoint
            if ((CONTEXT_TO_PROGRAM_COUNTER (pContextRecord) <  (DWORD)g_kdKernData.pfnHwTrap) ||
                (CONTEXT_TO_PROGRAM_COUNTER (pContextRecord) > ((DWORD)g_kdKernData.pfnHwTrap + HD_NOTIFY_MARGIN)))
            {
                fExceptionHandledByKD = TRUE; // Default: KD handles exception
                if (!fKitlStarted)
                { // JIT Debugging case
                    // Notify OAL that a JIT debug is pending, give a chance to notify user and accept or bypass
                    // KD_IOCTL_JIT_NOTIF can be used by OEM to warn the user that the device is currently
                    // blocked at an exception waiting to be handled by the debugger. The OAL code could
                    // simply blink some LEDs and wait for a key to be pressed. Depending on the key pressed,
                    // the user could indicate if the exception should be handled by the debugger or simply
                    // ignored and handled by the OS.
                    DEBUGGERMSG(KDZONE_ALERT, (TEXT("  KdTrap: JIT debugging requested, waiting for OEM selection\r\n")));
                    fExceptionHandledByKD = !KDIoControl (KD_IOCTL_JIT_NOTIF, NULL, 0);
                    if (fExceptionHandledByKD)
                    {
                        DEBUGGERMSG(KDZONE_ALERT, (TEXT("  KdTrap: JIT debugging accepted\r\n")));
                    }
                    else
                    {
                        DEBUGGERMSG(KDZONE_ALERT, (TEXT("  KdTrap: JIT debugging bypassed\r\n")));
                    }
                }

                if (fExceptionHandledByKD)
                {
                    EnableHDNotifs (TRUE);
                    // register KDBG
                    g_fKdbgRegistered = g_kdKernData.pKITLIoCtl(IOCTL_EDBG_REGISTER_DFLT_CLIENT, &pucDummy, KITL_SVC_KDBG, &pucDummy, 0, NULL);
                    DEBUGGERMSG(KDZONE_TRAP, (TEXT("  KdTrap: KITLRegisterDfltClient returned: %d\r\n"), g_fKdbgRegistered));
                }
            }
            else
            {
                fExceptionHandledByKD = FALSE;
            }

            if (!fExceptionHandledByKD) goto exit;
        }
        else
        {
            DEBUGGERMSG(KDZONE_TRAP, (TEXT("  KdTrap: KITL is not started\r\n")));
        }
    }

    OldFir = CONTEXT_TO_PROGRAM_COUNTER (pContextRecord);
    if ((ZeroPtr(CONTEXT_TO_PROGRAM_COUNTER (pContextRecord)) > (1 << VA_SECTION)) ||
        (ZeroPtr(CONTEXT_TO_PROGRAM_COUNTER (pContextRecord)) < (DWORD)DllLoadBase))
    {
         CONTEXT_TO_PROGRAM_COUNTER (pContextRecord) = (UINT) MapPtrProc (CONTEXT_TO_PROGRAM_COUNTER (pContextRecord), pCurProc);
    }

    // Allow OAL to remap exceptions
    kei.nVersion = 1;
    kei.ulAddress = (ULONG)ExceptionRecord->ExceptionAddress;
    kei.ulExceptionCode = ExceptionRecord->ExceptionCode;
    kei.ulFlags = 0;
    if (KDIoControl (KD_IOCTL_MAP_EXCEPTION, &kei, sizeof(KD_EXCEPTION_INFO)))
    {
        ExceptionRecord->ExceptionCode = kei.ulExceptionCode;
    }

    g_dwExceptionCode = ExceptionRecord->ExceptionCode;

    DEBUGGERMSG(KDZONE_TRAP, (TEXT("  KdTrap: Exception at %08X Breakcode = %08X ExceptionCode = %08X\r\n"),
        CONTEXT_TO_PROGRAM_COUNTER (pContextRecord),
        ExceptionRecord->ExceptionInformation[0],
        ExceptionRecord->ExceptionCode));

⌨️ 快捷键说明

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