[NTOS:KD/KDROSDBG] Move debug output from ntoskrnl to kdcom.dll

CORE-10749
This commit is contained in:
Hervé Poussineau 2022-07-10 15:59:41 +02:00
parent 8cf3e9942b
commit 6a48b358cd
2 changed files with 141 additions and 118 deletions

View file

@ -63,6 +63,10 @@ typedef struct _KDP_DEBUG_MODE
ULONG KdbDebugState = 0; /* KDBG Settings (NOECHO, KDSERIAL) */
KDP_DEBUG_MODE KdpDebugMode;
#define KdpScreenLineLengthDefault 80
static CHAR KdpScreenLineBuffer[KdpScreenLineLengthDefault + 1] = "";
static ULONG KdpScreenLineBufferPos = 0, KdpScreenLineLength = 0;
/* Port Information for the Serial Native Mode */
ULONG SerialPortNumber;
CPPORT SerialPortInfo;
@ -165,6 +169,57 @@ KdpGetDebugMode(PCHAR Currentp2)
/* SCREEN FUNCTIONS **********************************************************/
static VOID
NTAPI
KdpScreenDebugPrint(PCHAR String,
ULONG Length)
{
PCHAR pch = String;
while (pch < String + Length && *pch)
{
if (*pch == '\b')
{
/* HalDisplayString does not support '\b'. Workaround it and use '\r' */
if (KdpScreenLineLength > 0)
{
/* Remove last character from buffer */
KdpScreenLineBuffer[--KdpScreenLineLength] = '\0';
KdpScreenLineBufferPos = KdpScreenLineLength;
/* Clear row and print line again */
HalDisplayString("\r");
HalDisplayString(KdpScreenLineBuffer);
}
}
else
{
KdpScreenLineBuffer[KdpScreenLineLength++] = *pch;
KdpScreenLineBuffer[KdpScreenLineLength] = '\0';
}
if (*pch == '\n' || KdpScreenLineLength == KdpScreenLineLengthDefault)
{
/* Print buffered characters */
if (KdpScreenLineBufferPos != KdpScreenLineLength)
HalDisplayString(KdpScreenLineBuffer + KdpScreenLineBufferPos);
/* Clear line buffer */
KdpScreenLineBuffer[0] = '\0';
KdpScreenLineLength = KdpScreenLineBufferPos = 0;
}
++pch;
}
/* Print buffered characters */
if (KdpScreenLineBufferPos != KdpScreenLineLength)
{
HalDisplayString(KdpScreenLineBuffer + KdpScreenLineBufferPos);
KdpScreenLineBufferPos = KdpScreenLineLength;
}
}
static VOID
KdpScreenAcquire(VOID)
{
@ -202,6 +257,25 @@ KdpScreenInit(ULONG BootPhase)
/* SERIAL FUNCTIONS **********************************************************/
static VOID
NTAPI
KdpSerialDebugPrint(PCHAR String,
ULONG Length)
{
PCHAR pch = String;
/* Output the message */
while (pch < String + Length && *pch != '\0')
{
if (*pch == '\n')
{
CpPutByte(&SerialPortInfo, '\r');
}
CpPutByte(&SerialPortInfo, *pch);
pch++;
}
}
static BOOLEAN
NTAPI
KdPortInitializeEx(
@ -263,6 +337,10 @@ KdpSerialInit(ULONG BootPhase)
/* FILE FUNCTIONS **********************************************************/
static VOID
NTAPI
KdpFileInit(ULONG BootPhase);
static VOID
NTAPI
KdpLoggerThread(PVOID Context)
@ -310,6 +388,52 @@ KdpLoggerThread(PVOID Context)
}
}
static VOID
NTAPI
KdpFileDebugPrint(PCHAR String,
ULONG Length)
{
ULONG beg, end, num;
if (KdpDebugBuffer == NULL)
return;
if (!KdpLogFileHandle)
{
KIRQL OldIrql = KeGetCurrentIrql();
KeLowerIrql(PASSIVE_LEVEL);
KdpFileInit(3);
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
}
beg = KdpCurrentPosition;
num = KdpFreeBytes;
if (Length < num)
num = Length;
if (num != 0)
{
end = (beg + num) % KdpBufferSize;
KdpCurrentPosition = end;
KdpFreeBytes -= num;
if (end > beg)
{
RtlCopyMemory(KdpDebugBuffer + beg, String, num);
}
else
{
RtlCopyMemory(KdpDebugBuffer + beg, String, KdpBufferSize - beg);
RtlCopyMemory(KdpDebugBuffer, String + KdpBufferSize - beg, end);
}
}
/* Signal the logger thread */
if (KdpLogFileHandle)
KeSetEvent(&KdpLoggerThreadEvent, IO_NO_INCREMENT, FALSE);
}
static VOID
NTAPI
KdpFileInit(ULONG BootPhase)
@ -407,6 +531,18 @@ KdpFileInit(ULONG BootPhase)
}
}
static VOID
KdpPrintString(
_In_ PSTRING Output)
{
if (KdpDebugMode.Screen)
KdpScreenDebugPrint(Output->Buffer, Output->Length);
if (KdpDebugMode.Serial)
KdpSerialDebugPrint(Output->Buffer, Output->Length);
if (KdpDebugMode.File)
KdpFileDebugPrint(Output->Buffer, Output->Length);
}
/* FUNCTIONS ****************************************************************/
/*
@ -534,6 +670,11 @@ KdSendPacket(
IN PSTRING MessageData,
IN OUT PKD_CONTEXT Context)
{
if (PacketType == PACKET_TYPE_KD_DEBUG_IO)
{
KdpPrintString(MessageData);
return;
}
}
/*

View file

@ -23,8 +23,6 @@
/* GLOBALS *******************************************************************/
#define KdpBufferSize (1024 * 512)
static BOOLEAN KdpLoggingEnabled = FALSE;
static BOOLEAN KdpLoggingStarting = FALSE;
static PCHAR KdpDebugBuffer = NULL;
static volatile ULONG KdpCurrentPosition = 0;
static volatile ULONG KdpFreeBytes = 0;
@ -38,10 +36,6 @@ static KSPIN_LOCK KdpSerialSpinLock;
ULONG SerialPortNumber = DEFAULT_DEBUG_PORT;
CPPORT SerialPortInfo = {0, DEFAULT_DEBUG_BAUD_RATE, 0};
#define KdpScreenLineLengthDefault 80
static CHAR KdpScreenLineBuffer[KdpScreenLineLengthDefault + 1] = "";
static ULONG KdpScreenLineBufferPos = 0, KdpScreenLineLength = 0;
KDP_DEBUG_MODE KdpDebugMode;
LIST_ENTRY KdProviders = {&KdProviders, &KdProviders};
KD_DISPATCH_TABLE DispatchTable[KdMax];
@ -114,8 +108,6 @@ KdpLoggerThread(PVOID Context)
ASSERT(ExGetPreviousMode() == KernelMode);
KdpLoggingEnabled = TRUE;
while (TRUE)
{
KeWaitForSingleObject(&KdpLoggerThreadEvent, Executive, KernelMode, FALSE, NULL);
@ -159,53 +151,6 @@ NTAPI
KdpPrintToLogFile(PCHAR String,
ULONG Length)
{
KIRQL OldIrql;
ULONG beg, end, num;
BOOLEAN DoReinit = FALSE;
if (KdpDebugBuffer == NULL) return;
/* Acquire the printing spinlock without waiting at raised IRQL */
OldIrql = KdpAcquireLock(&KdpDebugLogSpinLock);
beg = KdpCurrentPosition;
num = KdpFreeBytes;
if (Length < num)
num = Length;
if (num != 0)
{
end = (beg + num) % KdpBufferSize;
KdpCurrentPosition = end;
KdpFreeBytes -= num;
if (end > beg)
{
RtlCopyMemory(KdpDebugBuffer + beg, String, num);
}
else
{
RtlCopyMemory(KdpDebugBuffer + beg, String, KdpBufferSize - beg);
RtlCopyMemory(KdpDebugBuffer, String + KdpBufferSize - beg, end);
}
}
/* Release the spinlock */
if (OldIrql == PASSIVE_LEVEL && !KdpLoggingStarting && !KdpLoggingEnabled && ExpInitializationPhase >= 2)
{
DoReinit = TRUE;
}
KdpReleaseLock(&KdpDebugLogSpinLock, OldIrql);
if (DoReinit)
{
KdpLoggingStarting = TRUE;
KdpDebugLogInit(NULL, 3);
}
/* Signal the logger thread */
if (OldIrql <= DISPATCH_LEVEL && KdpLoggingEnabled)
KeSetEvent(&KdpLoggerThreadEvent, IO_NO_INCREMENT, FALSE);
}
VOID
@ -315,25 +260,6 @@ NTAPI
KdpSerialPrint(PCHAR String,
ULONG Length)
{
PCHAR pch = String;
KIRQL OldIrql;
/* Acquire the printing spinlock without waiting at raised IRQL */
OldIrql = KdpAcquireLock(&KdpSerialSpinLock);
/* Output the string */
while (pch < String + Length && *pch)
{
if (*pch == '\n')
{
KdPortPutByteEx(&SerialPortInfo, '\r');
}
KdPortPutByteEx(&SerialPortInfo, *pch);
pch++;
}
/* Release the spinlock */
KdpReleaseLock(&KdpSerialSpinLock, OldIrql);
}
VOID
@ -407,50 +333,6 @@ NTAPI
KdpScreenPrint(PCHAR String,
ULONG Length)
{
PCHAR pch = String;
while (pch < String + Length && *pch)
{
if (*pch == '\b')
{
/* HalDisplayString does not support '\b'. Workaround it and use '\r' */
if (KdpScreenLineLength > 0)
{
/* Remove last character from buffer */
KdpScreenLineBuffer[--KdpScreenLineLength] = '\0';
KdpScreenLineBufferPos = KdpScreenLineLength;
/* Clear row and print line again */
HalDisplayString("\r");
HalDisplayString(KdpScreenLineBuffer);
}
}
else
{
KdpScreenLineBuffer[KdpScreenLineLength++] = *pch;
KdpScreenLineBuffer[KdpScreenLineLength] = '\0';
}
if (*pch == '\n' || KdpScreenLineLength == KdpScreenLineLengthDefault)
{
/* Print buffered characters */
if (KdpScreenLineBufferPos != KdpScreenLineLength)
HalDisplayString(KdpScreenLineBuffer + KdpScreenLineBufferPos);
/* Clear line buffer */
KdpScreenLineBuffer[0] = '\0';
KdpScreenLineLength = KdpScreenLineBufferPos = 0;
}
++pch;
}
/* Print buffered characters */
if (KdpScreenLineBufferPos != KdpScreenLineLength)
{
HalDisplayString(KdpScreenLineBuffer + KdpScreenLineBufferPos);
KdpScreenLineBufferPos = KdpScreenLineLength;
}
}
VOID