stack_trace try to get function arguments

This commit is contained in:
Mathieu Maret 2018-11-19 13:56:19 +01:00
parent dc0789aa72
commit e998fec795
4 changed files with 58 additions and 18 deletions

View File

@ -4,9 +4,9 @@ AS=nasm
ASFLAGS += -f elf32
#LDFLAGS += -m32 -nostdlib -mkernel -fno-stack-protector
LDFLAGS += -m32 -nostdlib -static -fno-common -fno-use-cxa-atexit -fno-exceptions -fno-non-call-exceptions -fno-weak -fno-rtti -fno-stack-protector
CFLAGS += -m32 -Wall -Wextra -Werror -ffreestanding -fno-exceptions -fno-pie -fno-stack-protector
CXXFLAGS += -m32 -Wall -Wextra -Werror -ffreestanding -fno-exceptions -fno-rtti -fno-pie
DEBUG_FLAGS += -g -Og -DDEBUG -fno-omit-frame-pointer
CFLAGS += -m32 -Wall -Wextra -Werror -ffreestanding -fno-exceptions -fno-pie -fno-stack-protector
CXXFLAGS += -m32 -Wall -Wextra -Werror -ffreestanding -fno-exceptions -fno-rtti -fno-pie
DEBUG_FLAGS += -g -Og -DDEBUG -fno-omit-frame-pointer -fno-inline
SUBDIRS := core drivers tests
@ -39,7 +39,7 @@ core/irq_handler.o:core/irq_handler.c
%.o:%.asm
$(AS) $(ASFLAGS) -o $@ $<
self_test: CFLAGS += -DRUN_TEST
self_test: CFLAGS += -DRUN_TEST -DDEBUG
self_test: clean kernel
qemu-system-x86_64 -kernel kernel -serial stdio

View File

@ -32,7 +32,7 @@ align 16
stack_bottom:
resb 16384 ; 16 KiB
stack_top:
; The linker script specifies _start as the entry point to the kernel and the
; bootloader will jump to this position once the kernel has been loaded. It
; doesn't make sense to return from this function as the bootloader is gone.
@ -55,7 +55,7 @@ _start:
; stack (as it grows downwards on x86 systems). This is necessarily done
; in assembly as languages such as C cannot function without a stack.
mov esp, stack_top
mov ebp, stack_bottom
mov ebp, esp
; This is a good place to initialize crucial processor state before the
; high-level kernel is entered. It's best to minimize the early
@ -100,3 +100,8 @@ _start:
.hang: hlt
jmp .hang
.end:
global _stack_bottom
_stack_bottom: dd stack_bottom
global _stack_top
_stack_top: dd stack_top

View File

@ -1,28 +1,47 @@
#include "stack.h"
#include "types.h"
#include "vga.h"
void printStackTrace(unsigned int maxFrames){
extern vaddr_t _stack_bottom;
extern vaddr_t _stack_top;
void printStackTrace(unsigned int maxFrames)
{
#ifdef DEBUG
// Now on Stack:
// ( potential second function argument )
// ( potential second function argument )
// first function argument (maxFrames)
// return address from caller
// EBP (Extended Base Pointer) of calling function
unsigned int * ebp = &maxFrames - 2;
for (unsigned int frame = 0 ; frame < maxFrames; frame ++){
unsigned int eip = ebp [1];
if (eip == 0){
unsigned int *ebp = __builtin_frame_address(0);
for (unsigned int frame = 0; frame < maxFrames; frame++) {
unsigned int eip = ebp[1];
if (eip == 0) {
// No caller on stack
break;
}
unsigned int *arguments = ebp + 2;
printf("[%d] 0x%x (", frame, eip);
int nbArg = 0;
do {
if ((_stack_bottom <= (vaddr_t)arguments) &&
((vaddr_t)arguments <= _stack_top)) {
printf(" 0x%x", *arguments);
arguments += 1;
} else {
break;
}
nbArg++;
if (nbArg >= 4) {
break;
}
} while (1);
printf(")\n");
ebp = (unsigned int *)(ebp[0]);
//unsigned int * arguments = &ebp[2];
printf(" 0x%x\n", eip);
}
#else
printf("Must be compiled with -fno-omit-frame-pointer for full stack\n");
unsigned int * ebp = &maxFrames - 2;
unsigned int eip = ebp [1];
printf("Caller: 0x%x\n", eip);
unsigned int *ebp = &maxFrames - 2;
unsigned int eip = ebp[1];
printf("[0] 0x%x\n", eip);
#endif
}

View File

@ -1,7 +1,9 @@
#include "list.h"
#include "klibc.h"
#include "mem.h"
#include "paging.h"
#include "serial.h"
#include "stack.h"
#include "vga.h"
void testPhymem(void)
@ -79,13 +81,27 @@ static void testPaging(void)
}
}
static void test_backtrace_2(int a, int b){
printStackTrace(a+b);
}
static void test_backtrace_1(int a){
test_backtrace_2(a, 3);
}
void test_backtrace(){
test_backtrace_1(2);
}
void run_test(void)
{
testPaging();
printf("Testing Serial");
printf("Testing Serial\n");
serialWrite('h');
serialWrite('e');
serialWrite('l');
serialWrite('l');
serialWrite('o');
printf("Testing backtrace\n");
test_backtrace();
}