summaryrefslogtreecommitdiff
path: root/kernel/lib
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-08 17:55:13 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-08 17:55:13 -0400
commit331a2a442b2c8595002d342372d4d08f104b382d (patch)
tree7f46cf1a774d9135383125211b268b28df34d232 /kernel/lib
parentremove boot dir (diff)
downloadcomus-331a2a442b2c8595002d342372d4d08f104b382d.tar.gz
comus-331a2a442b2c8595002d342372d4d08f104b382d.tar.bz2
comus-331a2a442b2c8595002d342372d4d08f104b382d.zip
backtrace
Diffstat (limited to 'kernel/lib')
-rw-r--r--kernel/lib/backtrace.c46
-rw-r--r--kernel/lib/panic.c2
2 files changed, 48 insertions, 0 deletions
diff --git a/kernel/lib/backtrace.c b/kernel/lib/backtrace.c
new file mode 100644
index 0000000..fb708b2
--- /dev/null
+++ b/kernel/lib/backtrace.c
@@ -0,0 +1,46 @@
+#include <lib.h>
+
+struct stackframe {
+ struct stackframe *rbp;
+ void *rip;
+};
+
+size_t backtrace(void **dst, size_t len)
+{
+ struct stackframe *rbp;
+ __asm__("mov %%rbp, %0" : "=r"(rbp));
+ return backtrace_ex(dst, len, rbp->rip, rbp->rbp);
+}
+
+size_t backtrace_ex(void **dst, size_t len, void *ip, void *bp)
+{
+ struct stackframe *frame = bp;
+ __asm__("mov %%rbp, %0" : "=r"(frame));
+ if (len > 0) {
+ dst[0] = ip;
+ }
+ size_t i;
+ for (i = 1; frame && i < len; i++) {
+ dst[i] = frame->rip;
+ frame = frame->rbp;
+ }
+ return i;
+}
+
+void log_backtrace(void)
+{
+ struct stackframe *rbp;
+ __asm__("mov %%rbp, %0" : "=r"(rbp));
+ log_backtrace_ex(rbp->rip, rbp->rbp);
+}
+
+void log_backtrace_ex(void *ip, void *bp)
+{
+ struct stackframe *frame = bp;
+ kputs("Stack trace:\n");
+ kprintf(" %p\n", ip);
+ while (frame) {
+ kprintf(" %p\n", frame->rip);
+ frame = frame->rbp;
+ }
+}
diff --git a/kernel/lib/panic.c b/kernel/lib/panic.c
index 5381041..d3db908 100644
--- a/kernel/lib/panic.c
+++ b/kernel/lib/panic.c
@@ -1,3 +1,4 @@
+#include "lib/klib.h"
#include <lib.h>
#include <stdarg.h>
#include <comus/asm.h>
@@ -10,6 +11,7 @@ __attribute__((noreturn)) void panic(const char *format, ...)
kprintf("\n\n!!! PANIC !!!\n");
kvprintf(format, list);
kprintf("\n\n");
+ log_backtrace();
while (1)
halt();