mirror of
https://git.stationery.faith/corn/corn.git
synced 2024-11-22 06:32:18 +00:00
added backtraces
This commit is contained in:
parent
417d5b17b8
commit
6b8f33c22d
8 changed files with 130 additions and 9 deletions
20
include/backtrace.h
Normal file
20
include/backtrace.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// Fill dst with a stack trace consisting of return addresses
|
||||||
|
// in order from top to bottom. returns the number filled (at most len)
|
||||||
|
size_t backtrace(void **dst, size_t len);
|
||||||
|
|
||||||
|
|
||||||
|
// same as backtrace but with specified instruction and base pointer
|
||||||
|
size_t backtrace_ex(void **dst, size_t len, void* ip, void *bp);
|
||||||
|
|
||||||
|
// TODO symbols
|
||||||
|
//size_t backtrace_symbols(char *const *dst, size_t len);
|
||||||
|
|
||||||
|
// Log a backtrace
|
||||||
|
void log_backtrace();
|
||||||
|
|
||||||
|
// same as log_backtrace with specified insruction and base pointer
|
||||||
|
void log_backtrace_ex(void *ip, void *bp);
|
|
@ -6,3 +6,5 @@
|
||||||
#define panic(msg) _panic_impl(_PANIC_STR(__LINE__), __FILE__, msg)
|
#define panic(msg) _panic_impl(_PANIC_STR(__LINE__), __FILE__, msg)
|
||||||
|
|
||||||
_Noreturn void _panic_impl(char *line, char *file, char *msg);
|
_Noreturn void _panic_impl(char *line, char *file, char *msg);
|
||||||
|
|
||||||
|
_Noreturn void panic_interrupt(void *ip, void *bp, char *msg);
|
||||||
|
|
53
src/arch/amd64/backtrace.c
Normal file
53
src/arch/amd64/backtrace.c
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#include <backtrace.h>
|
||||||
|
#include <lib.h>
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
struct stackframe {
|
||||||
|
struct stackframe *rbp;
|
||||||
|
void *rip;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t backtrace(void **dst, size_t len) {
|
||||||
|
struct stackframe *rbp;
|
||||||
|
__asm__ volatile ("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__ volatile ("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() {
|
||||||
|
struct stackframe *rbp;
|
||||||
|
__asm__ volatile ("mov %%rbp, %0" : "=r"(rbp));
|
||||||
|
log_backtrace_ex(rbp->rip, rbp->rbp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void log_backtrace_ex(void *ip, void *bp) {
|
||||||
|
struct stackframe *frame = bp;
|
||||||
|
char buf[20];
|
||||||
|
serial_out_str("Stack trace:\n");
|
||||||
|
ultoa((size_t)ip, buf, 16);
|
||||||
|
serial_out_str(" 0x");
|
||||||
|
serial_out_str(buf);
|
||||||
|
serial_out_str("\n");
|
||||||
|
while(frame) {
|
||||||
|
ultoa((size_t)frame->rip, buf, 16);
|
||||||
|
serial_out_str(" 0x");
|
||||||
|
serial_out_str(buf);
|
||||||
|
serial_out_str("\n");
|
||||||
|
frame = frame->rbp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -136,13 +136,16 @@ start:
|
||||||
bits 64
|
bits 64
|
||||||
code64:
|
code64:
|
||||||
|
|
||||||
mov dx, 16
|
mov dx, 16 ; set segment registers
|
||||||
mov ds, dx
|
mov ds, dx ; so that interrupts work
|
||||||
mov ss, dx
|
mov ss, dx
|
||||||
|
|
||||||
|
xor rbp, rbp ; set ebp to 0 so we know where to end stack traces
|
||||||
|
|
||||||
pop rdi
|
pop rdi
|
||||||
call amd64_shim
|
call amd64_shim
|
||||||
mov rdi, rax
|
mov rdi, rax
|
||||||
|
|
||||||
sti
|
sti
|
||||||
call kmain
|
call kmain
|
||||||
cli
|
cli
|
||||||
|
|
|
@ -49,8 +49,10 @@ align 8
|
||||||
isr_stub_%+%1:
|
isr_stub_%+%1:
|
||||||
PUSHALL
|
PUSHALL
|
||||||
cld
|
cld
|
||||||
mov rdi, %1
|
mov rdi, %1 ; exception number
|
||||||
mov rsi, 0
|
mov rsi, 0 ; placeholder error code
|
||||||
|
mov rdx, [rsp + 15 * 8] ; instruction pointer
|
||||||
|
mov rcx, rbp ; base pointer for stack trace
|
||||||
call idt_exception_handler
|
call idt_exception_handler
|
||||||
POPALL
|
POPALL
|
||||||
iretq
|
iretq
|
||||||
|
@ -64,10 +66,13 @@ align 8
|
||||||
isr_stub_%+%1:
|
isr_stub_%+%1:
|
||||||
PUSHALL
|
PUSHALL
|
||||||
cld
|
cld
|
||||||
mov rdi, %1
|
mov rdi, %1 ; exception number
|
||||||
pop rsi
|
mov rsi, [rsp + 15 * 8] ; error code
|
||||||
|
mov rdx, [rsp + 16 * 8] ; instruction pointer
|
||||||
|
mov rcx, rbp ; base pointer for stack trace
|
||||||
call idt_exception_handler
|
call idt_exception_handler
|
||||||
POPALL
|
POPALL
|
||||||
|
sub rsp, 8 ; discard error code
|
||||||
iretq
|
iretq
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
#include <serial.h>
|
#include <serial.h>
|
||||||
|
|
||||||
|
#include "backtrace.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
|
|
||||||
|
@ -107,7 +108,7 @@ char *EXCEPTIONS[] = {
|
||||||
"0x1F Reserved",
|
"0x1F Reserved",
|
||||||
};
|
};
|
||||||
|
|
||||||
void idt_exception_handler(uint64_t exception, uint64_t code) {
|
void idt_exception_handler(uint64_t exception, uint64_t code, void *rip, void *rbp) {
|
||||||
// TODO don't just panic
|
// TODO don't just panic
|
||||||
char buf[24];
|
char buf[24];
|
||||||
char msg[256] = "Exception ";
|
char msg[256] = "Exception ";
|
||||||
|
@ -127,7 +128,7 @@ void idt_exception_handler(uint64_t exception, uint64_t code) {
|
||||||
strcat(msg, buf);
|
strcat(msg, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
panic(msg);
|
panic_interrupt(rip, rbp, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idt_pic_eoi(uint8_t exception) {
|
void idt_pic_eoi(uint8_t exception) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <panic.h>
|
#include <panic.h>
|
||||||
|
#include <backtrace.h>
|
||||||
|
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include "bindings.h"
|
#include "bindings.h"
|
||||||
|
@ -12,7 +13,19 @@ _Noreturn void _panic_impl(char *line, char *file, char *msg) {
|
||||||
serial_out_str(line);
|
serial_out_str(line);
|
||||||
serial_out_str(":\n");
|
serial_out_str(":\n");
|
||||||
serial_out_str(msg);
|
serial_out_str(msg);
|
||||||
serial_out('\n');
|
serial_out_str("\n\n");
|
||||||
|
log_backtrace();
|
||||||
|
while (1) {
|
||||||
|
halt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_Noreturn void panic_interrupt(void *ip, void *bp, char *msg) {
|
||||||
|
cli();
|
||||||
|
serial_out_str("\n\n!!! PANIC !!!\n");
|
||||||
|
serial_out_str(msg);
|
||||||
|
serial_out_str("\n\n");
|
||||||
|
log_backtrace_ex(ip, bp);
|
||||||
while (1) {
|
while (1) {
|
||||||
halt();
|
halt();
|
||||||
}
|
}
|
||||||
|
|
24
src/kmain.c
24
src/kmain.c
|
@ -4,6 +4,30 @@
|
||||||
#include <fb.h>
|
#include <fb.h>
|
||||||
#include <shim.h>
|
#include <shim.h>
|
||||||
|
|
||||||
|
void print_memory() {
|
||||||
|
size_t WIDTH = 64;
|
||||||
|
|
||||||
|
for(size_t i = 0;; i += WIDTH) {
|
||||||
|
char buf[20];
|
||||||
|
ultoa(i, buf, 16);
|
||||||
|
serial_out_str("0x");
|
||||||
|
for(size_t k = 0; k < 6 - strlen(buf); k++) {
|
||||||
|
serial_out('0');
|
||||||
|
}
|
||||||
|
serial_out_str(buf);
|
||||||
|
serial_out_str(": ");
|
||||||
|
for(size_t j = 0; j < WIDTH; j++) {
|
||||||
|
char x = *(char *)(i + j);
|
||||||
|
if(x < 0x20 || x >= 0x7f) {
|
||||||
|
serial_out('.');
|
||||||
|
} else {
|
||||||
|
serial_out(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serial_out('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void kmain(struct boot_info *info) {
|
void kmain(struct boot_info *info) {
|
||||||
memory_init(info->map);
|
memory_init(info->map);
|
||||||
serial_out_str("entered kmain\n");
|
serial_out_str("entered kmain\n");
|
||||||
|
|
Loading…
Reference in a new issue