Browse Source

stack tracing symbol names

master
Mathieu Serandour 11 months ago
parent
commit
ee60166047
  1. 35
      kernel/lib/panic.c
  2. 115
      kernel/lib/stacktrace.c
  3. 7
      kernel/lib/stacktrace.h

35
kernel/lib/panic.c

@ -4,40 +4,9 @@
#include "../drivers/ps2kb.h"
#include "../acpi/power.h"
#include "../memory/vmap.h"
#include "stacktrace.h"
int zero = 0;
#define MAX_STACK_TRACE 15
extern uint64_t _rbp(void);
// always inline: make sure
static inline __attribute__((always_inline)) void stack_trace(void) {
void** ptr = (void**)_rbp();
puts("backtrace:\n");
for(unsigned i = 0; i < MAX_STACK_TRACE; i++) {
//printf("oui. %lx ", ptr);
if(*ptr == 0) // reached the top
break;
void* rip = *(ptr+1);
if(!is_kernel_memory((uint64_t)rip)) {
//maybe it is an exception error code
rip = *(ptr+2);
printf(" %llx - EXCEPTION\n", rip);
}
else
printf(" %llx\n", rip);
ptr = *ptr;
}
}
__attribute__((noreturn)) void panic(const char* panic_string) {
driver_t* terminal = get_active_terminal();
@ -56,7 +25,7 @@ __attribute__((noreturn)) void panic(const char* panic_string) {
puts(panic_string);
puts("\n\n");
stack_trace();
stacktrace_print();
puts(
"\n\n"

115
kernel/lib/stacktrace.c

@ -0,0 +1,115 @@
#include <stdint.h>
#include "../memory/vmap.h"
#include "../lib/assert.h"
#include "../lib/logging.h"
#include "sprintf.h"
#define MAX_STACK_TRACE 15
extern uint64_t _rbp(void);
typedef struct {
uint64_t addr;
char name[56];
} sym_t;
static const struct {
uint64_t n_symbols;
sym_t symbols[];
}* file = NULL;
void stacktrace_file(const void* f) {
file = f;
}
// offset: output offset
// addr = addr(symbol) + offset
// not found -> return NULL
static const char* get_symbol_name(
uint64_t addr,
unsigned* offset
) {
if(!file)
return NULL;
// dichotomy
uint64_t A = 0;
uint64_t B = file->n_symbols - 1;
uint64_t addrA = file->symbols[0].addr;
uint64_t addrB = file->symbols[file->n_symbols - 1].addr;
if(addr < addrA)
return NULL;
if(addr >= addrB) {
*offset = addr - file->symbols[file->n_symbols - 1].addr;
return file->symbols[file->n_symbols - 1].addr;
}
uint64_t C = (A+B)>>2;
while(A+1 != B) {
uint64_t addrC = file->symbols[C].addr;
if(addr < addrC) {
B = C;
addrB = addrC;
}
else {
A = C;
addrA = addrC;
}
log_warn("issou");
}
*offset = addr - addrA;
return file->symbols[A].name;
}
void stacktrace_print(void) {
void** ptr = (void**)_rbp();
puts("backtrace:\n");
// printf("BAR = %x", bar);
for(unsigned i = 0; i < MAX_STACK_TRACE; i++) {
//printf("oui. %lx ", ptr);
if(*ptr == 0) // reached the top
break;
puts(" ");
int interrupt_routine = 0;
void* rip = *(ptr+1);
if(!is_kernel_memory((uint64_t)rip)) {
//maybe it is an exception error code
interrupt_routine = 1;
rip = *(ptr+2);
}
printf("%llx ", rip);
unsigned* offset;
const char* symbol = get_symbol_name(rip, &offset);
for(;;);
if(symbol)
printf("<%s+%x>", symbol, offset);
else
printf("<??>");
if(!interrupt_routine)
puts("\n");
else
puts(" - INTERRUPT ROUTINE\n");
ptr = *ptr;
}
}

7
kernel/lib/stacktrace.h

@ -0,0 +1,7 @@
#pragma once
// give a stack trace file
void stacktrace_file(const void*);
void stacktrace_print(void);
Loading…
Cancel
Save