diff --git a/kernel/include/trace/StackTracer.h b/kernel/include/trace/StackTracer.h new file mode 100644 index 00000000..1f857547 --- /dev/null +++ b/kernel/include/trace/StackTracer.h @@ -0,0 +1,12 @@ +#pragma once +#include + +struct StackTracer +{ + StackTracer(); + StackTracer(uintptr_t base_pointer); + void trace(); + + private: + uintptr_t m_base_pointer; +}; \ No newline at end of file diff --git a/kernel/src/interrupts/Entry.cpp b/kernel/src/interrupts/Entry.cpp index 7344bd87..e439287c 100644 --- a/kernel/src/interrupts/Entry.cpp +++ b/kernel/src/interrupts/Entry.cpp @@ -5,6 +5,7 @@ #include "log/Log.h" #include "panic/hang.h" #include "std/stdio.h" +#include "trace/StackTracer.h" extern "C" void common_handler(SavedContext* context) { @@ -15,14 +16,23 @@ extern "C" void common_handler(SavedContext* context) } if (context->number == 13) { - kerrorln("General protection fault at RIP %lx, cs %ld, ss %ld, RSP %lx, error code %ld\n", context->rip, + kerrorln("General protection fault at RIP %lx, cs %ld, ss %ld, RSP %lx, error code %ld", context->rip, context->cs, context->ss, context->rsp, context->error_code); + kinfoln("Stack trace:"); + + StackTracer tracer(context->rbp); + tracer.trace(); while (1) halt(); } if (context->number == 14) { - kerrorln("Page fault in %s (RIP %lx), while trying to access %lx, error code %ld\n", + kerrorln("Page fault in %s (RIP %lx), while trying to access %lx, error code %ld", context->cs == 8 ? "ring 0" : "ring 3", context->rip, context->cr2, context->error_code); + kinfoln("Stack trace:"); + + StackTracer tracer(context->rbp); + tracer.trace(); + hang(); } if (context->number == 8) diff --git a/kernel/src/trace/StackTracer.cpp b/kernel/src/trace/StackTracer.cpp new file mode 100644 index 00000000..48a49b64 --- /dev/null +++ b/kernel/src/trace/StackTracer.cpp @@ -0,0 +1,30 @@ +#include "trace/StackTracer.h" +#include "std/stdio.h" +#include "trace/Resolve.h" + +StackTracer::StackTracer() +{ + asm("mov %%rbp, %0" : "=r"(m_base_pointer)); +} + +StackTracer::StackTracer(uintptr_t base_pointer) : m_base_pointer(base_pointer) +{ +} + +typedef struct stackframe +{ + struct stackframe* next; + uintptr_t instruction; +} stackframe; + +void StackTracer::trace() +{ + stackframe* frame = (stackframe*)m_base_pointer; + while (frame) + { + char symbol_name[512]; + get_symbol_name(frame->instruction, symbol_name); + printf("%lx: %s\n", frame->instruction, symbol_name); + frame = frame->next; + } +} \ No newline at end of file