static void panic_printf(const char *fmt, ...) { va_list va; va_start(va, fmt); vprintf(fmt, va); serial_vprintf(fmt, va); va_end(va); }
// I/O helpers to allow for toggle of serial or vga console void console_printf(console_color_t color, char *fmt, ...) { va_list argp; unsigned sgr; va_start(argp, fmt); if ((sysio[0] & 0x2) == 0x2) vga_vprintf(vga_console_color(color), fmt, argp); else { serial_ansi_sgr(0, color); serial_vprintf(0, fmt, argp); } va_end(argp); }
void __attribute__((optimize("O0"))) panic(char* error, ...) { if(unlikely(!spinlock_get(&lock, 30))) { freeze(); } va_list va; va_start(va, error); interrupts_disable(); panic_printf("\nKernel Panic: "); vprintf(error, va); serial_vprintf(error, va); panic_printf("\n"); va_end(va); panic_printf("Last PIT tick: %d (rate %d, uptime: %d seconds)\n", (uint32_t)timer_tick, timer_rate, uptime()); task_t* task = scheduler_get_current(); if(task) { panic_printf("Running task: %d <%s>", task->pid, task->name); /* uint32_t task_offset = task->state->eip - task->entry; if(task_offset >= 0) { panic_printf("+%x at 0x%x", task_offset, task->state->eip); } */ panic_printf("\n"); } else { panic_printf("Running task: [No task running]\n"); } panic_printf("Paging context: %s\n\n", vmem_get_name(vmem_currentContext)); panic_printf("Call trace:\n"); intptr_t addresses[10]; int read = walk_stack(addresses, 10); for(int i = 0; i < read; i++) { panic_printf("#%-6d %s <%#x>\n", i, addr2name(addresses[i]), addresses[i]); } freeze(); }