reactos/ntoskrnl/include/internal/kd64.h

747 lines
15 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Kernel
* LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/include/internal/kd64.h
* PURPOSE: Internal header for the KD64 Library
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
2017-12-12 11:42:13 +00:00
#pragma once
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
//
// Default size of the DbgPrint log buffer
//
#if DBG
#define KD_DEFAULT_LOG_BUFFER_SIZE 0x8000
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
#else
#define KD_DEFAULT_LOG_BUFFER_SIZE 0x1000
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
#endif
//
// Default size of the Message and Path buffers
//
#define KDP_MSG_BUFFER_SIZE 0x1000
//
// Maximum supported number of breakpoints
//
#define KD_BREAKPOINT_MAX 32
//
// Highest limit starting which we consider that breakpoint addresses
// are either in system space, or in user space but inside shared DLLs.
//
// I'm wondering whether this can be computed using MmHighestUserAddress
// or whether there is already some #define somewhere else...
// See http://www.drdobbs.com/windows/faster-dll-load-load/184416918
// and http://www.drdobbs.com/rebasing-win32-dlls/184416272
// for a tentative explanation.
//
#define KD_HIGHEST_USER_BREAKPOINT_ADDRESS (PVOID)0x60000000 // MmHighestUserAddress
//
// Breakpoint Status Flags
//
#define KD_BREAKPOINT_ACTIVE 0x01
#define KD_BREAKPOINT_PENDING 0x02
#define KD_BREAKPOINT_SUSPENDED 0x04
#define KD_BREAKPOINT_EXPIRED 0x08
//
// Structure for Breakpoints
//
typedef struct _BREAKPOINT_ENTRY
{
ULONG Flags;
ULONG_PTR DirectoryTableBase;
PVOID Address;
KD_BREAKPOINT_TYPE Content;
} BREAKPOINT_ENTRY, *PBREAKPOINT_ENTRY;
//
// Debug and Multi-Processor Switch Routine Definitions
//
typedef
BOOLEAN
(NTAPI *PKDEBUG_ROUTINE)(
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context,
IN KPROCESSOR_MODE PreviousMode,
IN BOOLEAN SecondChance
);
//
// Initialization Routines
//
BOOLEAN
NTAPI
KdInitSystem(
_In_ ULONG BootPhase,
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock
);
VOID
NTAPI
KdUpdateDataBlock(
VOID
);
//
// Determines if the kernel debugger must handle a particular trap
//
BOOLEAN
NTAPI
KdIsThisAKdTrap(
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context,
IN KPROCESSOR_MODE PreviousMode
);
//
// Multi-Processor Switch Support
//
KCONTINUE_STATUS
NTAPI
KdReportProcessorChange(
VOID);
//
// Time Slip Support
//
VOID
NTAPI
KdpTimeSlipWork(
IN PVOID Context
);
VOID
NTAPI
KdpTimeSlipDpcRoutine(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
//
// Debug Trap Handlers
//
BOOLEAN
NTAPI
KdpStub(
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT ContextRecord,
IN KPROCESSOR_MODE PreviousMode,
IN BOOLEAN SecondChanceException
);
BOOLEAN
NTAPI
KdpTrap(
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame,
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT ContextRecord,
IN KPROCESSOR_MODE PreviousMode,
IN BOOLEAN SecondChanceException
);
//
// Port Locking
//
VOID
NTAPI
KdpPortLock(
VOID
);
VOID
NTAPI
KdpPortUnlock(
VOID
);
BOOLEAN
NTAPI
KdpPollBreakInWithPortLock(
VOID
);
//
// Debugger Enter, Exit, Enable and Disable
//
BOOLEAN
NTAPI
KdEnterDebugger(
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame
);
VOID
NTAPI
KdExitDebugger(
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
IN BOOLEAN Enable
);
NTSTATUS
NTAPI
KdEnableDebuggerWithLock(
IN BOOLEAN NeedLock
);
NTSTATUS
NTAPI
KdDisableDebuggerWithLock(
IN BOOLEAN NeedLock
);
//
// Debug Event Handlers
//
NTSTATUS
NTAPI
KdpPrint(
_In_ ULONG ComponentId,
_In_ ULONG Level,
_In_reads_bytes_(Length) PCHAR String,
_In_ USHORT Length,
_In_ KPROCESSOR_MODE PreviousMode,
_In_ PKTRAP_FRAME TrapFrame,
_In_ PKEXCEPTION_FRAME ExceptionFrame,
_Out_ PBOOLEAN Handled
);
- Replace RtlpGetExceptionAddress by the _ReturnAddress intrinsic and add it to ARM intrin.h as it was missing. - Simplify RtlpCheckForActiveDebugger: Remove the BOOLEAN parameter as we would always pass it FALSE. Always return FALSE false from kernel mode for simplicity. - Fix a critical flaw in our exception support: RtlRaiseException and RtlRaiseStatus were implemented in C on x86. This lead to unpredictable register corruption because the compiler could not know that it had to preserve non-volatile registers before calling RtlCaptureContext as the saved context is later used to restore the caller in case the exception is handled and execution is continued. This made the functions unsafe to return from as any non-volatile register could be corrupted. Implement them in assembly for x86 to safely capture the context using only EBP and ESP. The C versions of those routines are still used and shared for the other architectures we support -- needs to be determined if this is safe and correct for those architectures. - The ntdll exception Wine exposed this issue, and all tests now pass. The remaining failures on the build server are caused by missing or incomplete debug register support in KVM/QEMU. Run the test in another VM or on real hardware and all the tests will pass. - Implement Debug Prompt (DbgPrompt) support for KD and KDBG. The KDBG implementation reads the prompt from keyboard or serial depending on the mode so that sysreg and rosdbg can support it too. - Properly implement RtlAssert using DbgPrompt to prompt for the action to take instead of always doing a breakpoint. The new implementation is disabled until sysreg can support this. Also move RtlAssert to its own file as it has nothing to do with the error routines (nor does it belong in exception.c). - Note that DbgPrompt was already used in PspCatchCriticalBreak, and this would have resulted in a silent hang as BREAKPOINT_PROMPT wasn't handled at all by KDBG. - Implement KiRaiseAssertion (10 lines of code with the trap macros) and thus support NT_ASSERT. Add partial support for it to KDBG to print out a warning and the address of the failure, but don't do anything else. Also add NT_ASSERT to the DDK headers so that we can use it, but don't use it yet as the ARM method of performing this has not been decided nor implemented. - KiTrap3 doesn't set STATUS_SUCCESS but BREAKPOINT_BREAK. They have the same numerical value but very different meaning -- BREAKPOINT_BREAK means that the exception is a software breakpoint and not a debug service call. Fix some comments to document that this is what is checked for. - Fix inverted and broken logic in KdpReport. It would never pass second chance exceptions to the debugger, didn't respect the stop-on-exception flag properly and would always fail to handle some special exceptions in both first and second chance instead of just failing to handle it in first chance. Clean up, reformat and document what is going on. - The DebugPrint and DebugPrompt support routines only perform a 2D interrupt on x86; use more portable comments. - Add Alex to the programmer section of x86's kdsup.c -- he wrote KdpGetStateChange, KdpSetContextState and the code that was previously in KdpRead/WriteControlSpace. - Add my name to the parts of KD where I have made significant work on getting KD/WinDbg support up and running. - KD debugging is now quite functional and stable. Some bugs and stubs remain to be flushed out, but overall KD is now much better and easier to use than KDBG. svn path=/trunk/; revision=43705
2009-10-23 22:51:39 +00:00
USHORT
NTAPI
KdpPrompt(
_In_reads_bytes_(PromptLength) PCHAR PromptString,
_In_ USHORT PromptLength,
_Out_writes_bytes_(MaximumResponseLength) PCHAR ResponseString,
_In_ USHORT MaximumResponseLength,
_In_ KPROCESSOR_MODE PreviousMode,
_In_ PKTRAP_FRAME TrapFrame,
_In_ PKEXCEPTION_FRAME ExceptionFrame
);
VOID
NTAPI
KdpSymbol(
IN PSTRING DllPath,
- DBGKD_WAIT_STATE_CHANGE64 is used in KD protocol 5, not number 6 that we use. Protocol 6 uses the DBGKD_ANY_WAIT_STATE_CHANGE structure which is sized according to the largest control-report structure (AMD64_DBGKD_CONTROL_REPORT currently), and is larger than DBGKD_WAIT_STATE_CHANGE64 on x86. This worked because our DBGKD_WAIT_STATE_CHANGE32/64 structures contained incorrect DBGKD_CONTROL_REPORT (used) and CONTEXT (unused) members that sized up the wait-state structure to pass WinDbg's length verification! It actually becomes larger than DBGKD_ANY_WAIT_STATE_CHANGE, but WinDbg only seems bail out only if the structure is too small. Remove the incorrect members from the protocol 5 structures and change to DBGKD_ANY_WAIT_STATE_CHANGE everywhere. - Correct the value of SIZE_OF_FX_REGISTERS -- it was 4 times too low which resulted in KeContextToTrapFrame not properly clearing out the XMM register area. Correct the define and move it out from ke.h to x86's ketypes.h and use it in the FXSAVE format structure. Also remove the IOPM definitions from ke.h as they have been in the NDK for a while. - KD uses STRINGs, not ANSI_STRINGs -- they are the same thing, but let's be consistent. - ExceptionRecord32To64 should be available for both 32 and 64 bit builds (and it shouldn't be a forceinline). Get rid of CopyExceptionRecord and determine if we need to convert or can just copy it directly instead. - Use _WIN64 instead of _M_AMD64 when determining if we need to set the DBGKD_VERS_FLAG_PTR64 flag. - Don't check Nt/DbgQueryDebugFilterState for zero or nonzero -- it actually returns TRUE, FALSE or STATUS_INVALID_PARAMETER_1! Check for != TRUE in preparation for proper implementation of NtSet/QueryDebugFilterState. - Fix Format parameter of DbgPrintReturnControlC -- it is const like the other DbgPrint* routines. - Be consistent with the types used in debug.c and don't set local variables to zero if we are going to return to caller -- this doesn't seem to be required anymore. - Fix DebugService and DebugService2: DebugService should take a ULONG followed by 4 pointers and DebugService2 doesn't return anything. - Use ZwCurrentProcess() instead of -1 or 0xFFFFFFFF (which is incorrect for 64-bit) for the ProcessId parameter of DbgLoad/UnloadImageSymbols to clarify what is being passed. Don't use ZwCurrentProcess() in KeBugCheckWithTf for the pointer parameter of DbgUnLoadImageSymbols either. Use MAXULONG_PTR casted to PVOID instead. - Use better named and sized variables in KdpTrap for setting the "return register" in the caller's CONTEXT. - Correct and clarify the comment documenting under what conditions we pass user mode exceptions to the kernel debugger. svn path=/trunk/; revision=43741
2009-10-25 15:56:38 +00:00
IN PKD_SYMBOLS_INFO SymbolInfo,
IN BOOLEAN Unload,
IN KPROCESSOR_MODE PreviousMode,
IN PCONTEXT ContextRecord,
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame
);
VOID
NTAPI
KdpCommandString(
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
IN PSTRING NameString,
IN PSTRING CommandString,
IN KPROCESSOR_MODE PreviousMode,
IN PCONTEXT ContextRecord,
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame
);
//
// State Change Notifications
//
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
VOID
NTAPI
KdpReportLoadSymbolsStateChange(
IN PSTRING PathName,
IN PKD_SYMBOLS_INFO SymbolInfo,
IN BOOLEAN Unload,
IN OUT PCONTEXT Context
);
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
VOID
NTAPI
KdpReportCommandStringStateChange(
IN PSTRING NameString,
IN PSTRING CommandString,
IN OUT PCONTEXT Context
);
BOOLEAN
NTAPI
KdpReportExceptionStateChange(
IN PEXCEPTION_RECORD ExceptionRecord,
IN OUT PCONTEXT Context,
IN BOOLEAN SecondChanceException
);
//
// Breakpoint Support
//
ULONG
NTAPI
KdpAddBreakpoint(
IN PVOID Address
);
VOID
NTAPI
KdSetOwedBreakpoints(
VOID
);
BOOLEAN
NTAPI
KdpDeleteBreakpoint(
IN ULONG BpEntry
);
BOOLEAN
NTAPI
KdpDeleteBreakpointRange(
IN PVOID Base,
IN PVOID Limit
);
VOID
NTAPI
KdpSuspendBreakPoint(
IN ULONG BpEntry
);
VOID
NTAPI
KdpRestoreAllBreakpoints(
VOID
);
VOID
NTAPI
KdpSuspendAllBreakPoints(
VOID
);
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
//
// Routine to determine if it is safe to disable the debugger
//
NTSTATUS
NTAPI
KdpAllowDisable(
VOID
);
//
// Safe memory read & write Support
//
NTSTATUS
NTAPI
KdpCopyMemoryChunks(
_In_ ULONG64 Address,
_In_ PVOID Buffer,
_In_ ULONG TotalSize,
_In_ ULONG ChunkSize,
_In_ ULONG Flags,
_Out_opt_ PULONG ActualSize
);
//
// Internal memory handling routines for KD isolation
//
VOID
NTAPI
KdpMoveMemory(
_In_ PVOID Destination,
_In_ PVOID Source,
_In_ SIZE_T Length
);
VOID
NTAPI
KdpZeroMemory(
_In_ PVOID Destination,
_In_ SIZE_T Length
);
//
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
// Low Level Support Routines for the KD API
//
//
// Version
//
VOID
NTAPI
KdpSysGetVersion(
IN PDBGKD_GET_VERSION64 Version
);
//
// Context
//
VOID
NTAPI
KdpGetStateChange(
IN PDBGKD_MANIPULATE_STATE64 State,
IN PCONTEXT Context
);
VOID
NTAPI
KdpSetContextState(
- DBGKD_WAIT_STATE_CHANGE64 is used in KD protocol 5, not number 6 that we use. Protocol 6 uses the DBGKD_ANY_WAIT_STATE_CHANGE structure which is sized according to the largest control-report structure (AMD64_DBGKD_CONTROL_REPORT currently), and is larger than DBGKD_WAIT_STATE_CHANGE64 on x86. This worked because our DBGKD_WAIT_STATE_CHANGE32/64 structures contained incorrect DBGKD_CONTROL_REPORT (used) and CONTEXT (unused) members that sized up the wait-state structure to pass WinDbg's length verification! It actually becomes larger than DBGKD_ANY_WAIT_STATE_CHANGE, but WinDbg only seems bail out only if the structure is too small. Remove the incorrect members from the protocol 5 structures and change to DBGKD_ANY_WAIT_STATE_CHANGE everywhere. - Correct the value of SIZE_OF_FX_REGISTERS -- it was 4 times too low which resulted in KeContextToTrapFrame not properly clearing out the XMM register area. Correct the define and move it out from ke.h to x86's ketypes.h and use it in the FXSAVE format structure. Also remove the IOPM definitions from ke.h as they have been in the NDK for a while. - KD uses STRINGs, not ANSI_STRINGs -- they are the same thing, but let's be consistent. - ExceptionRecord32To64 should be available for both 32 and 64 bit builds (and it shouldn't be a forceinline). Get rid of CopyExceptionRecord and determine if we need to convert or can just copy it directly instead. - Use _WIN64 instead of _M_AMD64 when determining if we need to set the DBGKD_VERS_FLAG_PTR64 flag. - Don't check Nt/DbgQueryDebugFilterState for zero or nonzero -- it actually returns TRUE, FALSE or STATUS_INVALID_PARAMETER_1! Check for != TRUE in preparation for proper implementation of NtSet/QueryDebugFilterState. - Fix Format parameter of DbgPrintReturnControlC -- it is const like the other DbgPrint* routines. - Be consistent with the types used in debug.c and don't set local variables to zero if we are going to return to caller -- this doesn't seem to be required anymore. - Fix DebugService and DebugService2: DebugService should take a ULONG followed by 4 pointers and DebugService2 doesn't return anything. - Use ZwCurrentProcess() instead of -1 or 0xFFFFFFFF (which is incorrect for 64-bit) for the ProcessId parameter of DbgLoad/UnloadImageSymbols to clarify what is being passed. Don't use ZwCurrentProcess() in KeBugCheckWithTf for the pointer parameter of DbgUnLoadImageSymbols either. Use MAXULONG_PTR casted to PVOID instead. - Use better named and sized variables in KdpTrap for setting the "return register" in the caller's CONTEXT. - Correct and clarify the comment documenting under what conditions we pass user mode exceptions to the kernel debugger. svn path=/trunk/; revision=43741
2009-10-25 15:56:38 +00:00
IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
IN PCONTEXT Context
);
//
// MSR
//
NTSTATUS
NTAPI
KdpSysReadMsr(
IN ULONG Msr,
OUT PLARGE_INTEGER MsrValue
);
NTSTATUS
NTAPI
KdpSysWriteMsr(
IN ULONG Msr,
IN PLARGE_INTEGER MsrValue
);
//
// Bus
//
NTSTATUS
NTAPI
KdpSysReadBusData(
IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN ULONG Offset,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength
);
NTSTATUS
NTAPI
KdpSysWriteBusData(
IN ULONG BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN ULONG Offset,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength
);
//
// Control Space
//
NTSTATUS
NTAPI
KdpSysReadControlSpace(
IN ULONG Processor,
IN ULONG64 BaseAddress,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength
);
NTSTATUS
NTAPI
KdpSysWriteControlSpace(
IN ULONG Processor,
IN ULONG64 BaseAddress,
IN PVOID Buffer,
IN ULONG Length,
OUT PULONG ActualLength
);
//
// I/O Space
//
NTSTATUS
NTAPI
KdpSysReadIoSpace(
IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize
);
NTSTATUS
NTAPI
KdpSysWriteIoSpace(
IN ULONG InterfaceType,
IN ULONG BusNumber,
IN ULONG AddressSpace,
IN ULONG64 IoAddress,
IN PVOID DataValue,
IN ULONG DataSize,
OUT PULONG ActualDataSize
);
//
// Low Memory
//
NTSTATUS
NTAPI
KdpSysCheckLowMemory(
IN ULONG Flags
);
//
// Internal routine for sending strings directly to the debugger
//
VOID
__cdecl
KdpDprintf(
_In_ PCSTR Format,
...);
BOOLEAN
NTAPI
KdpPrintString(
_In_ PSTRING Output);
[NTOS:KD64] Implement KdLogDbgPrint() for the WinDbg !dbgprint command. See this command's documentation: https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/-dbgprint and the section "DbgPrint buffer and the debugger" https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/reading-and-filtering-debugging-messages#dbgprint-buffer-and-the-debugger for more details. - Loosely implement the function, based on our existing circular printout buffers in kdio.c. - Enable its usage in the KdpPrint() and KdpPrompt() functions. Notice that this function will *only* capture the strings being sent **to** the debugger, and not the strings the debugger itself produce. (This means that we cannot use the KdPrintCircularBuffer as a replacement for our KDBG dmesg one, for example...) How to test: Run ReactOS under WinDbg, and use the !dbgprint command to view the buffer. You can also use the Memory Window, place yourself at the address pointed by KdPrintCircularBuffer and KdPrintWritePointer, and read its contents. What you should observe: Prior notice: The circular buffer in debug builds of ReactOS and Windows is 0x8000 bytes large. In release builds, its size is down to 0x1000. 1- When you start e.g. the 2nd-stage GUI installation of ReactOS, going past the initial "devices installation" and letting it stabilize on the Welcome page, break into WinDbg and run the !dbgprint command. You should notice that the end of its output is weirdly truncated, compared to what has been actually emitted to the debug output. Comparing this with the actual contents of the circular buffer (via Memory Window), shows that the buffer contents is actually correct. 2- Copy all the text that has been output by the !dbgprint command and paste it in an editor; count the number of all characters appearing + newlines (only CR or LF), and observe that this number is "mysteriously" equal to 16384 == 0x4000. 3- Continue running ReactOS installation for a little while, breaking back back into WinDbg and looking at !dbgprint again. Its output seems to be still stopping at the same place as before (but the actual buffer memory contents shows otherwise). Continue running ROS installation, and break into the debugger when ROS is about to restart. You should now observe that the dbgprint buffer rolled over: dd nt!KdPrintRolloverCount shows 1. Carefully analysing the output of !dbgprint, however, you will notice that it looks a bit garbage-y: the first part of the output is actually truncated after 16384 characters, then you get a second part of the buffer showing what ReactOS was printing while shutting down. Then you get again what was shown at the top of the !dbgprint output. (Of course, comparing with the actual contents of the circular buffer in memory shows that its contents are fine...) The reason of these strange observations, is because there is an intrinsic bug in the !dbgprint command implementation (in kdexts.dll). Essentially, it displays the contents of the circular buffer in two single dprintf() calls: one for the "older" (bottom) part of the buffer: [WritePointer, EndOfBuffer] and one for the "newer" (upper) part of the buffer: [CircularBuffer, WritePointer[ . The first aspect of the bug (causing observation 3), is that those two parts are not necessarily NULL-terminated strings (especially after rollover), so for example, displaying the upper part of the buffer, will potentially also display part of the buffer's bottom part. The second aspect of the bug (explaining observations 1 and 2), is due to the implementation of the dprintf() function (callback in dbgenv.dll). There, it uses a fixed-sized buffer of size 0x4000 == 16384 characters. Since the output of the circular buffer is not done by little chunks, but by the two large parts, if any of those are larger than 0x4000 they get truncated on display. (This last observation is confirmed in a completely different context by https://community.osr.com/discussion/112439/dprintf-s-max-string-length .)
2022-11-23 22:24:59 +00:00
VOID
NTAPI
KdLogDbgPrint(
_In_ PSTRING String);
//
// Global KD Data
//
extern DBGKD_GET_VERSION64 KdVersionBlock;
extern KDDEBUGGER_DATA64 KdDebuggerDataBlock;
extern LIST_ENTRY KdpDebuggerDataListHead;
extern KSPIN_LOCK KdpDataSpinLock;
extern LARGE_INTEGER KdPerformanceCounterRate;
extern LARGE_INTEGER KdTimerStart;
extern ULONG KdDisableCount;
extern KD_CONTEXT KdpContext;
extern PKDEBUG_ROUTINE KiDebugRoutine;
extern BOOLEAN KdBreakAfterSymbolLoad;
extern BOOLEAN KdPitchDebugger;
extern BOOLEAN KdAutoEnableOnEvent;
extern BOOLEAN KdBlockEnable;
extern BOOLEAN KdIgnoreUmExceptions;
extern BOOLEAN KdPreviouslyEnabled;
extern BOOLEAN KdpDebuggerStructuresInitialized;
extern BOOLEAN KdEnteredDebugger;
extern KDPC KdpTimeSlipDpc;
extern KTIMER KdpTimeSlipTimer;
extern WORK_QUEUE_ITEM KdpTimeSlipWorkItem;
extern LONG KdpTimeSlipPending;
extern PKEVENT KdpTimeSlipEvent;
extern KSPIN_LOCK KdpTimeSlipEventLock;
extern BOOLEAN KdpPortLocked;
extern BOOLEAN KdpControlCPressed;
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
extern BOOLEAN KdpContextSent;
extern KSPIN_LOCK KdpDebuggerLock;
extern LARGE_INTEGER KdTimerStop, KdTimerStart, KdTimerDifference;
extern CHAR KdpMessageBuffer[KDP_MSG_BUFFER_SIZE];
extern CHAR KdpPathBuffer[KDP_MSG_BUFFER_SIZE];
[NTOS:KD64] Implement KdLogDbgPrint() for the WinDbg !dbgprint command. See this command's documentation: https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/-dbgprint and the section "DbgPrint buffer and the debugger" https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/reading-and-filtering-debugging-messages#dbgprint-buffer-and-the-debugger for more details. - Loosely implement the function, based on our existing circular printout buffers in kdio.c. - Enable its usage in the KdpPrint() and KdpPrompt() functions. Notice that this function will *only* capture the strings being sent **to** the debugger, and not the strings the debugger itself produce. (This means that we cannot use the KdPrintCircularBuffer as a replacement for our KDBG dmesg one, for example...) How to test: Run ReactOS under WinDbg, and use the !dbgprint command to view the buffer. You can also use the Memory Window, place yourself at the address pointed by KdPrintCircularBuffer and KdPrintWritePointer, and read its contents. What you should observe: Prior notice: The circular buffer in debug builds of ReactOS and Windows is 0x8000 bytes large. In release builds, its size is down to 0x1000. 1- When you start e.g. the 2nd-stage GUI installation of ReactOS, going past the initial "devices installation" and letting it stabilize on the Welcome page, break into WinDbg and run the !dbgprint command. You should notice that the end of its output is weirdly truncated, compared to what has been actually emitted to the debug output. Comparing this with the actual contents of the circular buffer (via Memory Window), shows that the buffer contents is actually correct. 2- Copy all the text that has been output by the !dbgprint command and paste it in an editor; count the number of all characters appearing + newlines (only CR or LF), and observe that this number is "mysteriously" equal to 16384 == 0x4000. 3- Continue running ReactOS installation for a little while, breaking back back into WinDbg and looking at !dbgprint again. Its output seems to be still stopping at the same place as before (but the actual buffer memory contents shows otherwise). Continue running ROS installation, and break into the debugger when ROS is about to restart. You should now observe that the dbgprint buffer rolled over: dd nt!KdPrintRolloverCount shows 1. Carefully analysing the output of !dbgprint, however, you will notice that it looks a bit garbage-y: the first part of the output is actually truncated after 16384 characters, then you get a second part of the buffer showing what ReactOS was printing while shutting down. Then you get again what was shown at the top of the !dbgprint output. (Of course, comparing with the actual contents of the circular buffer in memory shows that its contents are fine...) The reason of these strange observations, is because there is an intrinsic bug in the !dbgprint command implementation (in kdexts.dll). Essentially, it displays the contents of the circular buffer in two single dprintf() calls: one for the "older" (bottom) part of the buffer: [WritePointer, EndOfBuffer] and one for the "newer" (upper) part of the buffer: [CircularBuffer, WritePointer[ . The first aspect of the bug (causing observation 3), is that those two parts are not necessarily NULL-terminated strings (especially after rollover), so for example, displaying the upper part of the buffer, will potentially also display part of the buffer's bottom part. The second aspect of the bug (explaining observations 1 and 2), is due to the implementation of the dprintf() function (callback in dbgenv.dll). There, it uses a fixed-sized buffer of size 0x4000 == 16384 characters. Since the output of the circular buffer is not done by little chunks, but by the two large parts, if any of those are larger than 0x4000 they get truncated on display. (This last observation is confirmed in a completely different context by https://community.osr.com/discussion/112439/dprintf-s-max-string-length .)
2022-11-23 22:24:59 +00:00
- Fix support for /CRASHDEBUG and /NODEBUG; we didn't respect those settings properly and would initialize KD at boot even if they were set. - Re-enable the breakpoint in vDbgPrintExWithPrefixInternal() as this works properly now. Without this breakpoint some break-in requests got lost if the break-in occurred when handling a debug print (happened a lot at boot). - Implement Command String support for DbgCommandString() -- we now handle every debug service call. - Implement NtSetDebugFilterState() and NtQueryDebugFilterState() for KD, meaning we now support debug filters properly. - Implement KdRefreshDebuggerNotPresent(), KdChangeOption() and KdPowerTransition(). Stub KdSystemDebugControl() to return error status instead of hanging the system. - Stub the rest of the KD API to print a warning and return a failure packet instead of hanging. - Set and respect KdpContextSent when getting and setting the thread context -- WinDbg doesn't seem to rely on this, but better safe than sorry. - Support MP when getting and setting the thread context too -- if the context is operation is for another processor than the current, just get it through the KiProcessorBlock array. - Initialize the MajorVersion in the KD version block more properly -- the high byte is the major identifier (0 for NT). Add the required DBGKD_MAJOR_TYPES enumeration to wdbgexts.h. - Simplify setting and clearing the InDbgPrint flag in the TEB to minimize the impact on kernel execution; use 2 dedicated routines instead of a generic one. - KdpSymbol doesn't return anything, so don't return an ignore status from KdpReportLoadSymbolsStateChange. - Expose the KdpDefaultRetries and Kd_WIN2000_Mask variables to the registry and add them to KDBG too (unused there). - No reason to implement KdpSysGetVersion per architecture; move it back to the generic code. - Add some ARM offsets to the debugger data block that (N/A on other architectures). - Fix the default size of the DbgPrint log buffer for free builds to save some space. It should be 4 KB for a free build and 32 KB for a checked build. - Move KeDisableInterrupts to cpu.c as it fits here more than in the IRQ support code in irqobj.c. - Use KeDisableInterrupts in KeFreezeExecution instead of checking the x86 EFLAG directly. svn path=/trunk/; revision=43912
2009-11-02 17:45:51 +00:00
extern CHAR KdPrintDefaultCircularBuffer[KD_DEFAULT_LOG_BUFFER_SIZE];
[NTOS:KD64] Implement KdLogDbgPrint() for the WinDbg !dbgprint command. See this command's documentation: https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/-dbgprint and the section "DbgPrint buffer and the debugger" https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/reading-and-filtering-debugging-messages#dbgprint-buffer-and-the-debugger for more details. - Loosely implement the function, based on our existing circular printout buffers in kdio.c. - Enable its usage in the KdpPrint() and KdpPrompt() functions. Notice that this function will *only* capture the strings being sent **to** the debugger, and not the strings the debugger itself produce. (This means that we cannot use the KdPrintCircularBuffer as a replacement for our KDBG dmesg one, for example...) How to test: Run ReactOS under WinDbg, and use the !dbgprint command to view the buffer. You can also use the Memory Window, place yourself at the address pointed by KdPrintCircularBuffer and KdPrintWritePointer, and read its contents. What you should observe: Prior notice: The circular buffer in debug builds of ReactOS and Windows is 0x8000 bytes large. In release builds, its size is down to 0x1000. 1- When you start e.g. the 2nd-stage GUI installation of ReactOS, going past the initial "devices installation" and letting it stabilize on the Welcome page, break into WinDbg and run the !dbgprint command. You should notice that the end of its output is weirdly truncated, compared to what has been actually emitted to the debug output. Comparing this with the actual contents of the circular buffer (via Memory Window), shows that the buffer contents is actually correct. 2- Copy all the text that has been output by the !dbgprint command and paste it in an editor; count the number of all characters appearing + newlines (only CR or LF), and observe that this number is "mysteriously" equal to 16384 == 0x4000. 3- Continue running ReactOS installation for a little while, breaking back back into WinDbg and looking at !dbgprint again. Its output seems to be still stopping at the same place as before (but the actual buffer memory contents shows otherwise). Continue running ROS installation, and break into the debugger when ROS is about to restart. You should now observe that the dbgprint buffer rolled over: dd nt!KdPrintRolloverCount shows 1. Carefully analysing the output of !dbgprint, however, you will notice that it looks a bit garbage-y: the first part of the output is actually truncated after 16384 characters, then you get a second part of the buffer showing what ReactOS was printing while shutting down. Then you get again what was shown at the top of the !dbgprint output. (Of course, comparing with the actual contents of the circular buffer in memory shows that its contents are fine...) The reason of these strange observations, is because there is an intrinsic bug in the !dbgprint command implementation (in kdexts.dll). Essentially, it displays the contents of the circular buffer in two single dprintf() calls: one for the "older" (bottom) part of the buffer: [WritePointer, EndOfBuffer] and one for the "newer" (upper) part of the buffer: [CircularBuffer, WritePointer[ . The first aspect of the bug (causing observation 3), is that those two parts are not necessarily NULL-terminated strings (especially after rollover), so for example, displaying the upper part of the buffer, will potentially also display part of the buffer's bottom part. The second aspect of the bug (explaining observations 1 and 2), is due to the implementation of the dprintf() function (callback in dbgenv.dll). There, it uses a fixed-sized buffer of size 0x4000 == 16384 characters. Since the output of the circular buffer is not done by little chunks, but by the two large parts, if any of those are larger than 0x4000 they get truncated on display. (This last observation is confirmed in a completely different context by https://community.osr.com/discussion/112439/dprintf-s-max-string-length .)
2022-11-23 22:24:59 +00:00
extern PCHAR KdPrintWritePointer;
extern ULONG KdPrintRolloverCount;
extern PCHAR KdPrintCircularBuffer;
extern ULONG KdPrintBufferSize;
extern ULONG KdPrintBufferChanges;
extern KSPIN_LOCK KdpPrintSpinLock;
extern BREAKPOINT_ENTRY KdpBreakpointTable[KD_BREAKPOINT_MAX];
extern KD_BREAKPOINT_TYPE KdpBreakpointInstruction;
extern BOOLEAN KdpOweBreakpoint;
extern BOOLEAN BreakpointsSuspended;
extern ULONG KdpNumInternalBreakpoints;
extern ULONG_PTR KdpCurrentSymbolStart, KdpCurrentSymbolEnd;
extern ULONG TraceDataBuffer[40];
extern ULONG TraceDataBufferPosition;
//
// Debug Filter Component Table
//
#define MAX_KD_COMPONENT_TABLE_ENTRIES (DPFLTR_ENDOFTABLE_ID + 1)
extern ULONG KdComponentTableSize;
extern PULONG KdComponentTable[MAX_KD_COMPONENT_TABLE_ENTRIES];
//
// Debug Filter Masks
//
extern ULONG Kd_WIN2000_Mask;
extern ULONG Kd_SYSTEM_Mask;
extern ULONG Kd_SMSS_Mask;
extern ULONG Kd_SETUP_Mask;
extern ULONG Kd_NTFS_Mask;
extern ULONG Kd_FSTUB_Mask;
extern ULONG Kd_CRASHDUMP_Mask;
extern ULONG Kd_CDAUDIO_Mask;
extern ULONG Kd_CDROM_Mask;
extern ULONG Kd_CLASSPNP_Mask;
extern ULONG Kd_DISK_Mask;
extern ULONG Kd_REDBOOK_Mask;
extern ULONG Kd_STORPROP_Mask;
extern ULONG Kd_SCSIPORT_Mask;
extern ULONG Kd_SCSIMINIPORT_Mask;
extern ULONG Kd_CONFIG_Mask;
extern ULONG Kd_I8042PRT_Mask;
extern ULONG Kd_SERMOUSE_Mask;
extern ULONG Kd_LSERMOUS_Mask;
extern ULONG Kd_KBDHID_Mask;
extern ULONG Kd_MOUHID_Mask;
extern ULONG Kd_KBDCLASS_Mask;
extern ULONG Kd_MOUCLASS_Mask;
extern ULONG Kd_TWOTRACK_Mask;
extern ULONG Kd_WMILIB_Mask;
extern ULONG Kd_ACPI_Mask;
extern ULONG Kd_AMLI_Mask;
extern ULONG Kd_HALIA64_Mask;
extern ULONG Kd_VIDEO_Mask;
extern ULONG Kd_SVCHOST_Mask;
extern ULONG Kd_VIDEOPRT_Mask;
extern ULONG Kd_TCPIP_Mask;
extern ULONG Kd_DMSYNTH_Mask;
extern ULONG Kd_NTOSPNP_Mask;
extern ULONG Kd_FASTFAT_Mask;
extern ULONG Kd_SAMSS_Mask;
extern ULONG Kd_PNPMGR_Mask;
extern ULONG Kd_NETAPI_Mask;
extern ULONG Kd_SCSERVER_Mask;
extern ULONG Kd_SCCLIENT_Mask;
extern ULONG Kd_SERIAL_Mask;
extern ULONG Kd_SERENUM_Mask;
extern ULONG Kd_UHCD_Mask;
extern ULONG Kd_RPCPROXY_Mask;
extern ULONG Kd_AUTOCHK_Mask;
extern ULONG Kd_DCOMSS_Mask;
extern ULONG Kd_UNIMODEM_Mask;
extern ULONG Kd_SIS_Mask;
extern ULONG Kd_FLTMGR_Mask;
extern ULONG Kd_WMICORE_Mask;
extern ULONG Kd_BURNENG_Mask;
extern ULONG Kd_IMAPI_Mask;
extern ULONG Kd_SXS_Mask;
extern ULONG Kd_FUSION_Mask;
extern ULONG Kd_IDLETASK_Mask;
extern ULONG Kd_SOFTPCI_Mask;
extern ULONG Kd_TAPE_Mask;
extern ULONG Kd_MCHGR_Mask;
extern ULONG Kd_IDEP_Mask;
extern ULONG Kd_PCIIDE_Mask;
extern ULONG Kd_FLOPPY_Mask;
extern ULONG Kd_FDC_Mask;
extern ULONG Kd_TERMSRV_Mask;
extern ULONG Kd_W32TIME_Mask;
extern ULONG Kd_PREFETCHER_Mask;
extern ULONG Kd_RSFILTER_Mask;
extern ULONG Kd_FCPORT_Mask;
extern ULONG Kd_PCI_Mask;
extern ULONG Kd_DMIO_Mask;
extern ULONG Kd_DMCONFIG_Mask;
extern ULONG Kd_DMADMIN_Mask;
extern ULONG Kd_WSOCKTRANSPORT_Mask;
extern ULONG Kd_VSS_Mask;
extern ULONG Kd_PNPMEM_Mask;
extern ULONG Kd_PROCESSOR_Mask;
extern ULONG Kd_DMSERVER_Mask;
extern ULONG Kd_SR_Mask;
extern ULONG Kd_INFINIBAND_Mask;
extern ULONG Kd_IHVDRIVER_Mask;
extern ULONG Kd_IHVVIDEO_Mask;
extern ULONG Kd_IHVAUDIO_Mask;
extern ULONG Kd_IHVNETWORK_Mask;
extern ULONG Kd_IHVSTREAMING_Mask;
extern ULONG Kd_IHVBUS_Mask;
extern ULONG Kd_HPS_Mask;
extern ULONG Kd_RTLTHREADPOOL_Mask;
extern ULONG Kd_LDR_Mask;
extern ULONG Kd_TCPIP6_Mask;
extern ULONG Kd_ISAPNP_Mask;
extern ULONG Kd_SHPC_Mask;
extern ULONG Kd_STORPORT_Mask;
extern ULONG Kd_STORMINIPORT_Mask;
extern ULONG Kd_PRINTSPOOLER_Mask;
extern ULONG Kd_VSSDYNDISK_Mask;
extern ULONG Kd_VERIFIER_Mask;
extern ULONG Kd_VDS_Mask;
extern ULONG Kd_VDSBAS_Mask;
extern ULONG Kd_VDSDYN_Mask; // Specified in Vista+
extern ULONG Kd_VDSDYNDR_Mask;
extern ULONG Kd_VDSLDR_Mask; // Specified in Vista+
extern ULONG Kd_VDSUTIL_Mask;
extern ULONG Kd_DFRGIFC_Mask;
extern ULONG Kd_DEFAULT_Mask;
extern ULONG Kd_MM_Mask;
extern ULONG Kd_DFSC_Mask;
extern ULONG Kd_WOW64_Mask;
//
// Components specified in Vista+, some of which we also use in ReactOS
//
extern ULONG Kd_ALPC_Mask;
extern ULONG Kd_WDI_Mask;
extern ULONG Kd_PERFLIB_Mask;
extern ULONG Kd_KTM_Mask;
extern ULONG Kd_IOSTRESS_Mask;
extern ULONG Kd_HEAP_Mask;
extern ULONG Kd_WHEA_Mask;
extern ULONG Kd_USERGDI_Mask;
extern ULONG Kd_MMCSS_Mask;
extern ULONG Kd_TPM_Mask;
extern ULONG Kd_THREADORDER_Mask;
extern ULONG Kd_ENVIRON_Mask;
extern ULONG Kd_EMS_Mask;
extern ULONG Kd_WDT_Mask;
extern ULONG Kd_FVEVOL_Mask;
extern ULONG Kd_NDIS_Mask;
extern ULONG Kd_NVCTRACE_Mask;
extern ULONG Kd_LUAFV_Mask;
extern ULONG Kd_APPCOMPAT_Mask;
extern ULONG Kd_USBSTOR_Mask;
extern ULONG Kd_SBP2PORT_Mask;
extern ULONG Kd_COVERAGE_Mask;
extern ULONG Kd_CACHEMGR_Mask;
extern ULONG Kd_MOUNTMGR_Mask;
extern ULONG Kd_CFR_Mask;
extern ULONG Kd_TXF_Mask;
extern ULONG Kd_KSECDD_Mask;
extern ULONG Kd_FLTREGRESS_Mask;
extern ULONG Kd_MPIO_Mask;
extern ULONG Kd_MSDSM_Mask;
extern ULONG Kd_UDFS_Mask;
extern ULONG Kd_PSHED_Mask;
extern ULONG Kd_STORVSP_Mask;
extern ULONG Kd_LSASS_Mask;
extern ULONG Kd_SSPICLI_Mask;
extern ULONG Kd_CNG_Mask;
extern ULONG Kd_EXFAT_Mask;
extern ULONG Kd_FILETRACE_Mask;
extern ULONG Kd_XSAVE_Mask;
extern ULONG Kd_SE_Mask;
extern ULONG Kd_DRIVEEXTENDER_Mask;
//
// Components specified in Windows 8
//
extern ULONG Kd_POWER_Mask;
extern ULONG Kd_CRASHDUMPXHCI_Mask;
extern ULONG Kd_GPIO_Mask;
extern ULONG Kd_REFS_Mask;
extern ULONG Kd_WER_Mask;
//
// Components specified in Windows 10
//
extern ULONG Kd_CAPIMG_Mask;
extern ULONG Kd_VPCI_Mask;
extern ULONG Kd_STORAGECLASSMEMORY_Mask;
extern ULONG Kd_FSLIB_Mask;