mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
Improve debugging functions
- More sensible stack tracer, in C++ (no symbols yet) - Was forgetting to add null frame to new kernel stacks - __kernel_assert was using an old vector - A GP fault will only print its associated table entry
This commit is contained in:
@@ -8,13 +8,14 @@ __kernel_assert(const char *file, unsigned line, const char *message)
|
||||
if (cons) {
|
||||
cons->set_color(9 , 0);
|
||||
cons->puts("\n\n ERROR: ");
|
||||
cons->puts(message);
|
||||
cons->puts("\n ");
|
||||
cons->puts(file);
|
||||
cons->puts(":");
|
||||
cons->put_dec(line);
|
||||
cons->puts(": ");
|
||||
cons->puts(message);
|
||||
cons->puts("\n");
|
||||
}
|
||||
|
||||
__asm__ ( "int $0e7h" );
|
||||
__asm__ ( "int $0e4h" );
|
||||
while (1) __asm__ ("hlt");
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
#include "gdt.h"
|
||||
#include "page_manager.h"
|
||||
|
||||
#define print_reg(name, value) cons->printf(" %s: %016lx\n", name, (value));
|
||||
#define print_regL(name, value) cons->printf(" %s: %016lx", name, (value));
|
||||
#define print_regM(name, value) cons->printf(" %s: %016lx", name, (value));
|
||||
#define print_regR(name, value) cons->printf(" %s: %016lx\n", name, (value));
|
||||
|
||||
size_t __counter_syscall_enter = 0;
|
||||
size_t __counter_syscall_sysret = 0;
|
||||
@@ -14,48 +16,52 @@ print_regs(const cpu_state ®s)
|
||||
{
|
||||
console *cons = console::get();
|
||||
|
||||
print_reg("rax", regs.rax);
|
||||
print_reg("rbx", regs.rbx);
|
||||
print_reg("rcx", regs.rcx);
|
||||
print_reg("rdx", regs.rdx);
|
||||
print_reg("rdi", regs.rdi);
|
||||
print_reg("rsi", regs.rsi);
|
||||
print_regL("rax", regs.rax);
|
||||
print_regM("rbx", regs.rbx);
|
||||
print_regR("rcx", regs.rcx);
|
||||
print_regL("rdx", regs.rdx);
|
||||
print_regM("rdi", regs.rdi);
|
||||
print_regR("rsi", regs.rsi);
|
||||
|
||||
cons->puts("\n");
|
||||
print_reg(" r8", regs.r8);
|
||||
print_reg(" r9", regs.r9);
|
||||
print_reg("r10", regs.r10);
|
||||
print_reg("r11", regs.r11);
|
||||
print_reg("r12", regs.r12);
|
||||
print_reg("r13", regs.r13);
|
||||
print_reg("r14", regs.r14);
|
||||
print_reg("r15", regs.r15);
|
||||
print_regL(" r8", regs.r8);
|
||||
print_regM(" r9", regs.r9);
|
||||
print_regR("r10", regs.r10);
|
||||
print_regL("r11", regs.r11);
|
||||
print_regM("r12", regs.r12);
|
||||
print_regR("r13", regs.r13);
|
||||
print_regL("r14", regs.r14);
|
||||
print_regM("r15", regs.r15);
|
||||
|
||||
cons->puts("\n");
|
||||
print_reg("rbp", regs.rbp);
|
||||
print_reg("rsp", regs.user_rsp);
|
||||
print_reg("sp0", tss_get_stack(0));
|
||||
cons->puts("\n\n");
|
||||
print_regL("rbp", regs.rbp);
|
||||
print_regM("rsp", regs.user_rsp);
|
||||
print_regR("sp0", tss_get_stack(0));
|
||||
|
||||
cons->puts("\n");
|
||||
print_reg(" cs", regs.cs);
|
||||
print_reg(" ss", regs.ss);
|
||||
|
||||
cons->puts("\n");
|
||||
print_reg("rip", regs.rip);
|
||||
|
||||
cons->puts("\n");
|
||||
print_reg("cr3", page_manager::get()->get_pml4());
|
||||
print_regL("rip", regs.rip);
|
||||
print_regM("cr3", page_manager::get()->get_pml4());
|
||||
cons->puts("\n\n");
|
||||
}
|
||||
|
||||
struct frame
|
||||
{
|
||||
frame *prev;
|
||||
uintptr_t return_addr;
|
||||
};
|
||||
|
||||
void
|
||||
print_stacktrace(int skip)
|
||||
{
|
||||
console *cons = console::get();
|
||||
int frame = 0;
|
||||
uint64_t bp = get_frame(skip);
|
||||
while (bp) {
|
||||
cons->printf(" frame %2d: %lx\n", frame, bp);
|
||||
bp = get_frame(++frame + skip);
|
||||
|
||||
frame *fp = nullptr;
|
||||
int fi = -skip;
|
||||
__asm__ __volatile__ ( "mov %%rbp, %0" : "=r" (fp) );
|
||||
|
||||
while (fp) {
|
||||
if (fi++ >= 0)
|
||||
cons->printf(" frame %2d: %lx\n", fi-1, fp->return_addr);
|
||||
fp = fp->prev;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ extern "C" {
|
||||
uintptr_t get_rip();
|
||||
uintptr_t get_frame(int frame);
|
||||
uintptr_t get_gsbase();
|
||||
|
||||
}
|
||||
|
||||
extern size_t __counter_syscall_enter;
|
||||
@@ -17,7 +16,7 @@ extern size_t __counter_syscall_sysret;
|
||||
|
||||
void print_regs(const cpu_state ®s);
|
||||
void print_stack(const cpu_state ®s);
|
||||
void print_stacktrace(int skip = 0);
|
||||
void print_stacktrace(int skip);
|
||||
|
||||
#define print_reg(name, value) cons->printf(" %s: %016lx\n", name, (value));
|
||||
|
||||
|
||||
@@ -18,19 +18,3 @@ _halt:
|
||||
hlt
|
||||
jmp _halt
|
||||
|
||||
|
||||
global get_frame
|
||||
get_frame:
|
||||
mov rcx, rbp
|
||||
|
||||
.loop:
|
||||
mov rax, [rcx + 8]
|
||||
mov rcx, [rcx]
|
||||
cmp rdi, 0
|
||||
je .done
|
||||
|
||||
sub rdi, 1
|
||||
jmp .loop
|
||||
|
||||
.done:
|
||||
ret
|
||||
|
||||
@@ -184,18 +184,25 @@ gdt_init()
|
||||
}
|
||||
|
||||
void
|
||||
gdt_dump()
|
||||
gdt_dump(int index)
|
||||
{
|
||||
const table_ptr &table = g_gdtr;
|
||||
|
||||
console *cons = console::get();
|
||||
cons->printf(" GDT: loc:%lx size:%d\n", table.base, table.limit+1);
|
||||
|
||||
int start = 0;
|
||||
int count = (table.limit + 1) / sizeof(gdt_descriptor);
|
||||
if (index != -1) {
|
||||
start = index;
|
||||
count = 1;
|
||||
} else {
|
||||
cons->printf(" GDT: loc:%lx size:%d\n", table.base, table.limit+1);
|
||||
}
|
||||
|
||||
const gdt_descriptor *gdt =
|
||||
reinterpret_cast<const gdt_descriptor *>(table.base);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
for (int i = start; i < start+count; ++i) {
|
||||
uint32_t base =
|
||||
(gdt[i].base_high << 24) |
|
||||
(gdt[i].base_mid << 16) |
|
||||
@@ -233,17 +240,25 @@ gdt_dump()
|
||||
}
|
||||
|
||||
void
|
||||
idt_dump()
|
||||
idt_dump(int index)
|
||||
{
|
||||
const table_ptr &table = g_idtr;
|
||||
|
||||
log::info(logs::boot, "Loaded IDT at: %lx size: %d bytes", table.base, table.limit+1);
|
||||
|
||||
int start = 0;
|
||||
int count = (table.limit + 1) / sizeof(idt_descriptor);
|
||||
if (index != -1) {
|
||||
start = index;
|
||||
count = 1;
|
||||
log::info(logs::boot, "IDT FOR INDEX %02x", index);
|
||||
} else {
|
||||
log::info(logs::boot, "Loaded IDT at: %lx size: %d bytes", table.base, table.limit+1);
|
||||
}
|
||||
|
||||
const idt_descriptor *idt =
|
||||
reinterpret_cast<const idt_descriptor *>(table.base);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
for (int i = start; i < start+count; ++i) {
|
||||
uint64_t base =
|
||||
(static_cast<uint64_t>(idt[i].base_high) << 32) |
|
||||
(static_cast<uint64_t>(idt[i].base_mid) << 16) |
|
||||
|
||||
@@ -25,7 +25,9 @@ void tss_set_stack(int ring, uintptr_t rsp);
|
||||
uintptr_t tss_get_stack(int ring);
|
||||
|
||||
/// Dump information about the current GDT to the screen
|
||||
void gdt_dump();
|
||||
/// \arg index Which entry to print, or -1 for all entries
|
||||
void gdt_dump(int index = -1);
|
||||
|
||||
/// Dump information about the current IDT to the screen
|
||||
void idt_dump();
|
||||
/// \arg index Which entry to print, or -1 for all entries
|
||||
void idt_dump(int index = -1);
|
||||
|
||||
@@ -124,13 +124,13 @@ isr_handler(uintptr_t return_rsp, cpu_state *regs)
|
||||
switch ((regs->errorcode & 0x07) >> 1) {
|
||||
case 0:
|
||||
cons->printf(" GDT[%x]\n", index);
|
||||
gdt_dump();
|
||||
gdt_dump(index);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case 3:
|
||||
cons->printf(" IDT[%x]\n", index);
|
||||
idt_dump();
|
||||
idt_dump(index);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -143,8 +143,9 @@ scheduler::load_process(const char *name, const void *data, size_t size)
|
||||
// Create a one-page kernel stack space
|
||||
void *stack0 = proc->setup_kernel_stack(stack_size, 0);
|
||||
|
||||
// Stack grows down, point to the end
|
||||
void *sp0 = kutil::offset_pointer(stack0, stack_size);
|
||||
// Stack grows down, point to the end, resere space for initial null frame
|
||||
static const size_t null_frame = sizeof(uint64_t);
|
||||
void *sp0 = kutil::offset_pointer(stack0, stack_size - null_frame);
|
||||
|
||||
cpu_state *state = reinterpret_cast<cpu_state *>(sp0) - 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user