Panic: show panic message on screen

This commit is contained in:
apio 2022-10-16 18:23:33 +02:00
parent 6d821d2638
commit a1146a5ce2
8 changed files with 65 additions and 99 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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"

View File

@ -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();
}