BOOLEAN NTAPI KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChance) { KD_CONTINUE_TYPE Return = kdHandleException; ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0]; /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */ if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) && (ExceptionRecord->NumberParameters > 0) && ((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) || (ExceptionCommand == BREAKPOINT_UNLOAD_SYMBOLS) || (ExceptionCommand == BREAKPOINT_COMMAND_STRING) || (ExceptionCommand == BREAKPOINT_PRINT) || (ExceptionCommand == BREAKPOINT_PROMPT))) { /* Check if this is a debug print */ if (ExceptionCommand == BREAKPOINT_PRINT) { /* Print the string */ KdpServiceDispatcher(BREAKPOINT_PRINT, (PVOID)ExceptionRecord->ExceptionInformation[1], ExceptionRecord->ExceptionInformation[2]); /* Return success */ KeSetContextReturnRegister(Context, STATUS_SUCCESS); } #ifdef KDBG else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) { PLDR_DATA_TABLE_ENTRY LdrEntry; /* Load symbols. Currently implemented only for KDBG! */ if(KdbpSymFindModule(((PKD_SYMBOLS_INFO)ExceptionRecord->ExceptionInformation[2])->BaseOfDll, NULL, -1, &LdrEntry)) KdbSymProcessSymbols(LdrEntry); } else if (ExceptionCommand == BREAKPOINT_PROMPT) { ULONG ReturnValue; LPSTR OutString; USHORT OutStringLength; /* Get the response string and length */ OutString = (LPSTR)Context->Ebx; OutStringLength = (USHORT)Context->Edi; /* Call KDBG */ ReturnValue = KdpPrompt((LPSTR)ExceptionRecord-> ExceptionInformation[1], (USHORT)ExceptionRecord-> ExceptionInformation[2], OutString, OutStringLength); /* Return the number of characters that we received */ Context->Eax = ReturnValue; } #endif /* This we can handle: simply bump the Program Counter */ KeSetContextPc(Context, KeGetContextPc(Context) + KD_BREAKPOINT_SIZE); return TRUE; } #ifdef KDBG /* Check if this is an assertion failure */ if (ExceptionRecord->ExceptionCode == STATUS_ASSERTION_FAILURE) { /* Bump EIP to the instruction following the int 2C */ Context->Eip += 2; } #endif /* Get out of here if the Debugger isn't connected */ if (KdDebuggerNotPresent) return FALSE; #ifdef KDBG /* Call KDBG if available */ Return = KdbEnterDebuggerException(ExceptionRecord, PreviousMode, Context, TrapFrame, !SecondChance); #else /* not KDBG */ if (WrapperInitRoutine) { /* Call GDB */ Return = WrapperTable.KdpExceptionRoutine(ExceptionRecord, Context, TrapFrame); } #endif /* not KDBG */ /* Debugger didn't handle it, please handle! */ if (Return == kdHandleException) return FALSE; /* Debugger handled it */ return TRUE; }
/*! \brief Initializes the KDB symbols implementation. * * \param DispatchTable Pointer to the KD dispatch table * \param BootPhase Phase of initialization */ VOID NTAPI KdbInitialize( PKD_DISPATCH_TABLE DispatchTable, ULONG BootPhase) { PCHAR p1, p2; SHORT Found = FALSE; CHAR YesNo; PLDR_DATA_TABLE_ENTRY LdrEntry; DPRINT("KdbSymInit() BootPhase=%d\n", BootPhase); LoadSymbols = FALSE; #if DBG /* Load symbols only if we have 96Mb of RAM or more */ if (MmNumberOfPhysicalPages >= 0x6000) LoadSymbols = TRUE; #endif if (BootPhase == 0) { /* Write out the functions that we support for now */ DispatchTable->KdpInitRoutine = KdpKdbgInit; DispatchTable->KdpPrintRoutine = KdbDebugPrint; /* Register as a Provider */ InsertTailList(&KdProviders, &DispatchTable->KdProvidersList); /* Perform actual initialization of symbol module */ //NtoskrnlModuleObject->PatchInformation = NULL; //LdrHalModuleObject->PatchInformation = NULL; InitializeListHead(&SymbolFileListHead); KeInitializeSpinLock(&SymbolFileListLock); /* Check the command line for /LOADSYMBOLS, /NOLOADSYMBOLS, * /LOADSYMBOLS={YES|NO}, /NOLOADSYMBOLS={YES|NO} */ ASSERT(KeLoaderBlock); p1 = KeLoaderBlock->LoadOptions; while('\0' != *p1 && NULL != (p2 = strchr(p1, '/'))) { p2++; Found = 0; if (0 == _strnicmp(p2, "LOADSYMBOLS", 11)) { Found = +1; p2 += 11; } else if (0 == _strnicmp(p2, "NOLOADSYMBOLS", 13)) { Found = -1; p2 += 13; } if (0 != Found) { while (isspace(*p2)) { p2++; } if ('=' == *p2) { p2++; while (isspace(*p2)) { p2++; } YesNo = toupper(*p2); if ('N' == YesNo || 'F' == YesNo || '0' == YesNo) { Found = -1 * Found; } } LoadSymbols = (0 < Found); } p1 = p2; } RosSymInit(&KdbpRosSymCallbacks); } else if (BootPhase == 3) { /* Load symbols for NTOSKRNL.EXE. It is always the first module in PsLoadedModuleList. KeLoaderBlock can't be used here as its content is just temporary. */ LdrEntry = CONTAINING_RECORD(PsLoadedModuleList.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); KdbSymProcessSymbols(LdrEntry); /* Also load them for HAL.DLL. */ LdrEntry = CONTAINING_RECORD(PsLoadedModuleList.Flink->Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); KdbSymProcessSymbols(LdrEntry); KdbpSymbolsInitialized = TRUE; } }