kernel: try some shit to get the compiler to put a backtrace
This commit is contained in:
parent
ca489e986a
commit
cfc9159ad9
7 changed files with 90 additions and 10 deletions
|
@ -58,7 +58,9 @@ override CFLAGS += \
|
|||
-fno-stack-check \
|
||||
-fno-PIC \
|
||||
-ffunction-sections \
|
||||
-fdata-sections
|
||||
-fdata-sections \
|
||||
-fno-omit-frame-pointer \
|
||||
-fno-optimize-sibling-calls
|
||||
|
||||
# Internal C preprocessor flags that should not be changed by the user.
|
||||
override CPPFLAGS := \
|
||||
|
|
|
@ -10,7 +10,7 @@ void __x86_64_syscall_init() {
|
|||
wrmsr(IA32_EFER, efer);
|
||||
uint64_t star = 0;
|
||||
star |= ((uint64_t)0x28 << 32); // kernel cs
|
||||
star |= ((uint64_t)0x30 << 48); // user cs base (SYSCALL adds 16 for CS=0x38, 24 for SS=0x40)
|
||||
star |= ((uint64_t)0x30 << 48); // user cs base (SYSCALL adds 16 for CS=0x40, 24 for SS=0x38)
|
||||
wrmsr(IA32_STAR, star);
|
||||
wrmsr(IA32_LSTAR, (uint64_t)syscall_entry);
|
||||
wrmsr(IA32_CSTAR, 0x0);
|
||||
|
|
|
@ -57,7 +57,11 @@ struct flanterm_context *ft_ctx;
|
|||
|
||||
char kstack[8192];
|
||||
|
||||
void kmain(void) {
|
||||
void test3() { *((uint8_t*)0x0) = (uint8_t)0xFF; }
|
||||
void test2() { test3();}
|
||||
void test1() { test2(); }
|
||||
|
||||
void __kmain(void) {
|
||||
if (framebuffer_request.response != NULL) {
|
||||
|
||||
struct limine_framebuffer *framebuffer =
|
||||
|
@ -97,6 +101,7 @@ void kmain(void) {
|
|||
|
||||
syscall_init();
|
||||
sched_init();
|
||||
test1();
|
||||
|
||||
// vfs_init();
|
||||
|
||||
|
@ -105,6 +110,7 @@ void kmain(void) {
|
|||
|
||||
program_t *p = elf_load(module_request.response->modules[0]->address, 1);
|
||||
|
||||
|
||||
sched_process *proc =
|
||||
sched_create("Test", p->entry, p->pm, SCHED_USER_PROCESS);
|
||||
|
||||
|
@ -112,6 +118,5 @@ void kmain(void) {
|
|||
|
||||
pit_enable();
|
||||
while (1)
|
||||
;
|
||||
;
|
||||
;;
|
||||
}
|
||||
|
|
10
kernel/src/premain.asm
Normal file
10
kernel/src/premain.asm
Normal file
|
@ -0,0 +1,10 @@
|
|||
bits 64
|
||||
section .text
|
||||
global kmain
|
||||
extern __kmain
|
||||
extern kstack
|
||||
|
||||
kmain:
|
||||
mov rsp, kstack+0x2000 ; supposons 16 KiB de stack
|
||||
xor rbp, rbp ; Set %ebp to NULL
|
||||
call __kmain
|
|
@ -1,3 +1,4 @@
|
|||
#include "sys/errhnd/panic.h"
|
||||
#include "arch/x86_64/idt.h"
|
||||
#include "lib/spinlock.h"
|
||||
#include <mm/memop.h>
|
||||
|
@ -59,7 +60,9 @@ static void __panic_display_page_fault(registers_t *regs) {
|
|||
uint64_t cr2;
|
||||
asm volatile("mov %%cr2, %0" : "=r"(cr2));
|
||||
|
||||
log("Page Fault Details:\n");
|
||||
log("-- PAGE FAULT DETAILS --\n");
|
||||
log("This appears to be a page fault.\n");
|
||||
log("\n");
|
||||
log("Faulting Address (CR2): 0x%lx\n", cr2);
|
||||
log("Error Code: %d\n", regs->err_code);
|
||||
log("Flags:\n");
|
||||
|
@ -83,6 +86,7 @@ static void __panic_display_page_fault(registers_t *regs) {
|
|||
|
||||
if (regs->err_code & (1 << 4))
|
||||
log(" - Instruction Fetch\n");
|
||||
log("\n");
|
||||
}
|
||||
|
||||
static void __panic_display_regs(registers_t *regs) {
|
||||
|
@ -96,11 +100,60 @@ static void __panic_display_regs(registers_t *regs) {
|
|||
regs->rip, regs->cs, regs->ss, regs->rflags, regs->int_no,
|
||||
regs->err_code);
|
||||
log("RSP: %p\n", regs->rsp);
|
||||
log("\n");
|
||||
|
||||
if (regs->int_no == 14) // If it's a page fault
|
||||
__panic_display_page_fault(regs);
|
||||
}
|
||||
|
||||
static void __panic_display_bt(registers_t *regs) {
|
||||
if (regs->cs == 0x43 || regs->cs == 0x3B) {
|
||||
log("The backtrace can't be dumped from a userspace process.\n");
|
||||
return; // Don't try to backtrace userspace
|
||||
}
|
||||
|
||||
log("-- BACKTRACE --\n");
|
||||
|
||||
// First print the current instruction pointer from the interrupt frame
|
||||
if (regs->rip) {
|
||||
log("* %p (current)\n", regs->rip);
|
||||
}
|
||||
|
||||
uint64_t *frame = (uint64_t*)regs->rbp;
|
||||
if (!frame || (uint64_t)frame < 0xffffffff80000000) {
|
||||
log("No further stack frames available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Frame format in x86_64:
|
||||
// [rbp] -> previous rbp
|
||||
// [rbp+8] -> return address
|
||||
int depth = 0;
|
||||
while (frame && depth < 16) { // Limit depth to avoid infinite loops
|
||||
// Validate both frame and return address pointers
|
||||
uint64_t *ret_addr_ptr = frame + 1;
|
||||
if ((uint64_t)ret_addr_ptr < 0xffffffff80000000) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t ret_addr = *ret_addr_ptr;
|
||||
if (ret_addr < 0xffffffff80000000 || ret_addr > 0xfffffffffffff000) {
|
||||
break;
|
||||
}
|
||||
|
||||
log("* %p\n", ret_addr);
|
||||
|
||||
uint64_t next_rbp = *frame;
|
||||
if (next_rbp < 0xffffffff80000000 || next_rbp > 0xfffffffffffff000) {
|
||||
break;
|
||||
}
|
||||
|
||||
frame = (uint64_t*)next_rbp;
|
||||
depth++;
|
||||
}
|
||||
log("\n");
|
||||
}
|
||||
|
||||
void __panic_display_ascii_art() {
|
||||
log(" _ __ _ ___ _ \n");
|
||||
log("| |/ /___ _ _ _ _ ___| | | _ \\__ _ _ _ (_)__ \n");
|
||||
|
@ -145,6 +198,8 @@ void panic_ctx(char *msg, registers_t *regs) {
|
|||
else
|
||||
log("No register context provided.\n");
|
||||
|
||||
__panic_display_bt(regs);
|
||||
|
||||
log("System halted: Please restart your computer manually.\n");
|
||||
|
||||
asm("cli");
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "arch/x86_64/idt.h"
|
||||
|
||||
typedef struct __panic_backtrace {
|
||||
struct Idt_StackFrame* rbp;
|
||||
uint64_t rip;
|
||||
} __attribute__((packed)) panic_backtrace_t;
|
||||
|
||||
void panic(char *msg);
|
||||
void panic_ctx(char *msg, registers_t *regs);
|
Loading…
Add table
Add a link
Reference in a new issue