- Made KeBugCheckEx into a call to KeBugCheckExWithTf.
[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.44 2004/03/11 21:50:24 dwelch 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 Ke386DisableInterrupts();
107 DebugLogDumpMessages();
108
109 if (KeGetCurrentIrql() < DISPATCH_LEVEL)
110 {
111 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
112 }
113 DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
114 BugCheckCode,
115 BugCheckParameter1,
116 BugCheckParameter2,
117 BugCheckParameter3,
118 BugCheckParameter4);
119
120 Status = RtlFindMessage((PVOID)KERNEL_BASE, //0xC0000000,
121 11, //RT_MESSAGETABLE,
122 0x09, //0x409,
123 BugCheckCode,
124 &Message);
125 if (NT_SUCCESS(Status))
126 {
127 if (Message->Flags == 0)
128 DbgPrint(" %s\n", Message->Text);
129 else
130 DbgPrint(" %S\n", (PWSTR)Message->Text);
131 }
132 else
133 {
134 DbgPrint(" No message text found!\n\n");
135 }
136
137 if (InBugCheck == 1)
138 {
139 DbgPrint("Recursive bug check halting now\n");
140 Ke386HaltProcessor();
141 }
142 InBugCheck = 1;
143 if (Tf != NULL)
144 {
145 KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2);
146 }
147 else
148 {
149 #if defined(__GNUC__)
150 KeDumpStackFrames((PULONG)__builtin_frame_address(0));
151 #elif defined(_MSC_VER)
152 __asm push ebp
153 __asm call KeDumpStackFrames
154 __asm add esp, 4
155 #else
156 #error Unknown compiler for inline assembler
157 #endif
158 }
159 MmDumpToPagingFile(BugCheckCode, BugCheckParameter1,
160 BugCheckParameter2, BugCheckParameter3,
161 BugCheckParameter4, Tf);
162
163 if (KdDebuggerEnabled)
164 {
165 Ke386EnableInterrupts();
166 DbgBreakPointNoBugCheck();
167 Ke386DisableInterrupts();
168 }
169
170 for (;;)
171 {
172 Ke386HaltProcessor();
173 }
174 }
175
176 /*
177 * @implemented
178 */
179 VOID STDCALL
180 KeBugCheckEx(ULONG BugCheckCode,
181 ULONG BugCheckParameter1,
182 ULONG BugCheckParameter2,
183 ULONG BugCheckParameter3,
184 ULONG BugCheckParameter4)
185 /*
186 * FUNCTION: Brings the system down in a controlled manner when an
187 * inconsistency that might otherwise cause corruption has been detected
188 * ARGUMENTS:
189 * BugCheckCode = Specifies the reason for the bug check
190 * BugCheckParameter[1-4] = Additional information about bug
191 * RETURNS: Doesn't
192 */
193 {
194 KeBugCheckWithTf(BugCheckCode, BugCheckParameter1, BugCheckParameter2,
195 BugCheckParameter3, BugCheckParameter4, NULL);
196 }
197
198 /*
199 * @implemented
200 */
201 VOID STDCALL
202 KeBugCheck(ULONG BugCheckCode)
203 /*
204 * FUNCTION: Brings the system down in a controlled manner when an
205 * inconsistency that might otherwise cause corruption has been detected
206 * ARGUMENTS:
207 * BugCheckCode = Specifies the reason for the bug check
208 * RETURNS: Doesn't
209 */
210 {
211 KeBugCheckEx(BugCheckCode, 0, 0, 0, 0);
212 }
213
214 /* EOF */