📄 kdtrap.c
字号:
//
// 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 + -