Panic: show panic message on screen
This commit is contained in:
parent
6d821d2638
commit
a1146a5ce2
@ -1,39 +1,6 @@
|
||||
#pragma once
|
||||
#include "log/Log.h"
|
||||
#include "misc/hang.h"
|
||||
#include "thread/Scheduler.h"
|
||||
#include "trace/StackTracer.h"
|
||||
#include "panic/Panic.h"
|
||||
|
||||
#define __call_assert_fail(...) \
|
||||
kerrorln(__VA_ARGS__); \
|
||||
StackTracer tracer; \
|
||||
tracer.trace(); \
|
||||
hang();
|
||||
#define ASSERT(expr) (bool)(expr) || panic("Assertion failed: " #expr)
|
||||
|
||||
#define ASSERT(expr) \
|
||||
do { \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
Task* cur_task = Scheduler::current_task(); \
|
||||
if (cur_task) \
|
||||
{ \
|
||||
__call_assert_fail("Assertion failed in task %ld at %s, line %d: %s", cur_task->id, __FILE__, \
|
||||
__LINE__, #expr); \
|
||||
} \
|
||||
else { __call_assert_fail("Assertion failed at %s, line %d: %s", __FILE__, __LINE__, #expr); } \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TODO(message) \
|
||||
do { \
|
||||
Task* cur_task = Scheduler::current_task(); \
|
||||
if (cur_task) \
|
||||
{ \
|
||||
__call_assert_fail("TODO in task %ld at %s, line %d: %s", cur_task->id, __FILE__, __LINE__, message); \
|
||||
} \
|
||||
else { __call_assert_fail("TODO at %s, line %d: %s", __FILE__, __LINE__, message); } \
|
||||
} while (0)
|
||||
|
||||
#ifdef ___weird_hack_to_put_something_at_end_of_file
|
||||
#undef ___weird_hack_to_put_something_at_end_of_file
|
||||
#endif
|
||||
#define TODO(message) panic("TODO: " message)
|
@ -22,6 +22,7 @@ namespace KernelLog
|
||||
void logln(const char* function, LogLevel level, const char* message, ...) PRINTF_LIKE(3, 4);
|
||||
void toggle_log_level(LogLevel level);
|
||||
void toggle_log_backend(Backend backend);
|
||||
void enable_log_backend(Backend backend);
|
||||
}
|
||||
|
||||
#ifndef MODULE
|
||||
|
@ -5,13 +5,11 @@
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
[[noreturn]] void __do_int_panic(Context* context, const char* file, int line, const char* message);
|
||||
[[noreturn]] void __do_panic(Context* context, const char* message);
|
||||
|
||||
[[noreturn]] void __panic(const char* message);
|
||||
[[noreturn]] bool __do_int_panic(Context* context, const char* file, int line, const char* message);
|
||||
[[noreturn]] bool __do_panic(const char* file, int line, const char* message);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define panic(message) asm volatile("cli\npush $16\npushq %%rsp\npushfq\npush $8\ncall __panic" : : "D"(message))
|
||||
#define panic(message) __do_panic(__FILE__, __LINE__, message)
|
||||
#define int_panic(context, message) __do_int_panic(context, __FILE__, __LINE__, message)
|
@ -80,4 +80,9 @@ void KernelLog::toggle_log_level(LogLevel level)
|
||||
void KernelLog::toggle_log_backend(Backend backend)
|
||||
{
|
||||
backend_mask ^= (1 << (int)backend);
|
||||
}
|
||||
|
||||
void KernelLog::enable_log_backend(Backend backend)
|
||||
{
|
||||
backend_mask |= (1 << (int)backend);
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
extern __do_panic
|
||||
global __panic
|
||||
|
||||
__panic:
|
||||
push BYTE 0 ; interrupt number
|
||||
push BYTE 0 ; error code
|
||||
push rax
|
||||
push rbx
|
||||
push rcx
|
||||
push rdx
|
||||
push rbp
|
||||
push rdi
|
||||
push rsi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
|
||||
mov r8, cr2
|
||||
push r8
|
||||
|
||||
mov rsi, rdi
|
||||
mov rdi, rsp
|
||||
|
||||
call __do_panic
|
||||
|
||||
cli
|
||||
loop:
|
||||
hlt
|
||||
jmp loop
|
@ -6,33 +6,45 @@
|
||||
#include "io/PIC.h"
|
||||
#include "log/Log.h"
|
||||
#include "misc/MSR.h"
|
||||
#include "render/TextRenderer.h"
|
||||
#include "std/stdio.h"
|
||||
#include "thread/Scheduler.h"
|
||||
#include "trace/StackTracer.h"
|
||||
|
||||
static void dump_registers(Context* context)
|
||||
void dump_registers(Context* context)
|
||||
{
|
||||
printf("-- Registers: \n");
|
||||
printf("rax: %lx, rbx: %lx, rcx: %lx, rdx: %lx\n", context->rax, context->rbx, context->rcx, context->rdx);
|
||||
printf("rsi: %lx, rdi: %lx, rsp: %lx, rbp: %lx\n", context->rsi, context->rdi, context->rsp, context->rbp);
|
||||
printf("r8: %lx, r9: %lx, r10: %lx, r11: %lx\n", context->r8, context->r9, context->r10, context->r11);
|
||||
printf("r12: %lx, r13: %lx, r14: %lx, r15: %lx\n", context->r12, context->r13, context->r14, context->r15);
|
||||
printf("rip: %lx, cs: %lx, ss: %lx\n", context->rip, context->cs, context->ss);
|
||||
printf("rflags: %lx, cr2: %lx\n", context->rflags, context->cr2);
|
||||
printf("ia32_efer: %lx\n", MSR::read_from(IA32_EFER_MSR));
|
||||
kinfoln("-- Registers:");
|
||||
kinfoln("rax: %lx, rbx: %lx, rcx: %lx, rdx: %lx", context->rax, context->rbx, context->rcx, context->rdx);
|
||||
kinfoln("rsi: %lx, rdi: %lx, rsp: %lx, rbp: %lx", context->rsi, context->rdi, context->rsp, context->rbp);
|
||||
kinfoln("r8: %lx, r9: %lx, r10: %lx, r11: %lx", context->r8, context->r9, context->r10, context->r11);
|
||||
kinfoln("r12: %lx, r13: %lx, r14: %lx, r15: %lx", context->r12, context->r13, context->r14, context->r15);
|
||||
kinfoln("rip: %lx, cs: %lx, ss: %lx", context->rip, context->cs, context->ss);
|
||||
kinfoln("rflags: %lx, cr2: %lx", context->rflags, context->cr2);
|
||||
kinfoln("ia32_efer: %lx", MSR::read_from(IA32_EFER_MSR));
|
||||
}
|
||||
|
||||
[[noreturn]] static void __panic_stub(Context* context)
|
||||
[[noreturn]] void __panic_stub(Context* context)
|
||||
{
|
||||
dump_registers(context);
|
||||
if (context) dump_registers(context);
|
||||
|
||||
if (InitRD::is_initialized())
|
||||
{
|
||||
printf("-- Stack trace:\n");
|
||||
StackTracer tracer(context->rbp);
|
||||
tracer.trace_with_ip(context->rip);
|
||||
kinfoln("-- Stack trace:");
|
||||
if (context)
|
||||
{
|
||||
StackTracer tracer(context->rbp);
|
||||
tracer.trace_with_ip(context->rip);
|
||||
}
|
||||
else
|
||||
{
|
||||
uintptr_t rbp;
|
||||
|
||||
asm volatile("mov %%rbp, %0" : "=r"(rbp));
|
||||
StackTracer tracer(rbp);
|
||||
tracer.trace();
|
||||
}
|
||||
}
|
||||
else { printf("-- No stack trace available\n"); }
|
||||
else { kinfoln("-- No stack trace available"); }
|
||||
|
||||
PIC::enable_master(0b11111101); // enable keyboard only
|
||||
PIC::enable_slave(0b11111111);
|
||||
@ -53,10 +65,14 @@ static void dump_registers(Context* context)
|
||||
while (1) asm volatile("hlt");
|
||||
}
|
||||
|
||||
extern "C" [[noreturn]] void __do_int_panic(Context* context, const char* file, int line, const char* message)
|
||||
extern "C" [[noreturn]] bool __do_int_panic(Context* context, const char* file, int line, const char* message)
|
||||
{
|
||||
asm volatile("cli");
|
||||
|
||||
KernelLog::enable_log_backend(Backend::Console);
|
||||
|
||||
TextRenderer::reset();
|
||||
|
||||
if (context->number >= 0x20 && context->number < 0x30) { PIC::send_eoi((uint8_t)(context->irq_number & 0xFF)); }
|
||||
|
||||
Task* task;
|
||||
@ -69,11 +85,20 @@ extern "C" [[noreturn]] void __do_int_panic(Context* context, const char* file,
|
||||
__panic_stub(context);
|
||||
}
|
||||
|
||||
extern "C" [[noreturn]] void __do_panic(Context* context, const char* message)
|
||||
extern "C" [[noreturn]] bool __do_panic(const char* file, int line, const char* message)
|
||||
{
|
||||
Task* task;
|
||||
if ((task = Scheduler::current_task())) { kerrorln("Kernel panic in task %ld: %s", task->id, message); }
|
||||
else { kerrorln("Kernel panic: %s", message); }
|
||||
asm volatile("cli");
|
||||
|
||||
__panic_stub(context);
|
||||
KernelLog::enable_log_backend(Backend::Console);
|
||||
|
||||
TextRenderer::reset();
|
||||
|
||||
Task* task;
|
||||
if ((task = Scheduler::current_task()))
|
||||
{
|
||||
kerrorln("Kernel panic in task %ld, at %s, line %d: %s", task->id, file, line, message);
|
||||
}
|
||||
else { kerrorln("Kernel panic at %s, line %d: %s", file, line, message); }
|
||||
|
||||
__panic_stub(nullptr);
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
#include "errno.h"
|
||||
#include "interrupts/Interrupts.h"
|
||||
#include "kassert.h"
|
||||
#include "log/Log.h"
|
||||
#include "memory/MemoryManager.h"
|
||||
#include "memory/PMM.h"
|
||||
#include "memory/VMM.h"
|
||||
|
@ -1,4 +1,7 @@
|
||||
#define MODULE "trace"
|
||||
|
||||
#include "trace/StackTracer.h"
|
||||
#include "log/Log.h"
|
||||
#include "memory/Memory.h"
|
||||
#include "std/stdio.h"
|
||||
#include "trace/Resolve.h"
|
||||
@ -24,8 +27,8 @@ void StackTracer::trace()
|
||||
while (frame && frame->instruction)
|
||||
{
|
||||
char symbol_name[512];
|
||||
get_symbol_name(frame->instruction, symbol_name, sizeof(symbol_name));
|
||||
printf("%lx: %s\n", frame->instruction, symbol_name);
|
||||
get_symbol_name(frame->instruction - sizeof(uintptr_t), symbol_name, sizeof(symbol_name));
|
||||
kinfoln("%lx: %s", frame->instruction - sizeof(uintptr_t), symbol_name);
|
||||
frame = frame->next;
|
||||
}
|
||||
}
|
||||
@ -34,7 +37,7 @@ void StackTracer::trace_with_ip(uintptr_t ip)
|
||||
{
|
||||
char symbol_name[512];
|
||||
get_symbol_name(ip, symbol_name, sizeof(symbol_name));
|
||||
printf("%lx: %s\n", ip, symbol_name);
|
||||
kinfoln("%lx: %s", ip, symbol_name);
|
||||
trace();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user