- Fixed the freeing of memory from boot load drivers.
[reactos.git] / reactos / ntoskrnl / ke / bug.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19 /* $Id: bug.c,v 1.40 2003/10/12 17:05:45 hbirr Exp $
20 *
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
26 * UPDATE HISTORY:
27 * Created 22/05/98
28 * Phillip Susi: 12/8/99: Minor fix
29 */
30
31 /* INCLUDES *****************************************************************/
32
33 #include <roskrnl.h>
34 #include <ntos/bootvid.h>
35 #include <internal/kd.h>
36 #include <internal/ke.h>
37 #include <internal/ps.h>
38
39 #include <internal/debug.h>
40
41 #include "../../hal/halx86/include/hal.h"
42
43 /* GLOBALS ******************************************************************/
44
45 static LIST_ENTRY BugcheckCallbackListHead = {NULL,NULL};
46 static ULONG InBugCheck;
47
48 VOID PsDumpThreads(VOID);
49
50 /* FUNCTIONS *****************************************************************/
51
52 VOID INIT_FUNCTION
53 KeInitializeBugCheck(VOID)
54 {
55 InitializeListHead(&BugcheckCallbackListHead);
56 InBugCheck = 0;
57 }
58
59 /*
60 * @unimplemented
61 */
62 BOOLEAN STDCALL
63 KeDeregisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord)
64 {
65 UNIMPLEMENTED;
66 return FALSE;
67 }
68
69 /*
70 * @implemented
71 */
72 BOOLEAN STDCALL
73 KeRegisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord,
74 PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine,
75 PVOID Buffer,
76 ULONG Length,
77 PUCHAR Component)
78 {
79 InsertTailList(&BugcheckCallbackListHead, &CallbackRecord->Entry);
80 CallbackRecord->Length = Length;
81 CallbackRecord->Buffer = Buffer;
82 CallbackRecord->Component = Component;
83 CallbackRecord->CallbackRoutine = CallbackRoutine;
84 return(TRUE);
85 }
86
87 VOID STDCALL
88 KeBugCheckWithTf(ULONG BugCheckCode,
89 ULONG BugCheckParameter1,
90 ULONG BugCheckParameter2,
91 ULONG BugCheckParameter3,
92 ULONG BugCheckParameter4,
93 PKTRAP_FRAME Tf)
94 {
95 PRTL_MESSAGE_RESOURCE_ENTRY Message;
96 NTSTATUS Status;
97 KIRQL OldIrql;
98
99 /* Make sure we're switching back to the blue screen and print messages on it */
100 HalReleaseDisplayOwnership();
101 if (0 == (KdDebugState & KD_DEBUG_GDB))
102 {
103 KdDebugState |= KD_DEBUG_SCREEN;
104 }
105
106 __asm__("cli\n\t");
107 if (KeGetCurrentIrql() < DISPATCH_LEVEL)
108 {
109 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
110 }
111 DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
112 BugCheckCode,
113 BugCheckParameter1,
114 BugCheckParameter2,
115 BugCheckParameter3,
116 BugCheckParameter4);
117
118 Status = RtlFindMessage((PVOID)KERNEL_BASE, //0xC0000000,
119 11, //RT_MESSAGETABLE,
120 0x09, //0x409,
121 BugCheckCode,
122 &Message);
123 if (NT_SUCCESS(Status))
124 {
125 if (Message->Flags == 0)
126 DbgPrint(" %s\n", Message->Text);
127 else
128 DbgPrint(" %S\n", (PWSTR)Message->Text);
129 }
130 else
131 {
132 DbgPrint(" No message text found!\n\n");
133 }
134
135 if (InBugCheck == 1)
136 {
137 DbgPrint("Recursive bug check halting now\n");
138 for (;;)
139 {
140 __asm__ ("hlt\n\t");
141 }
142 }
143 InBugCheck = 1;
144 KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2);
145 MmDumpToPagingFile(BugCheckCode, BugCheckParameter1,
146 BugCheckParameter2, BugCheckParameter3,
147 BugCheckParameter4, Tf);
148
149 if (KdDebuggerEnabled)
150 {
151 __asm__("sti\n\t");
152 DbgBreakPoint();
153 __asm__("cli\n\t");
154 }
155
156 for (;;)
157 {
158 __asm__("hlt\n\t");
159 }
160 }
161
162 /*
163 * @implemented
164 */
165 VOID STDCALL
166 KeBugCheckEx(ULONG BugCheckCode,
167 ULONG BugCheckParameter1,
168 ULONG BugCheckParameter2,
169 ULONG BugCheckParameter3,
170 ULONG BugCheckParameter4)
171 /*
172 * FUNCTION: Brings the system down in a controlled manner when an
173 * inconsistency that might otherwise cause corruption has been detected
174 * ARGUMENTS:
175 * BugCheckCode = Specifies the reason for the bug check
176 * BugCheckParameter[1-4] = Additional information about bug
177 * RETURNS: Doesn't
178 */
179 {
180 PRTL_MESSAGE_RESOURCE_ENTRY Message;
181 NTSTATUS Status;
182 KIRQL OldIrql;
183
184 /* Make sure we're switching back to the blue screen and print messages on it */
185 HalReleaseDisplayOwnership();
186 if (0 == (KdDebugState & KD_DEBUG_GDB))
187 {
188 KdDebugState |= KD_DEBUG_SCREEN;
189 }
190
191 __asm__("cli\n\t");
192 if (KeGetCurrentIrql() < DISPATCH_LEVEL)
193 {
194 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
195 }
196 DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
197 BugCheckCode,
198 BugCheckParameter1,
199 BugCheckParameter2,
200 BugCheckParameter3,
201 BugCheckParameter4);
202
203 Status = RtlFindMessage((PVOID)KERNEL_BASE, //0xC0000000,
204 11, //RT_MESSAGETABLE,
205 0x09, //0x409,
206 BugCheckCode,
207 &Message);
208 if (NT_SUCCESS(Status))
209 {
210 if (Message->Flags == 0)
211 DbgPrint(" %s\n", Message->Text);
212 else
213 DbgPrint(" %S\n", (PWSTR)Message->Text);
214 }
215 else
216 {
217 DbgPrint(" No message text found!\n\n");
218 }
219
220 if (InBugCheck == 1)
221 {
222 DbgPrint("Recursive bug check halting now\n");
223 for (;;)
224 {
225 __asm__("hlt\n\t");
226 }
227 }
228 InBugCheck = 1;
229 if (PsGetCurrentProcess() != NULL)
230 {
231 DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
232 DbgPrint("%.8s> ", PsGetCurrentProcess()->ImageFileName);
233 }
234 if (PsGetCurrentThread() != NULL)
235 {
236 DbgPrint("Thrd: %x Tid: %x\n",
237 PsGetCurrentThread(),
238 PsGetCurrentThread()->Cid.UniqueThread);
239 }
240 KeDumpStackFrames((PULONG)__builtin_frame_address(0));
241 MmDumpToPagingFile(BugCheckCode, BugCheckParameter1,
242 BugCheckParameter2, BugCheckParameter3,
243 BugCheckParameter4, NULL);
244
245 if (KdDebuggerEnabled)
246 {
247 __asm__("sti\n\t");
248 DbgBreakPoint();
249 __asm__("cli\n\t");
250 }
251
252 for (;;)
253 {
254 __asm__("hlt\n\t");
255 }
256 }
257
258 /*
259 * @implemented
260 */
261 VOID STDCALL
262 KeBugCheck(ULONG BugCheckCode)
263 /*
264 * FUNCTION: Brings the system down in a controlled manner when an
265 * inconsistency that might otherwise cause corruption has been detected
266 * ARGUMENTS:
267 * BugCheckCode = Specifies the reason for the bug check
268 * RETURNS: Doesn't
269 */
270 {
271 KeBugCheckEx(BugCheckCode, 0, 0, 0, 0);
272 }
273
274 /* EOF */