Skip to content

Commit

Permalink
stack trace: separate code and logger from page fault handler.
Browse files Browse the repository at this point in the history
  • Loading branch information
mumurik committed May 19, 2010
1 parent aa68f60 commit eb9b760
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 23 deletions.
78 changes: 59 additions & 19 deletions mona/core/kernel/PageManager.cpp
Expand Up @@ -691,6 +691,62 @@ PageEntry* PageManager::allocatePageTable() const
return (PageEntry*)(address);
}

#include "stdarg.h"
#include "vsprintf.h"

class NormalLogger
{
public:
static void printf(const char*fmt, ... )
{
#define BUFFER_SIZE 512
char buf[BUFFER_SIZE];
va_list ap;
va_start(ap, fmt);

int ret = vsprintf(buf, fmt, ap);
va_end(ap);
if (ret >= BUFFER_SIZE) {
print("bufer over at StackTrace::printf");
}
print(buf);
}
static void print(const char* str)
{
g_console->printf(str);
logprintf(str);
}
};

class StackTracer
{
public:
StackTracer(SymbolDictionary::SymbolDictionaryMap& dictMap) : dictMap_(dictMap) {}
template <class T> void dump(uint32_t pid, uint32_t ebp, uint32_t stackStart)
{
SymbolDictionary::SymbolDictionary *dict = dictMap_.get(pid);
if(dict != NULL)
{
T::printf("nullpo! stack trace:\n");
void**bp = (void**)ebp;
while(bp && ((uint32_t)bp) < stackStart)
{
// caller = bp[1];
SymbolDictionary::SymbolEntry* ent = dict->lookup((uint32_t)bp[1]);
if(ent != NULL)
T::printf(" %s: %s (%x)\n", ent->FunctionName, ent->FileName, (uint32_t)bp[1]);
else
T::printf("(unknown) %x\n", (uint32_t)bp[1]);
bp = (void**)(*bp);
}
dictMap_.remove(pid);
}
}

private:
SymbolDictionary::SymbolDictionaryMap& dictMap_;
};

// PageEntry* PageManager::allocatePageTable() const
// {
// uint8_t* table;
Expand Down Expand Up @@ -752,25 +808,9 @@ bool PageManager::pageFaultHandler(LinearAddress address, uint32_t error, uint32
logprintf("esp=%x ebp=%x esi=%x edi=%x\n", i->esp, i->ebp, i->esi, i->edi);
logprintf("cs =%x ds =%x ss =%x cr3=%x\n", i->cs , i->ds , i->ss , i->cr3);
logprintf("eflags=%x eip=%x\n", i->eflags, i->eip);
// stack walk here.
uint32_t pid = g_currentThread->process->getPid();
SymbolDictionary::SymbolDictionary *dict = symbolDictionaryMap_.get(pid);
if(dict != NULL)
{
g_console->printf("print stack trace:\n");
void**bp = (void**)i->ebp;
while(bp && ((uint32_t)bp) < g_currentThread->thread->stackSegment->getStart())
{
// caller = bp[1];
SymbolDictionary::SymbolEntry* ent = dict->lookup((uint32_t)bp[1]);
if(ent != NULL)
g_console->printf(" %s: %s\n", ent->FunctionName, ent->FileName);
else
g_console->printf("(unknown) %x\n", (uint32_t)bp[1]);
bp = (void**)(*bp);
}
symbolDictionaryMap_.remove(pid);
}

StackTracer tracer(symbolDictionaryMap_);
tracer.dump<NormalLogger>(g_currentThread->process->getPid(), i->ebp, g_currentThread->thread->stackSegment->getStart());
#endif

uint32_t stackButtom = current->getStackBottom(g_currentThread->thread);
Expand Down
4 changes: 0 additions & 4 deletions mona/core/kernel/PageManager.h
Expand Up @@ -12,9 +12,6 @@
#ifndef _MONA_PAGE_MANAGER_
#define _MONA_PAGE_MANAGER_

// for debug
#include "VirtualConsole.h"
extern "C" VirtualConsole* g_console;

#include "BitMap.h"
#include <sys/SymbolDictionary.h>
Expand Down Expand Up @@ -72,7 +69,6 @@ class PageManager {
SymbolDictionary::SymbolDictionary* dict = new SymbolDictionary::SymbolDictionary();
if(!dict->deserialize(data, size)) // deserialize use many memory, so I check error only here.
{
g_console->printf("deserialize fail!\n");
delete dict;
return false;
}
Expand Down

0 comments on commit eb9b760

Please sign in to comment.