Add support for stack traces
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
416e96c4d5
commit
0d437cfcca
@ -20,4 +20,7 @@ namespace CPU
|
|||||||
void enable_interrupts();
|
void enable_interrupts();
|
||||||
void disable_interrupts();
|
void disable_interrupts();
|
||||||
void wait_for_interrupt();
|
void wait_for_interrupt();
|
||||||
|
|
||||||
|
void get_stack_trace(void (*callback)(u64, void*), void* arg);
|
||||||
|
void get_stack_trace_at(Registers* regs, void (*callback)(u64, void*), void* arg);
|
||||||
}
|
}
|
@ -3,6 +3,7 @@
|
|||||||
#include "arch/Timer.h"
|
#include "arch/Timer.h"
|
||||||
#include "arch/x86_64/CPU.h"
|
#include "arch/x86_64/CPU.h"
|
||||||
#include "arch/x86_64/IO.h"
|
#include "arch/x86_64/IO.h"
|
||||||
|
#include "memory/MemoryManager.h"
|
||||||
#include "thread/Scheduler.h"
|
#include "thread/Scheduler.h"
|
||||||
#include <cpuid.h>
|
#include <cpuid.h>
|
||||||
#include <luna/Check.h>
|
#include <luna/Check.h>
|
||||||
@ -301,6 +302,17 @@ static void setup_idt()
|
|||||||
u64 cr2;
|
u64 cr2;
|
||||||
asm volatile("mov %%cr2, %0" : "=r"(cr2));
|
asm volatile("mov %%cr2, %0" : "=r"(cr2));
|
||||||
kerrorln("Page fault at RIP %lx while accessing %lx!", regs->rip, cr2);
|
kerrorln("Page fault at RIP %lx while accessing %lx!", regs->rip, cr2);
|
||||||
|
|
||||||
|
int frame_index = 0;
|
||||||
|
CPU::get_stack_trace_at(
|
||||||
|
regs,
|
||||||
|
[](u64 instruction, void* arg) {
|
||||||
|
int* ptr = (int*)arg;
|
||||||
|
kinfoln("#%d at %p", *ptr, (void*)instruction);
|
||||||
|
(*ptr)++;
|
||||||
|
},
|
||||||
|
&frame_index);
|
||||||
|
|
||||||
CPU::efficient_halt();
|
CPU::efficient_halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,6 +456,37 @@ namespace CPU
|
|||||||
{
|
{
|
||||||
task_state_segment.rsp[0] = top;
|
task_state_segment.rsp[0] = top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StackFrame
|
||||||
|
{
|
||||||
|
StackFrame* next;
|
||||||
|
u64 instruction;
|
||||||
|
};
|
||||||
|
|
||||||
|
void get_stack_trace(void (*callback)(u64, void*), void* arg)
|
||||||
|
{
|
||||||
|
u64 rbp;
|
||||||
|
asm volatile("mov %%rbp, %0" : "=r"(rbp));
|
||||||
|
StackFrame* current_frame = (StackFrame*)rbp;
|
||||||
|
// FIXME: Validate that the frame itself is readable, might span across multiple pages
|
||||||
|
while (current_frame && MemoryManager::validate_readable_page((u64)current_frame))
|
||||||
|
{
|
||||||
|
callback(current_frame->instruction, arg);
|
||||||
|
current_frame = current_frame->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_stack_trace_at(Registers* regs, void (*callback)(u64, void*), void* arg)
|
||||||
|
{
|
||||||
|
callback(regs->rip, arg);
|
||||||
|
StackFrame* current_frame = (StackFrame*)regs->rbp;
|
||||||
|
// FIXME: Validate that the frame itself is readable, might span across multiple pages
|
||||||
|
while (current_frame && MemoryManager::validate_readable_page((u64)current_frame))
|
||||||
|
{
|
||||||
|
callback(current_frame->instruction, arg);
|
||||||
|
current_frame = current_frame->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// called by kernel_yield
|
// called by kernel_yield
|
||||||
|
Loading…
Reference in New Issue
Block a user