[kernel] Use symbol table in stack traces

Now using the symbol table built by build_symbol_table.py in the kernel
when printing stack traces.
This commit is contained in:
2020-08-09 17:27:51 -07:00
parent 0d94776c46
commit bbb9aae198
12 changed files with 137 additions and 12 deletions

View File

@@ -5,6 +5,7 @@
#include "objects/process.h"
#include "objects/thread.h"
#include "page_manager.h"
#include "symbol_table.h"
size_t __counter_syscall_enter = 0;
size_t __counter_syscall_sysret = 0;
@@ -59,14 +60,26 @@ void
print_stacktrace(int skip)
{
console *cons = console::get();
symbol_table *syms = symbol_table::get();
frame *fp = nullptr;
int fi = -skip;
__asm__ __volatile__ ( "mov %%rbp, %0" : "=r" (fp) );
while (fp && fp->return_addr) {
if (fi++ >= 0)
cons->printf(" frame %2d: %lx\n", fi-1, fp->return_addr);
if (fi++ >= 0) {
const symbol_table::entry *e = syms ? syms->find_symbol(fp->return_addr) : nullptr;
const char *name = e ? e->name : "";
cons->printf(" frame %2d:", fi-1);
cons->set_color(5);
cons->printf(" %016llx", fp->return_addr);
cons->set_color();
cons->set_color(6);
cons->printf(" %s\n", name);
cons->set_color();
}
fp = fp->prev;
}
}

View File

@@ -22,6 +22,7 @@
#include "page_manager.h"
#include "scheduler.h"
#include "serial.h"
#include "symbol_table.h"
#include "syscall.h"
extern "C" {
@@ -121,8 +122,11 @@ kernel_main(args::header *header)
initrd::disk &ird = initrds.emplace(mod.location);
log::info(logs::boot, "initrd loaded with %d files.", ird.files().count());
for (auto &f : ird.files())
log::info(logs::boot, " %s%s (%d bytes).", f.executable() ? "*" : "", f.name(), f.size());
for (auto &f : ird.files()) {
char type = f.executable() ? '*' :
f.symbols() ? '+' : ' ';
log::info(logs::boot, " %c%s (%d bytes).", type, f.name(), f.size());
}
}
/*
@@ -180,14 +184,16 @@ kernel_main(args::header *header)
for (auto &ird : initrds) {
for (auto &f : ird.files()) {
if (f.executable())
if (f.executable()) {
sched->load_process(f.name(), f.data(), f.size());
} else if (f.symbols()) {
new symbol_table {f.data(), f.size()};
}
}
}
log::info(logs::objs, "Testing object system:");
/*
log::info(logs::objs, "Testing object system:");
test_observer obs1("event");
test_observer obs2("no handles");
{

View File

@@ -0,0 +1,49 @@
#include "kutil/assert.h"
#include "kutil/memory.h"
#include "log.h"
#include "symbol_table.h"
symbol_table * symbol_table::s_instance = nullptr;
symbol_table::symbol_table(const void *data, size_t size)
{
m_data = kutil::kalloc(size);
kassert(m_data, "Failed to allocate for symbol table");
kutil::memcpy(m_data, data, size);
uint64_t *values = reinterpret_cast<uint64_t*>(m_data);
m_entries = *values++;
m_index = reinterpret_cast<entry*>(values);
for (size_t i = 0; i < m_entries; ++i) {
uint64_t offset = reinterpret_cast<uint64_t>(m_index[i].name);
m_index[i].name = reinterpret_cast<char*>(m_data) + offset;
}
if (!s_instance)
s_instance = this;
log::info(logs::boot, "Loaded %d symbol table entries at %llx", m_entries, m_data);
}
symbol_table::~symbol_table()
{
kutil::kfree(m_data);
}
const symbol_table::entry *
symbol_table::find_symbol(uintptr_t addr) const
{
if (!m_entries)
return nullptr;
// TODO: binary search
for (size_t i = 0; i < m_entries; ++i) {
if (m_index[i].address > addr) {
return i ? &m_index[i - 1] : nullptr;
}
}
return &m_index[m_entries - 1];
}

34
src/kernel/symbol_table.h Normal file
View File

@@ -0,0 +1,34 @@
#pragma once
#include <stdint.h>
class symbol_table
{
public:
struct entry
{
uintptr_t address;
char *name;
};
static symbol_table * get() { return s_instance; }
/// Constructor.
/// \arg data Pointer to the start of the symbol_table data.
/// \arg size Size of the data, in bytes
symbol_table(const void *data, size_t size);
~symbol_table();
/// Find the closest symbol address before the given address
/// \args addr Address to search for
/// \returns Actual address of the symbol
const entry * find_symbol(uintptr_t addr) const;
private:
size_t m_entries;
entry *m_index;
void *m_data;
static symbol_table *s_instance;
};