5d8cfdee63f4633ed0c311a12b5ecc9f2ddb28f3
[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.36 2003/08/22 14:49:54 gvg 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
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
98 /*
99 * The bug check may have happened while the bootscreen image was displayed.
100 * If this happened, switch back to text mode.
101 */
102 if (InbvIsBootDriverInstalled())
103 {
104 InbvEnableBootDriver(FALSE);
105 }
106
107 /* Make sure we're switching back to the blue screen and print messages on it */
108 HalReleaseDisplayOwnership();
109 if (0 == (KdDebugState & KD_DEBUG_GDB))
110 {
111 KdDebugState |= KD_DEBUG_SCREEN;
112 }
113
114 __asm__("cli\n\t");
115 DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
116 BugCheckCode,
117 BugCheckParameter1,
118 BugCheckParameter2,
119 BugCheckParameter3,
120 BugCheckParameter4);
121
122 Status = RtlFindMessage((PVOID)KERNEL_BASE, //0xC0000000,
123 11, //RT_MESSAGETABLE,
124 0x09, //0x409,
125 BugCheckCode,
126 &Message);
127 if (NT_SUCCESS(Status))
128 {
129 if (Message->Flags == 0)
130 DbgPrint(" %s\n", Message->Text);
131 else
132 DbgPrint(" %S\n", (PWSTR)Message->Text);
133 }
134 else
135 {
136 DbgPrint(" No message text found!\n\n");
137 }
138
139 if (InBugCheck == 1)
140 {
141 DbgPrint("Recursive bug check halting now\n");
142 for (;;)
143 {
144 __asm__ ("hlt\n\t");
145 }
146 }
147 InBugCheck = 1;
148 KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2);
149 MmDumpToPagingFile(BugCheckCode, BugCheckParameter1,
150 BugCheckParameter2, BugCheckParameter3,
151 BugCheckParameter4, Tf);
152
153 if (KdDebuggerEnabled)
154 {
155 __asm__("sti\n\t");
156 DbgBreakPoint();
157 __asm__("cli\n\t");
158 }
159
160 for (;;)
161 {
162 __asm__("hlt\n\t");
163 }
164 }
165
166 /*
167 * @implemented
168 */
169 VOID STDCALL
170 KeBugCheckEx(ULONG BugCheckCode,
171 ULONG BugCheckParameter1,
172 ULONG BugCheckParameter2,
173 ULONG BugCheckParameter3,
174 ULONG BugCheckParameter4)
175 /*
176 * FUNCTION: Brings the system down in a controlled manner when an
177 * inconsistency that might otherwise cause corruption has been detected
178 * ARGUMENTS:
179 * BugCheckCode = Specifies the reason for the bug check
180 * BugCheckParameter[1-4] = Additional information about bug
181 * RETURNS: Doesn't
182 */
183 {
184 PRTL_MESSAGE_RESOURCE_ENTRY Message;
185 NTSTATUS Status;
186
187 /*
188 * The bug check may have happened while the bootscreen image was displayed.
189 * If this happened, switch back to text mode.
190 */
191 if (InbvIsBootDriverInstalled())
192 {
193 InbvEnableBootDriver(FALSE);
194 }
195
196 /* Make sure we're switching back to the blue screen and print messages on it */
197 HalReleaseDisplayOwnership();
198 KdDebugState |= KD_DEBUG_SCREEN;
199
200 __asm__("cli\n\t");
201 DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
202 BugCheckCode,
203 BugCheckParameter1,
204 BugCheckParameter2,
205 BugCheckParameter3,
206 BugCheckParameter4);
207
208 Status = RtlFindMessage((PVOID)KERNEL_BASE, //0xC0000000,
209 11, //RT_MESSAGETABLE,
210 0x09, //0x409,
211 BugCheckCode,
212 &Message);
213 if (NT_SUCCESS(Status))
214 {
215 if (Message->Flags == 0)
216 DbgPrint(" %s\n", Message->Text);
217 else
218 DbgPrint(" %S\n", (PWSTR)Message->Text);
219 }
220 else
221 {
222 DbgPrint(" No message text found!\n\n");
223 }
224
225 if (InBugCheck == 1)
226 {
227 DbgPrint("Recursive bug check halting now\n");
228 for (;;)
229 {
230 __asm__("hlt\n\t");
231 }
232 }
233 InBugCheck = 1;
234 if (PsGetCurrentProcess() != NULL)
235 {
236 DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
237 DbgPrint("%.8s> ", PsGetCurrentProcess()->ImageFileName);
238 }
239 if (PsGetCurrentThread() != NULL)
240 {
241 DbgPrint("Thrd: %x Tid: %x\n",
242 PsGetCurrentThread(),
243 PsGetCurrentThread()->Cid.UniqueThread);
244 }
245 KeDumpStackFrames((PULONG)__builtin_frame_address(0));
246 MmDumpToPagingFile(BugCheckCode, BugCheckParameter1,
247 BugCheckParameter2, BugCheckParameter3,
248 BugCheckParameter4, NULL);
249
250 if (KdDebuggerEnabled)
251 {
252 __asm__("sti\n\t");
253 DbgBreakPoint();
254 __asm__("cli\n\t");
255 }
256
257 for (;;)
258 {
259 __asm__("hlt\n\t");
260 }
261 }
262
263 /*
264 * @implemented
265 */
266 VOID STDCALL
267 KeBugCheck(ULONG BugCheckCode)
268 /*
269 * FUNCTION: Brings the system down in a controlled manner when an
270 * inconsistency that might otherwise cause corruption has been detected
271 * ARGUMENTS:
272 * BugCheckCode = Specifies the reason for the bug check
273 * RETURNS: Doesn't
274 */
275 {
276 KeBugCheckEx(BugCheckCode, 0, 0, 0, 0);
277 }
278
279 /* EOF */