Alex Ionescu <ionucu@videotron.ca>

Various bugcheck code improvements:
- Fix bugcheck code and make debugging easier for unhandled exceptions/spinlocks.
- Fix a race condition with TAB+B,
- Fix irql to be high_level.
- Fix calling unsafe function by caching bugcode data.
- Fix support for smp by using IPI.
- Fix not-breakpointing when no debugger is there.
- Implement KeBugCheck callbacks with reason.
- Fix callbacks not being called.
- Fix proper breakpoint during bugcheck.
Filip Navara <xnavara@volny.cz>
- Move the bugcheck initialization code into Ke (was in Ex on Alex's branch).

svn path=/trunk/; revision=13969
This commit is contained in:
Filip Navara 2005-03-12 16:01:30 +00:00
parent 5307ffb9c6
commit f954a88f34
7 changed files with 414 additions and 191 deletions

View file

@ -38,11 +38,11 @@
/* Assert only on "checked" version */
#ifndef NASSERT
#ifdef CONFIG_SMP
#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), KeBugCheck(0); }
#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), KeBugCheck(0); }
#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), DbgBreakPoint(); }
#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), DbgBreakPoint(); }
#else
#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); }
#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); }
#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); DbgBreakPoint(); }
#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); DbgBreakPoint(); }
#endif
#define assertmsg(_c_, _m_) \

View file

@ -196,7 +196,7 @@ VOID KeInitDpc(struct _KPCR* Pcr);
VOID KeInitDispatcher(VOID);
VOID KeInitializeDispatcher(VOID);
VOID KiInitializeSystemClock(VOID);
VOID KeInitializeBugCheck(VOID);
VOID KiInitializeBugCheck(VOID);
VOID Phase1Initialization(PVOID Context);
VOID KeInit1(PCHAR CommandLine, PULONG LastKernelAddress);

View file

@ -1,200 +1,445 @@
/* $Id$
*
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/bug.c
* PURPOSE: Graceful system shutdown if a bug is detected
*
* PROGRAMMERS: David Welch (welch@cwcom.net)
* PROGRAMMERS: Alex Ionescu - Rewrote Bugcheck Routines and implemented Reason Callbacks.
* David Welch (welch@cwcom.net)
* Phillip Susi
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#include <ntos/bootvid.h>
#define NDEBUG
#include <internal/debug.h>
#include "../../hal/halx86/include/hal.h"
/* GLOBALS ******************************************************************/
static LIST_ENTRY BugcheckCallbackListHead = {NULL,NULL};
static LIST_ENTRY BugcheckReasonCallbackListHead = {NULL,NULL};
static ULONG InBugCheck;
static PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages;
static ULONG KeBugCheckCount = 1;
/* FUNCTIONS *****************************************************************/
VOID INIT_FUNCTION
KeInitializeBugCheck(VOID)
VOID
INIT_FUNCTION
KiInitializeBugCheck(VOID)
{
InitializeListHead(&BugcheckCallbackListHead);
InBugCheck = 0;
PRTL_MESSAGE_RESOURCE_DATA BugCheckData;
LDR_RESOURCE_INFO ResourceInfo;
PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
NTSTATUS Status;
/* Initialize Callbadk Listhead and State */
InitializeListHead(&BugcheckCallbackListHead);
InitializeListHead(&BugcheckReasonCallbackListHead);
InBugCheck = 0;
/* Cache the Bugcheck Message Strings. Prepare the Lookup Data */
ResourceInfo.Type = 11;
ResourceInfo.Name = 1;
ResourceInfo.Language = 9;
/* Do the lookup. */
Status = LdrFindResource_U((PVOID)KERNEL_BASE,
&ResourceInfo,
RESOURCE_DATA_LEVEL,
&ResourceDataEntry);
/* Make sure it worked */
if (NT_SUCCESS(Status)) {
DPRINT1("Found Bugcheck Resource Data!\n");
/* Now actually get a pointer to it */
Status = LdrAccessResource((PVOID)KERNEL_BASE,
ResourceDataEntry,
(PVOID*)&BugCheckData,
NULL);
/* Make sure it worked */
if (NT_SUCCESS(Status)) {
DPRINT1("Got Pointer to Bugcheck Resource Data!\n");
KiBugCodeMessages = BugCheckData;
}
}
}
/*
* @implemented
*/
BOOLEAN STDCALL
BOOLEAN
STDCALL
KeDeregisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord)
{
/* Check the Current State */
if (CallbackRecord->State == BufferInserted) {
CallbackRecord->State = BufferEmpty;
RemoveEntryList(&CallbackRecord->Entry);
return TRUE;
}
/* The callback wasn't registered */
return FALSE;
KIRQL OldIrql;
BOOLEAN Status = FALSE;
/* Raise IRQL to High */
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
/* Check the Current State */
if (CallbackRecord->State == BufferInserted) {
/* Reset state and remove from list */
CallbackRecord->State = BufferEmpty;
RemoveEntryList(&CallbackRecord->Entry);
Status = TRUE;
}
/* Lower IRQL and return */
KeLowerIrql(OldIrql);
return Status;
}
/*
* @implemented
*/
BOOLEAN STDCALL
KeRegisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord,
PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine,
PVOID Buffer,
ULONG Length,
PUCHAR Component)
BOOLEAN
STDCALL
KeDeregisterBugCheckReasonCallback(IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord)
{
KIRQL OldIrql;
BOOLEAN Status = FALSE;
/* Raise IRQL to High */
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
/* Check the Current State */
if (CallbackRecord->State == BufferInserted) {
/* Check the Current State first so we don't double-register */
if (CallbackRecord->State == BufferEmpty) {
CallbackRecord->Length = Length;
CallbackRecord->Buffer = Buffer;
CallbackRecord->Component = Component;
CallbackRecord->CallbackRoutine = CallbackRoutine;
CallbackRecord->State = BufferInserted;
InsertTailList(&BugcheckCallbackListHead, &CallbackRecord->Entry);
return TRUE;
}
/* The Callback was already registered */
return(FALSE);
/* Reset state and remove from list */
CallbackRecord->State = BufferEmpty;
RemoveEntryList(&CallbackRecord->Entry);
Status = TRUE;
}
/* Lower IRQL and return */
KeLowerIrql(OldIrql);
return Status;
}
VOID STDCALL
KeBugCheckWithTf(ULONG BugCheckCode,
ULONG BugCheckParameter1,
ULONG BugCheckParameter2,
ULONG BugCheckParameter3,
ULONG BugCheckParameter4,
PKTRAP_FRAME Tf)
/*
* @implemented
*/
BOOLEAN
STDCALL
KeRegisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord,
PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine,
PVOID Buffer,
ULONG Length,
PUCHAR Component)
{
PRTL_MESSAGE_RESOURCE_ENTRY Message;
NTSTATUS Status;
ULONG Mask;
KIRQL OldIrql;
/* Make sure we're switching back to the blue screen and print messages on it */
HalReleaseDisplayOwnership();
if (0 == (KdDebugState & KD_DEBUG_GDB))
{
KdDebugState |= KD_DEBUG_SCREEN;
KIRQL OldIrql;
BOOLEAN Status = FALSE;
/* Raise IRQL to High */
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
/* Check the Current State first so we don't double-register */
if (CallbackRecord->State == BufferEmpty) {
/* Set the Callback Settings and insert into the list */
CallbackRecord->Length = Length;
CallbackRecord->Buffer = Buffer;
CallbackRecord->Component = Component;
CallbackRecord->CallbackRoutine = CallbackRoutine;
CallbackRecord->State = BufferInserted;
InsertTailList(&BugcheckCallbackListHead, &CallbackRecord->Entry);
Status = TRUE;
}
Ke386DisableInterrupts();
DebugLogDumpMessages();
/* Lower IRQL and return */
KeLowerIrql(OldIrql);
return Status;
}
if (MmGetKernelAddressSpace()->Lock.Owner == KeGetCurrentThread())
{
MmUnlockAddressSpace(MmGetKernelAddressSpace());
/*
* @implemented
*/
BOOLEAN
STDCALL
KeRegisterBugCheckReasonCallback(IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord,
IN PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine,
IN KBUGCHECK_CALLBACK_REASON Reason,
IN PUCHAR Component)
{
KIRQL OldIrql;
BOOLEAN Status = FALSE;
/* Raise IRQL to High */
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
/* Check the Current State first so we don't double-register */
if (CallbackRecord->State == BufferEmpty) {
/* Set the Callback Settings and insert into the list */
CallbackRecord->Component = Component;
CallbackRecord->CallbackRoutine = CallbackRoutine;
CallbackRecord->State = BufferInserted;
CallbackRecord->Reason = Reason;
InsertTailList(&BugcheckReasonCallbackListHead, &CallbackRecord->Entry);
Status = TRUE;
}
if (KeGetCurrentIrql() < DISPATCH_LEVEL)
{
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
}
DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
BugCheckCode,
BugCheckParameter1,
BugCheckParameter2,
BugCheckParameter3,
BugCheckParameter4);
/* Lower IRQL and return */
KeLowerIrql(OldIrql);
return Status;
}
Status = RtlFindMessage((PVOID)KERNEL_BASE, //0xC0000000,
11, //RT_MESSAGETABLE,
0x09, //0x409,
BugCheckCode,
&Message);
if (NT_SUCCESS(Status))
{
if (Message->Flags == 0)
DbgPrint(" %s\n", Message->Text);
else
DbgPrint(" %S\n", (PWSTR)Message->Text);
VOID
STDCALL
KeGetBugMessageText(ULONG BugCheckCode, PANSI_STRING OutputString)
{
ULONG i;
ULONG IdOffset;
ULONG_PTR MessageEntry;
PCHAR BugCode;
/* Find the message. This code is based on RtlFindMesssage -- Alex */
for (i = 0; i < KiBugCodeMessages->NumberOfBlocks; i++) {
/* Check if the ID Matches */
if ((BugCheckCode >= KiBugCodeMessages->Blocks[i].LowId) &&
(BugCheckCode <= KiBugCodeMessages->Blocks[i].HighId)) {
/* Get Offset to Entry */
MessageEntry = (ULONG_PTR)KiBugCodeMessages + KiBugCodeMessages->Blocks[i].OffsetToEntries;
IdOffset = BugCheckCode - KiBugCodeMessages->Blocks[i].LowId;
/* Get offset to ID */
for (i = 0; i < IdOffset; i++) {
/* Advance in the Entries */
MessageEntry += ((PRTL_MESSAGE_RESOURCE_ENTRY)MessageEntry)->Length;
}
/* Get the final Code */
BugCode = ((PRTL_MESSAGE_RESOURCE_ENTRY)MessageEntry)->Text;
/* Return it in the OutputString */
if (OutputString) {
OutputString->Buffer = BugCode;
OutputString->Length = strlen(BugCode) + 1;
OutputString->MaximumLength = strlen(BugCode) + 1;
} else {
/* Direct Output to Screen */
DbgPrint("%s\n", BugCode);
break;
}
}
}
else
{
DbgPrint(" No message text found!\n\n");
}
VOID
STDCALL
KiDoBugCheckCallbacks(VOID)
{
PKBUGCHECK_CALLBACK_RECORD CurrentRecord;
PLIST_ENTRY ListHead;
PLIST_ENTRY NextEntry;
/* FIXME: Check Checksum and add support for WithReason Callbacks */
/* First make sure that the list is Initialized... it might not be */
ListHead = &BugcheckCallbackListHead;
if (ListHead->Flink && ListHead->Blink) {
/* Loop the list */
NextEntry = ListHead->Flink;
while (NextEntry != ListHead) {
/* Get the Callback Record */
CurrentRecord = CONTAINING_RECORD(NextEntry,
KBUGCHECK_CALLBACK_RECORD,
Entry);
/* Make sure it's inserted */
if (CurrentRecord->State == BufferInserted) {
/* Call the routine */
CurrentRecord->State = BufferStarted;
(CurrentRecord->CallbackRoutine)(CurrentRecord->Buffer,
CurrentRecord->Length);
CurrentRecord->State = BufferFinished;
}
/* Move to next Entry */
NextEntry = NextEntry->Flink;
}
}
Mask = 1 << KeGetCurrentProcessorNumber();
if (InBugCheck & Mask)
{
#ifdef MP
DbgPrint("Recursive bug check on CPU%d, halting now\n", KeGetCurrentProcessorNumber());
/*
* FIXME:
* Send an ipi to all other processors which halt them too.
*/
#else
DbgPrint("Recursive bug check halting now\n");
}
VOID
STDCALL
KeBugCheckWithTf(ULONG BugCheckCode,
ULONG BugCheckParameter1,
ULONG BugCheckParameter2,
ULONG BugCheckParameter3,
ULONG BugCheckParameter4,
PKTRAP_FRAME Tf)
{
KIRQL OldIrql;
BOOLEAN GotExtendedCrashInfo = FALSE;
PVOID Address = 0;
PLIST_ENTRY CurrentEntry;
MODULE_TEXT_SECTION* CurrentSection = NULL;
extern LIST_ENTRY ModuleTextListHead;
/* Make sure we're switching back to the blue screen and print messages on it */
HalReleaseDisplayOwnership();
if (0 == (KdDebugState & KD_DEBUG_GDB)) KdDebugState |= KD_DEBUG_SCREEN;
/* Try to find out who did this. For this, we need a Trap Frame.
* Note: Some special BSODs pass the Frame/EIP as a Param. MSDN has the
* info so it eventually needs to be supported.
*/
if (Tf) {
/* For now, get Address from EIP */
Address = (PVOID)Tf->Eip;
/* Try to get information on the module */
CurrentEntry = ModuleTextListHead.Flink;
while (CurrentEntry != &ModuleTextListHead && CurrentEntry != NULL) {
/* Get the current Section */
CurrentSection = CONTAINING_RECORD(CurrentEntry,
MODULE_TEXT_SECTION,
ListEntry);
/* Check if this is the right one */
if ((Address != NULL && (Address >= (PVOID)CurrentSection->Base &&
Address < (PVOID)(CurrentSection->Base + CurrentSection->Length)))) {
/* We got it */
GotExtendedCrashInfo = TRUE;
break;
}
/* Loop again */
CurrentEntry = CurrentEntry->Flink;
}
}
/* Raise IRQL to HIGH_LEVEL */
Ke386DisableInterrupts();
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
/* Disable Interrupts, Dump Debug Messages */
DebugLogDumpMessages();
/* Unload the Kernel Adress Space if we own it */
if (MmGetKernelAddressSpace()->Lock.Owner == KeGetCurrentThread())
MmUnlockAddressSpace(MmGetKernelAddressSpace());
/* FIXMEs: Use inbv to clear, fill and write to screen. */
/* Show the STOP Message */
DbgPrint("A problem has been detected and ReactOS has been shut down to prevent "
"damage to your computer.\n\n");
/* Show the module name of who caused this */
if (GotExtendedCrashInfo) {
DbgPrint("The problem seems to be caused by the following file: %S\n\n", CurrentSection->Name);
}
/* Find the Bug Code String */
KeGetBugMessageText(BugCheckCode, NULL);
/* Show the techincal Data */
DbgPrint("Technical information:\n\n*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)\n\n",
BugCheckCode,
BugCheckParameter1,
BugCheckParameter2,
BugCheckParameter3,
BugCheckParameter4);
/* Show the module name and more data of who caused this */
if (GotExtendedCrashInfo) {
DbgPrint("*** %S - Address 0x%p base at 0x%p, DateStamp 0x%x\n\n",
CurrentSection->Name,
Address,
CurrentSection->Base,
0);
}
/* There can only be one Bugcheck per Bootup */
if (!InterlockedDecrement(&KeBugCheckCount)) {
#ifdef CONFIG_SMP
ULONG i;
/* Freeze the other CPUs */
for (i = 0; i < KeNumberProcessors; i++) {
if (i != KeGetCurrentProcessorNumber()) {
/* Send the IPI and give them one second to catch up */
KiIpiSendRequest(1 << i, IPI_REQUEST_FREEZE);
KeStallExecutionProcessor(1000000);
}
}
#endif
Ke386HaltProcessor();
}
/*
* FIXME:
* Use InterlockedOr or InterlockedBitSet.
*/
InBugCheck |= Mask;
if (Tf != NULL)
{
KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2);
}
else
{
/* Check if we got a Trap Frame */
if (Tf) {
/* Dump it */
KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2);
} else {
/* We can only dump the frames */
#if defined(__GNUC__)
KeDumpStackFrames((PULONG)__builtin_frame_address(0));
KeDumpStackFrames((PULONG)__builtin_frame_address(0));
#elif defined(_MSC_VER)
__asm push ebp
__asm call KeDumpStackFrames
__asm add esp, 4
__asm push ebp
__asm call KeDumpStackFrames
__asm add esp, 4
#else
#error Unknown compiler for inline assembler
#endif
}
MmDumpToPagingFile(BugCheckCode, BugCheckParameter1,
BugCheckParameter2, BugCheckParameter3,
BugCheckParameter4, Tf);
}
/* Call the Callbacks */;
KiDoBugCheckCallbacks();
if (KdDebuggerEnabled)
{
Ke386EnableInterrupts();
DbgBreakPointNoBugCheck();
Ke386DisableInterrupts();
/* Dump the BSOD to the Paging File */
MmDumpToPagingFile(BugCheckCode,
BugCheckParameter1,
BugCheckParameter2,
BugCheckParameter3,
BugCheckParameter4,
Tf);
/* Wake up the Debugger */
if (KdDebuggerEnabled) {
Ke386EnableInterrupts();
DbgBreakPointWithStatus(DBG_STATUS_BUGCHECK_SECOND);
Ke386DisableInterrupts();
}
}
for (;;)
{
/*
* FIXME:
* Send an ipi to all other processors which halt them too.
*/
Ke386HaltProcessor();
}
/* Halt this CPU now */
for (;;) Ke386HaltProcessor();
}
/*
* @implemented
*/
VOID STDCALL
KeBugCheckEx(ULONG BugCheckCode,
ULONG BugCheckParameter1,
ULONG BugCheckParameter2,
ULONG BugCheckParameter3,
ULONG BugCheckParameter4)
/*
*
* FUNCTION: Brings the system down in a controlled manner when an
* inconsistency that might otherwise cause corruption has been detected
* ARGUMENTS:
@ -202,23 +447,34 @@ KeBugCheckEx(ULONG BugCheckCode,
* BugCheckParameter[1-4] = Additional information about bug
* RETURNS: Doesn't
*/
VOID
STDCALL
KeBugCheckEx(ULONG BugCheckCode,
ULONG BugCheckParameter1,
ULONG BugCheckParameter2,
ULONG BugCheckParameter3,
ULONG BugCheckParameter4)
{
KeBugCheckWithTf(BugCheckCode, BugCheckParameter1, BugCheckParameter2,
BugCheckParameter3, BugCheckParameter4, NULL);
/* Call the Trap Frame version without a Trap Frame */
KeBugCheckWithTf(BugCheckCode,
BugCheckParameter1,
BugCheckParameter2,
BugCheckParameter3,
BugCheckParameter4,
NULL);
}
/*
* @implemented
*/
VOID STDCALL
KeBugCheck(ULONG BugCheckCode)
/*
*
* FUNCTION: Brings the system down in a controlled manner when an
* inconsistency that might otherwise cause corruption has been detected
* ARGUMENTS:
* BugCheckCode = Specifies the reason for the bug check
* RETURNS: Doesn't
*/
VOID STDCALL
KeBugCheck(ULONG BugCheckCode)
{
KeBugCheckEx(BugCheckCode, 0, 0, 0, 0);
}

View file

@ -257,19 +257,6 @@ ExRaiseHardError (
UNIMPLEMENTED;
}
/*
* @unimplemented
*/
BOOLEAN
STDCALL
KeDeregisterBugCheckReasonCallback(
IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord
)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
@ -283,20 +270,4 @@ KeGetRecommendedSharedDataAlignment(
return 0;
}
/*
* @unimplemented
*/
BOOLEAN
STDCALL
KeRegisterBugCheckReasonCallback(
IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord,
IN PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine,
IN KBUGCHECK_CALLBACK_REASON Reason,
IN PUCHAR Component
)
{
UNIMPLEMENTED;
return FALSE;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id:$
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -34,10 +34,10 @@ DbgBreakPoint(VOID)
* @implemented
*/
#if defined(__GNUC__)
__asm__(".globl _DbgBreakPointNoBugCheck@0\n\t"
"_DbgBreakPointNoBugCheck@0:\n\t"
"int $3\n\t"
"ret\n\t");
__asm__(".globl _DbgBreakPointNoBugCheck@0\n\t"
"_DbgBreakPointNoBugCheck@0:\n\t"
"int $3\n\t"
"ret\n\t");
#endif
/*

View file

@ -355,7 +355,7 @@ KeInit2(VOID)
{
PKPCR Pcr = KeGetCurrentKPCR();
KeInitializeBugCheck();
KiInitializeBugCheck();
KeInitializeDispatcher();
KiInitializeSystemClock();

View file

@ -178,11 +178,7 @@ KiAcquireSpinLock(PKSPIN_LOCK SpinLock)
* FIXME: This depends on gcc assembling this test to a single load from
* the spinlock's value.
*/
if (*SpinLock >= 2)
{
DbgPrint("Lock %x has bad value %x\n", SpinLock, *SpinLock);
KEBUGCHECK(0);
}
ASSERT(*SpinLock == 0 || 1);
while ((i = InterlockedExchangeUL(SpinLock, 1)) == 1)
{
@ -199,7 +195,7 @@ KiAcquireSpinLock(PKSPIN_LOCK SpinLock)
#endif
#else
DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i);
KEBUGCHECK(0);
KEBUGCHECKEX(SPIN_LOCK_ALREADY_OWNED, (ULONG)SpinLock, 0, 0, 0);
#endif /* CONFIG_SMP */
}
}
@ -227,7 +223,7 @@ KiReleaseSpinLock(PKSPIN_LOCK SpinLock)
if (*SpinLock != 1)
{
DbgPrint("Releasing unacquired spinlock %x\n", SpinLock);
KEBUGCHECK(0);
KEBUGCHECKEX(SPIN_LOCK_NOT_OWNED, (ULONG)SpinLock, 0, 0, 0);
}
(void)InterlockedExchangeUL(SpinLock, 0);
}