From e998fec79519737628187fec282636a26c26c6c6 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Mon, 19 Nov 2018 13:56:19 +0100 Subject: [PATCH] stack_trace try to get function arguments --- Makefile | 8 ++++---- boot.asm | 9 +++++++-- core/stack.c | 41 ++++++++++++++++++++++++++++++----------- tests/test.c | 18 +++++++++++++++++- 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 8225e46..6b7ef84 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/boot.asm b/boot.asm index ed48094..5f9b676 100644 --- a/boot.asm +++ b/boot.asm @@ -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 diff --git a/core/stack.c b/core/stack.c index b6a79ab..724c80b 100644 --- a/core/stack.c +++ b/core/stack.c @@ -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 } diff --git a/tests/test.c b/tests/test.c index d99714b..be951c6 100644 --- a/tests/test.c +++ b/tests/test.c @@ -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(); }