kernel
Loading...
Searching...
No Matches
bugcheck.c
Go to the documentation of this file.
1/*
2 * PROJECT: MatanelOS Kernel
3 * LICENSE: GPLv3
4 * PURPOSE: Bugcheck functions implementation.
5 */
6
7#include "../../includes/me.h"
8#include "../../includes/mg.h"
11#include "../../includes/mh.h"
12#include "../../includes/ps.h"
13
14#ifndef DEBUG
15#define DEBUG
16#endif
17
18 // We require GOP, so we extern it.
20extern bool isBugChecking;
21extern bool smpInitialized;
22
23extern uint32_t cursor_x;
24extern uint32_t cursor_y;
25
26// switched to uint64_t and not BUGCHECK_CODES since the custom ones arent in that enum, and compiler throws an error.
30static void resolveStopCode(char** s, uint64_t stopcode) {
31 switch (stopcode) {
32 case DIVIDE_BY_ZERO:
33 *s = "DIVIDE_BY_ZERO";
34 break;
35 case SINGLE_STEP:
36 *s = "SINGLE_STEP";
37 break;
39 *s = "NON_MASKABLE_INTERRUPT";
40 break;
41 case BREAKPOINT:
42 *s = "BREAKPOINT";
43 break;
44 case OVERFLOW:
45 *s = "OVERFLOW";
46 break;
47 case BOUNDS_CHECK:
48 *s = "BOUNDS_CHECK";
49 break;
50 case INVALID_OPCODE:
51 *s = "INVALID_OPCODE";
52 break;
53 case NO_COPROCESSOR:
54 *s = "NO_COPROCESSOR";
55 break;
56 case DOUBLE_FAULT:
57 *s = "DOUBLE_FAULT";
58 break;
60 *s = "COPROCESSOR_SEGMENT_OVERRUN";
61 break;
62 case INVALID_TSS:
63 *s = "INVALID_TSS";
64 break;
66 *s = "SEGMENT_SELECTOR_NOTPRESENT";
67 break;
69 *s = "STACK_SEGMENT_OVERRUN";
70 break;
72 *s = "GENERAL_PROTECTION_FAULT";
73 break;
74 case PAGE_FAULT:
75 *s = "PAGE_FAULT";
76 break;
77 case RESERVED:
78 *s = "RESERVED";
79 break;
81 *s = "FLOATING_POINT_ERROR";
82 break;
83 case ALIGNMENT_CHECK:
84 *s = "ALIGNMENT_CHECK";
85 break;
87 *s = "SEVERE_MACHINE_CHECK";
88 break;
90 *s = "MEMORY_MAP_SIZE_OVERRUN";
91 break;
93 *s = "MANUALLY_INITIATED_CRASH";
94 break;
95 case BAD_PAGING:
96 *s = "BAD_PAGING";
97 break;
99 *s = "BLOCK_DEVICE_LIMIT_REACHED";
100 break;
102 *s = "NULL_POINTER_DEREFERENCE";
103 break;
104 case FILESYSTEM_PANIC:
105 *s = "FILESYSTEM_PANIC";
106 break;
108 *s = "UNABLE_TO_INIT_TRACELASTFUNC";
109 break;
111 *s = "FRAME_LIMIT_REACHED";
112 break;
114 *s = "IRQL_NOT_LESS_OR_EQUAL";
115 break;
117 *s = "INVALID_IRQL_SUPPLIED";
118 break;
120 *s = "NULL_CTX_RECEIVED";
121 break;
123 *s = "THREAD_EXIT_FAILURE";
124 break;
125 case BAD_AHCI_COUNT:
126 *s = "BAD_AHCI_COUNT";
127 break;
128 case AHCI_INIT_FAILED:
129 *s = "AHCI_INIT_FAILED";
130 break;
132 *s = "MEMORY_LIMIT_REACHED";
133 break;
135 *s = "HEAP_ALLOCATION_FAILED";
136 break;
137 case NULL_THREAD:
138 *s = "NULL_THREAD";
139 break;
141 *s = "FATAL_IRQL_CORRUPTION";
142 break;
144 *s = "THREAD_ID_CREATION_FAILURE";
145 break;
147 *s = "ASSERTION_FAILURE";
148 break;
150 *s = "FRAME_ALLOCATION_FAILED";
151 break;
153 *s = "FRAME_BITMAP_CREATION_FAILURE";
154 break;
156 *s = "MEMORY_INVALID_FREE";
157 break;
159 *s = "MEMORY_CORRUPT_HEADER";
160 break;
162 *s = "MEMORY_DOUBLE_FREE";
163 break;
165 *s = "MEMORY_CORRUPT_FOOTER";
166 break;
168 *s = "GUARD_PAGE_DEREFERENCE";
169 break;
171 *s = "IRQL_NOT_GREATER_OR_EQUAL";
172 break;
174 *s = "KERNEL_STACK_OVERFLOWN";
175 break;
176 case BAD_POOL_CALLER:
177 *s = "BAD_POOL_CALLER";
178 break;
180 *s = "KMODE_EXCEPTION_NOT_HANDLED";
181 break;
183 *s = "ATTEMPTED_SWITCH_FROM_DPC";
184 break;
186 *s = "ATTEMPTED_WRITE_TO_READONLY_MEMORY";
187 break;
189 *s = "PSMGR_INIT_FAILED";
190 break;
192 *s = "PAGE_FAULT_IN_FREED_NONPAGED_POOL";
193 break;
195 *s = "PAGE_FAULT_IN_FREED_PAGED_POOL";
196 break;
198 *s = "PSWORKER_INIT_FAILED";
199 break;
201 *s = "MANUALLY_INITIATED_CRASH2";
202 break;
204 *s = "DPC_NOT_INITIALIZED";
205 break;
207 *s = "INVALID_PROCESS_ATTACH_ATTEMPT";
208 break;
210 *s = "ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY";
211 break;
212 default:
213 *s = "UNKNOWN_BUGCHECK_CODE";
214 break;
215 }
216}
217
219void
221 IN enum _BUGCHECK_CODES BugCheckCode
222)
223
224/*++
225
226 Routine description : Gracefully crashes the system.
227
228 Arguments:
229
230 [IN] enum _BUGCHECK_CODES BugCheckCode
231
232 Return Values:
233
234 None - This function does not return to caller.
235
236--*/
237
238{
239 MeBugCheckEx(BugCheckCode, NULL, NULL, NULL, NULL);
240}
241
242
244void
246 IN enum _BUGCHECK_CODES BugCheckCode,
247 IN void* BugCheckParameter1,
248 IN void* BugCheckParameter2,
249 IN void* BugCheckParameter3,
250 IN void* BugCheckParameter4
251)
252
253/*++
254
255 Routine description : Gracefully crashes the system, supplies parameters for debugging by the developer.
256
257 Arguments:
258
259 [IN] enum _BUGCHECK_CODES BugCheckCode
260 [IN] void* BugCheckParameter1
261 [IN] void* BugCheckParameter2
262 [IN] void* BugCheckParameter3
263 [IN] void* BugCheckParameter4
264
265 Return Values:
266
267 None - This function does not return to caller.
268
269 TODO:
270
271 Add minidumps if the filesystem is initialized.
272
273--*/
274
275{
276 // Critical system error, instead of triple faulting, we hang the system with specified error codes.
277 // Disable interrupts if they werent disabled before.
278 __cli();
279 if (smpInitialized) {
280 // If all other cores are online, we obviously want to stop them.
281 IPI_PARAMS dummy = { 0 };
283 }
284
285 // atomically check & set isBugChecking
286 bool prev = InterlockedExchangeBool(&isBugChecking, true);
287
288 if (prev == 1) {
289 while (1) __hlt();
290 }
291
292 // Acquire exclusive ownership to this processor for framebuffer access.
294
295#ifdef DEBUG
296 IRQL recordedIrql = MeGetCurrentProcessor()->currentIrql;
297#endif
298 // Force to be redrawn from the top, instead of last place.
299 cursor_x = 0;
300 cursor_y = 0;
301 _MeSetIrql(HIGH_LEVEL); // SET the irql to high level (not raise) (we could raise, but this takes less cycles and so is faster)
302
303 // Clear the screen to blue (bsod windows style)
304 gop_clear_screen(&gop_local, 0xFF0035b8);
305 // Write some debugging and an error message
306 gop_printf(0xFFFFFFFF, "FATAL ERROR: Your system has encountered a fatal error.\n\n");
307 gop_printf(0xFFFFFFFF, "Your system has been stopped for safety.\n\n");
308 char* stopCodeToStr = ""; // empty at first.
309 resolveStopCode(&stopCodeToStr, BugCheckCode);
310 gop_printf(0xFFFFFFFF, "**STOP CODE: ");
311 gop_printf(0xFF8B0000, "%s", stopCodeToStr);
312 gop_printf(0xFF00FF00, " (numerical: %d)**\n", BugCheckCode);
313 {
314#ifdef DEBUG
315 if (BugCheckCode == ASSERTION_FAILURE) {
316 // Print expression, reason, file, line.
318 "Expression: %s\n"
319 "Reason: %s\n"
320 "File: %s\n"
321 "Line: %lld\n", // Changed to %d since assert_fail passes a decimal number and not a char ptr.
322 (char*)BugCheckParameter1,
323 (char*)BugCheckParameter2,
324 (char*)BugCheckParameter3,
325 (long long)(intptr_t)BugCheckParameter4);
326 }
327 else {
328#endif
329 // Print parameters.
331 "Parameter 1: (Pointer: %p | Decimal: %lld | Pure Hex: %llx)\n"
332 "Parameter 2: (Pointer: %p | Decimal: %lld | Pure Hex: %llx)\n"
333 "Parameter 3: (Pointer: %p | Decimal: %lld | Pure Hex: %llx)\n"
334 "Parameter 4: (Pointer: %p | Decimal: %lld | Pure Hex: %llx)\n",
335 (void*)(uintptr_t)BugCheckParameter1, (long long)(intptr_t)BugCheckParameter1, (unsigned long long)(uintptr_t)BugCheckParameter1,
336 (void*)(uintptr_t)BugCheckParameter2, (long long)(intptr_t)BugCheckParameter2, (unsigned long long)(uintptr_t)BugCheckParameter2,
337 (void*)(uintptr_t)BugCheckParameter3, (long long)(intptr_t)BugCheckParameter3, (unsigned long long)(uintptr_t)BugCheckParameter3,
338 (void*)(uintptr_t)BugCheckParameter4, (long long)(intptr_t)BugCheckParameter4, (unsigned long long)(uintptr_t)BugCheckParameter4);
339#ifdef DEBUG
340 }
341#endif
342 }
343#ifdef DEBUG
344 gop_printf(0xFFFFA500, "**Last IRQL: %d**\n", recordedIrql);
345 gop_printf(0xFFFFA500, "DPC Active: %s\n", (MeGetCurrentProcessor()->DpcRoutineActive) ? "Yes" : "No");
346#endif
348 gop_printf(0xFFFFFF00, "Current Thread ID: %d\n", currTid);
349 if (smpInitialized) {
350 gop_printf(COLOR_LIME, "Sent IPI To all CPUs to HALT.\n");
351 gop_printf(COLOR_LIME, "Current Executing CPU: %d\n", MeGetCurrentProcessor()->lapic_ID);
352 }
353#ifdef DEBUG
354 // Thread information
355 PETHREAD CurrentThread = PsGetCurrentThread();
356 if (CurrentThread) {
357 // Display thread debug info
358 uintptr_t StackBase = (uintptr_t)CurrentThread->InternalThread.StackBase; // high address
359 uintptr_t StackSize = (CurrentThread->InternalThread.IsLargeStack) ? MI_LARGE_STACK_SIZE : MI_STACK_SIZE;
360 uintptr_t StackLimit = StackBase - StackSize; // low address (bottom of stack)
361 uintptr_t ThreadTop = (uintptr_t)CurrentThread->InternalThread.TrapRegisters.rsp;
362 gop_printf(COLOR_WHITE, "Thread Stack Range | %p - %p | Last saved top: %p\n", (void*)StackLimit, (void*)StackBase, (void*)ThreadTop);
363 gop_printf(COLOR_YELLOW, "PreviousMode: %s\n", (MeGetPreviousMode() == KernelMode) ? "KernelMode" : "UserMode");
364 }
365 gop_printf(COLOR_YELLOW, "Current CR3: %p\n", (void*)(uintptr_t)__read_cr3());
366 gop_printf(COLOR_YELLOW, "Current stack top: %p\n", (void*)(uintptr_t)__read_rsp());
367#endif
368 __cli();
369 while (1) {
370 __hlt();
371 __pause();
372 }
373}
#define NORETURN
Definition annotations.h:14
#define IN
Definition annotations.h:8
FORCEINLINE bool InterlockedExchangeBool(volatile bool *target, bool value)
Definition atomic.h:171
NORETURN void MeBugCheck(IN enum _BUGCHECK_CODES BugCheckCode)
Definition bugcheck.c:220
bool smpInitialized
Definition kernel.c:149
bool isBugChecking
Definition kernel.c:19
NORETURN void MeBugCheckEx(IN enum _BUGCHECK_CODES BugCheckCode, IN void *BugCheckParameter1, IN void *BugCheckParameter2, IN void *BugCheckParameter3, IN void *BugCheckParameter4)
Definition bugcheck.c:245
uint32_t cursor_y
Definition gop.c:44
GOP_PARAMS gop_local
Definition gop.c:223
uint32_t cursor_x
Definition gop.c:44
@ HIGH_LEVEL
Definition core.h:22
enum _IRQL IRQL
int32_t HANDLE
Definition core.h:58
ETHREAD * PETHREAD
Definition core.h:44
struct _GOP_PARAMS GOP_PARAMS
void MgAcquireExclusiveGopOwnerShip(void)
Definition gop.c:726
void gop_printf(uint32_t color, const char *fmt,...)
Definition gop.c:633
void gop_clear_screen(GOP_PARAMS *gop, uint32_t color)
Definition gop.c:225
FORCEINLINE void __pause(void)
Definition intrin.h:239
FORCEINLINE uint64_t __read_rsp(void)
Definition intrin.h:227
FORCEINLINE void __hlt(void)
Definition intrin.h:65
FORCEINLINE void __cli(void)
Definition intrin.h:43
FORCEINLINE uint64_t __read_cr3(void)
Definition intrin.h:93
void _MeSetIrql(IN IRQL NewIrql)
Definition irql.c:158
_BUGCHECK_CODES
Definition me.h:68
@ MANUALLY_INITIATED_CRASH
Definition me.h:90
@ NULL_POINTER_DEREFERENCE
Definition me.h:93
@ OVERFLOW
Definition me.h:73
@ FILESYSTEM_PANIC
Definition me.h:94
@ BAD_POOL_CALLER
Definition me.h:122
@ MEMORY_LIMIT_REACHED
Definition me.h:104
@ SEVERE_MACHINE_CHECK
Definition me.h:87
@ ATTEMPTED_WRITE_TO_READONLY_MEMORY
Definition me.h:123
@ COPROCESSOR_SEGMENT_OVERRUN
Definition me.h:78
@ FRAME_LIMIT_REACHED
Definition me.h:96
@ HEAP_ALLOCATION_FAILED
Definition me.h:105
@ NO_COPROCESSOR
Definition me.h:76
@ MEMORY_CORRUPT_HEADER
Definition me.h:113
@ PAGE_FAULT
Definition me.h:83
@ PAGE_FAULT_IN_FREED_NONPAGED_POOL
Definition me.h:125
@ PSMGR_INIT_FAILED
Definition me.h:130
@ FLOATING_POINT_ERROR
Definition me.h:85
@ GUARD_PAGE_DEREFERENCE
Definition me.h:116
@ MEMORY_INVALID_FREE
Definition me.h:112
@ IRQL_NOT_GREATER_OR_EQUAL
Definition me.h:98
@ THREAD_EXIT_FAILURE
Definition me.h:101
@ ASSERTION_FAILURE
Definition me.h:111
@ MEMORY_MAP_SIZE_OVERRUN
Custom ones.
Definition me.h:89
@ ATTEMPTED_SWITCH_FROM_DPC
Definition me.h:127
@ SINGLE_STEP
Definition me.h:70
@ KMODE_EXCEPTION_NOT_HANDLED
Definition me.h:118
@ DIVIDE_BY_ZERO
Definition me.h:69
@ NULL_THREAD
Definition me.h:106
@ KERNEL_STACK_OVERFLOWN
Definition me.h:117
@ BREAKPOINT
Definition me.h:72
@ ALIGNMENT_CHECK
Definition me.h:86
@ BAD_PAGING
Definition me.h:91
@ BLOCK_DEVICE_LIMIT_REACHED
Definition me.h:92
@ NON_MASKABLE_INTERRUPT
Definition me.h:71
@ INVALID_OPCODE
Definition me.h:75
@ INVALID_TSS
Definition me.h:79
@ FRAME_BITMAP_CREATION_FAILURE
Definition me.h:110
@ BAD_AHCI_COUNT
Definition me.h:102
@ NULL_CTX_RECEIVED
Definition me.h:100
@ MEMORY_DOUBLE_FREE
Definition me.h:114
@ FRAME_ALLOCATION_FAILED
Definition me.h:109
@ DPC_NOT_INITIALIZED
Definition me.h:132
@ UNABLE_TO_INIT_TRACELASTFUNC
Definition me.h:95
@ THREAD_ID_CREATION_FAILURE
Definition me.h:108
@ PAGE_FAULT_IN_FREED_PAGED_POOL
Definition me.h:126
@ PSWORKER_INIT_FAILED
Definition me.h:131
@ DOUBLE_FAULT
Definition me.h:77
@ MANUALLY_INITIATED_CRASH2
Definition me.h:129
@ STACK_SEGMENT_OVERRUN
Definition me.h:81
@ GENERAL_PROTECTION_FAULT
Definition me.h:82
@ ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY
Definition me.h:137
@ SEGMENT_SELECTOR_NOTPRESENT
Definition me.h:80
@ AHCI_INIT_FAILED
Definition me.h:103
@ INVALID_PROCESS_ATTACH_ATTEMPT
Definition me.h:134
@ IRQL_NOT_LESS_OR_EQUAL
Definition me.h:97
@ BOUNDS_CHECK
Definition me.h:74
@ INVALID_IRQL_SUPPLIED
Definition me.h:99
@ FATAL_IRQL_CORRUPTION
Definition me.h:107
@ RESERVED
Definition me.h:84
@ MEMORY_CORRUPT_FOOTER
Definition me.h:115
FORCEINLINE PPROCESSOR MeGetCurrentProcessor(void)
Definition me.h:369
FORCEINLINE PRIVILEGE_MODE MeGetPreviousMode(void)
Definition me.h:568
#define COLOR_YELLOW
Definition mg.h:35
#define COLOR_WHITE
Definition mg.h:33
#define COLOR_LIME
Definition mg.h:45
@ CPU_ACTION_STOP
Definition mh.h:89
struct _IPI_PARAMS IPI_PARAMS
#define MI_LARGE_STACK_SIZE
Definition mm.h:243
@ KernelMode
Definition mm.h:371
#define MI_STACK_SIZE
Definition mm.h:242
void MhSendActionToCpusAndWait(CPU_ACTION action, IPI_PARAMS parameter)
Definition smp.c:231
struct _ITHREAD InternalThread
Definition ps.h:183
HANDLE TID
Definition ps.h:187
void * StackBase
Definition me.h:269
bool IsLargeStack
Definition me.h:270
struct _TRAP_FRAME TrapRegisters
Definition me.h:267
enum _IRQL currentIrql
Definition me.h:283
struct _ITHREAD * currentThread
Definition me.h:285
uint64_t rsp
Definition me.h:163
PETHREAD PsGetCurrentThread(void)
Definition thread.c:279