3 * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/bug.c
23 * PURPOSE: Graceful system shutdown if a bug is detected
24 * PROGRAMMER: David Welch (welch@cwcom.net)
25 * PORTABILITY: Unchecked
28 * Phillip Susi: 12/8/99: Minor fix
31 /* INCLUDES *****************************************************************/
34 #include <ntos/bootvid.h>
35 #include <internal/debug.h>
36 #include "../../hal/halx86/include/hal.h"
38 /* GLOBALS ******************************************************************/
40 static LIST_ENTRY BugcheckCallbackListHead
= {NULL
,NULL
};
41 static ULONG InBugCheck
;
43 /* FUNCTIONS *****************************************************************/
46 KeInitializeBugCheck(VOID
)
48 InitializeListHead(&BugcheckCallbackListHead
);
56 KeDeregisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord
)
58 /* Check the Current State */
59 if (CallbackRecord
->State
== BufferInserted
) {
60 CallbackRecord
->State
= BufferEmpty
;
61 RemoveEntryList(&CallbackRecord
->Entry
);
65 /* The callback wasn't registered */
73 KeRegisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord
,
74 PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine
,
80 /* Check the Current State first so we don't double-register */
81 if (CallbackRecord
->State
== BufferEmpty
) {
82 CallbackRecord
->Length
= Length
;
83 CallbackRecord
->Buffer
= Buffer
;
84 CallbackRecord
->Component
= Component
;
85 CallbackRecord
->CallbackRoutine
= CallbackRoutine
;
86 CallbackRecord
->State
= BufferInserted
;
87 InsertTailList(&BugcheckCallbackListHead
, &CallbackRecord
->Entry
);
92 /* The Callback was already registered */
97 KeBugCheckWithTf(ULONG BugCheckCode
,
98 ULONG BugCheckParameter1
,
99 ULONG BugCheckParameter2
,
100 ULONG BugCheckParameter3
,
101 ULONG BugCheckParameter4
,
104 PRTL_MESSAGE_RESOURCE_ENTRY Message
;
109 /* Make sure we're switching back to the blue screen and print messages on it */
110 HalReleaseDisplayOwnership();
111 if (0 == (KdDebugState
& KD_DEBUG_GDB
))
113 KdDebugState
|= KD_DEBUG_SCREEN
;
116 Ke386DisableInterrupts();
117 DebugLogDumpMessages();
119 if (MmGetKernelAddressSpace()->Lock
.Owner
== KeGetCurrentThread())
121 MmUnlockAddressSpace(MmGetKernelAddressSpace());
124 if (KeGetCurrentIrql() < DISPATCH_LEVEL
)
126 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
128 DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
135 Status
= RtlFindMessage((PVOID
)KERNEL_BASE
, //0xC0000000,
136 11, //RT_MESSAGETABLE,
140 if (NT_SUCCESS(Status
))
142 if (Message
->Flags
== 0)
143 DbgPrint(" %s\n", Message
->Text
);
145 DbgPrint(" %S\n", (PWSTR
)Message
->Text
);
149 DbgPrint(" No message text found!\n\n");
151 Mask
= 1 << KeGetCurrentProcessorNumber();
152 if (InBugCheck
& Mask
)
155 DbgPrint("Recursive bug check on CPU%d, halting now\n", KeGetCurrentProcessorNumber());
158 * Send an ipi to all other processors which halt them too.
161 DbgPrint("Recursive bug check halting now\n");
163 Ke386HaltProcessor();
167 * Use InterlockedOr or InterlockedBitSet.
172 KiDumpTrapFrame(Tf
, BugCheckParameter1
, BugCheckParameter2
);
176 #if defined(__GNUC__)
177 KeDumpStackFrames((PULONG
)__builtin_frame_address(0));
178 #elif defined(_MSC_VER)
180 __asm call KeDumpStackFrames
183 #error Unknown compiler for inline assembler
186 MmDumpToPagingFile(BugCheckCode
, BugCheckParameter1
,
187 BugCheckParameter2
, BugCheckParameter3
,
188 BugCheckParameter4
, Tf
);
190 if (KdDebuggerEnabled
)
192 Ke386EnableInterrupts();
193 DbgBreakPointNoBugCheck();
194 Ke386DisableInterrupts();
201 * Send an ipi to all other processors which halt them too.
203 Ke386HaltProcessor();
211 KeBugCheckEx(ULONG BugCheckCode
,
212 ULONG BugCheckParameter1
,
213 ULONG BugCheckParameter2
,
214 ULONG BugCheckParameter3
,
215 ULONG BugCheckParameter4
)
217 * FUNCTION: Brings the system down in a controlled manner when an
218 * inconsistency that might otherwise cause corruption has been detected
220 * BugCheckCode = Specifies the reason for the bug check
221 * BugCheckParameter[1-4] = Additional information about bug
225 KeBugCheckWithTf(BugCheckCode
, BugCheckParameter1
, BugCheckParameter2
,
226 BugCheckParameter3
, BugCheckParameter4
, NULL
);
233 KeBugCheck(ULONG BugCheckCode
)
235 * FUNCTION: Brings the system down in a controlled manner when an
236 * inconsistency that might otherwise cause corruption has been detected
238 * BugCheckCode = Specifies the reason for the bug check
242 KeBugCheckEx(BugCheckCode
, 0, 0, 0, 0);