aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/core/sys.c
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2015-03-11 17:59:28 +0100
committerAlex Auvolat <alex@adnab.me>2015-03-11 17:59:28 +0100
commit0b76aff59b586d87ee0449bc7deda878f4633515 (patch)
tree8fd773681e302d84bc1f33c2a2bdf791f0b0df95 /src/kernel/core/sys.c
parent64b9108a58d3483e9b63511c4cf74b12dceeb0f6 (diff)
downloadkogata-0b76aff59b586d87ee0449bc7deda878f4633515.tar.gz
kogata-0b76aff59b586d87ee0449bc7deda878f4633515.zip
Add better stack tracing technology (now uses kernel memory map!)
Diffstat (limited to 'src/kernel/core/sys.c')
-rw-r--r--src/kernel/core/sys.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/kernel/core/sys.c b/src/kernel/core/sys.c
index 8be6c7f..554c95e 100644
--- a/src/kernel/core/sys.c
+++ b/src/kernel/core/sys.c
@@ -1,6 +1,9 @@
#include <sys.h>
#include <dbglog.h>
#include <thread.h>
+#include <string.h>
+
+#include <btree.h>
// Kernel panic and kernel assert failure
@@ -9,6 +12,15 @@ static void panic_do(const char* type, const char *msg, const char* file, int li
asm volatile("cli;");
dbg_printf("/\n| %s:\t%s\n", type, msg);
dbg_printf("| File: \t%s:%i\n", file, line);
+
+ dbg_printf("- trace\n");
+ dbg_printf("| current thread: 0x%p\n", current_thread);
+ uint32_t *ebp;
+ asm volatile("mov %%ebp, %0":"=r"(ebp));
+ kernel_stacktrace(ebp[0], ebp[1]);
+
+ dbg_print_region_info();
+
dbg_printf("| System halted -_-'\n");
dbg_printf("\\---------------------------------------------------------/");
BOCHS_BREAKPOINT;
@@ -26,4 +38,50 @@ void panic_assert(const char* assertion, const char* file, int line) {
panic_do("ASSERT FAILED", assertion, file, line);
}
+// ---- kernel symbol map
+
+btree_t *kernel_symbol_map = 0;
+
+void load_kernel_symbol_map(char* text, size_t len) {
+ kernel_symbol_map = create_btree(id_key_cmp_fun, 0);
+ ASSERT (kernel_symbol_map != 0);
+
+ dbg_printf("Loading kernel symbol map...\n");
+
+ char* it = text;
+ while (it < text + len) {
+ char* eol = it;
+ while (eol < text + len && *eol != 0 && *eol != '\n') eol++;
+ if (eol >= text + len) break;
+ *eol = 0;
+
+ if (it[16] == '0' && it[17] == 'x' && it[34] == ' ' && it[49] == ' ') {
+ uint32_t addr = 0;
+ for (unsigned i = 18; i < 34; i++) {
+ addr *= 16;
+ if (it[i] >= '0' && it[i] <= '9') addr += it[i] - '0';
+ if (it[i] >= 'a' && it[i] <= 'f') addr += it[i] - 'a' + 10;
+ }
+ btree_add(kernel_symbol_map, (void*)addr, it + 50);
+ }
+
+ it = eol + 1;
+ }
+}
+
+void kernel_stacktrace(uint32_t ebp, uint32_t eip) {
+ int i = 0;
+ while (ebp >= K_HIGHHALF_ADDR && eip >= K_HIGHHALF_ADDR && i++ < 10) {
+ char* sym = 0;
+ if (kernel_symbol_map != 0) sym = btree_lower(kernel_symbol_map, (void*)eip);
+
+ dbg_printf("| 0x%p EIP: 0x%p %s\n", ebp, eip, sym);
+
+ uint32_t *d = (uint32_t*)ebp;
+ ebp = d[0];
+ eip = d[1];
+ }
+}
+
+
/* vim: set ts=4 sw=4 tw=0 noet :*/