stack_trace try to get function arguments
This commit is contained in:
parent
dc0789aa72
commit
e998fec795
4
Makefile
4
Makefile
@ -6,7 +6,7 @@ ASFLAGS += -f elf32
|
|||||||
LDFLAGS += -m32 -nostdlib -static -fno-common -fno-use-cxa-atexit -fno-exceptions -fno-non-call-exceptions -fno-weak -fno-rtti -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
|
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
|
CXXFLAGS += -m32 -Wall -Wextra -Werror -ffreestanding -fno-exceptions -fno-rtti -fno-pie
|
||||||
DEBUG_FLAGS += -g -Og -DDEBUG -fno-omit-frame-pointer
|
DEBUG_FLAGS += -g -Og -DDEBUG -fno-omit-frame-pointer -fno-inline
|
||||||
|
|
||||||
SUBDIRS := core drivers tests
|
SUBDIRS := core drivers tests
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ core/irq_handler.o:core/irq_handler.c
|
|||||||
%.o:%.asm
|
%.o:%.asm
|
||||||
$(AS) $(ASFLAGS) -o $@ $<
|
$(AS) $(ASFLAGS) -o $@ $<
|
||||||
|
|
||||||
self_test: CFLAGS += -DRUN_TEST
|
self_test: CFLAGS += -DRUN_TEST -DDEBUG
|
||||||
self_test: clean kernel
|
self_test: clean kernel
|
||||||
qemu-system-x86_64 -kernel kernel -serial stdio
|
qemu-system-x86_64 -kernel kernel -serial stdio
|
||||||
|
|
||||||
|
7
boot.asm
7
boot.asm
@ -55,7 +55,7 @@ _start:
|
|||||||
; stack (as it grows downwards on x86 systems). This is necessarily done
|
; stack (as it grows downwards on x86 systems). This is necessarily done
|
||||||
; in assembly as languages such as C cannot function without a stack.
|
; in assembly as languages such as C cannot function without a stack.
|
||||||
mov esp, stack_top
|
mov esp, stack_top
|
||||||
mov ebp, stack_bottom
|
mov ebp, esp
|
||||||
|
|
||||||
; This is a good place to initialize crucial processor state before the
|
; This is a good place to initialize crucial processor state before the
|
||||||
; high-level kernel is entered. It's best to minimize the early
|
; high-level kernel is entered. It's best to minimize the early
|
||||||
@ -100,3 +100,8 @@ _start:
|
|||||||
.hang: hlt
|
.hang: hlt
|
||||||
jmp .hang
|
jmp .hang
|
||||||
.end:
|
.end:
|
||||||
|
|
||||||
|
global _stack_bottom
|
||||||
|
_stack_bottom: dd stack_bottom
|
||||||
|
global _stack_top
|
||||||
|
_stack_top: dd stack_top
|
||||||
|
39
core/stack.c
39
core/stack.c
@ -1,28 +1,47 @@
|
|||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
|
#include "types.h"
|
||||||
#include "vga.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
|
#ifdef DEBUG
|
||||||
// Now on Stack:
|
// Now on Stack:
|
||||||
// ( potential second function argument )
|
// ( potential second function argument )
|
||||||
// first function argument (maxFrames)
|
// first function argument (maxFrames)
|
||||||
// return address from caller
|
// return address from caller
|
||||||
// EBP (Extended Base Pointer) of calling function
|
// EBP (Extended Base Pointer) of calling function
|
||||||
unsigned int * ebp = &maxFrames - 2;
|
unsigned int *ebp = __builtin_frame_address(0);
|
||||||
for (unsigned int frame = 0 ; frame < maxFrames; frame ++){
|
for (unsigned int frame = 0; frame < maxFrames; frame++) {
|
||||||
unsigned int eip = ebp [1];
|
unsigned int eip = ebp[1];
|
||||||
if (eip == 0){
|
if (eip == 0) {
|
||||||
// No caller on stack
|
// No caller on stack
|
||||||
break;
|
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]);
|
ebp = (unsigned int *)(ebp[0]);
|
||||||
//unsigned int * arguments = &ebp[2];
|
|
||||||
printf(" 0x%x\n", eip);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
printf("Must be compiled with -fno-omit-frame-pointer for full stack\n");
|
printf("Must be compiled with -fno-omit-frame-pointer for full stack\n");
|
||||||
unsigned int * ebp = &maxFrames - 2;
|
unsigned int *ebp = &maxFrames - 2;
|
||||||
unsigned int eip = ebp [1];
|
unsigned int eip = ebp[1];
|
||||||
printf("Caller: 0x%x\n", eip);
|
printf("[0] 0x%x\n", eip);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
18
tests/test.c
18
tests/test.c
@ -1,7 +1,9 @@
|
|||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
#include "klibc.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
#include "stack.h"
|
||||||
#include "vga.h"
|
#include "vga.h"
|
||||||
|
|
||||||
void testPhymem(void)
|
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)
|
void run_test(void)
|
||||||
{
|
{
|
||||||
testPaging();
|
testPaging();
|
||||||
printf("Testing Serial");
|
printf("Testing Serial\n");
|
||||||
serialWrite('h');
|
serialWrite('h');
|
||||||
serialWrite('e');
|
serialWrite('e');
|
||||||
serialWrite('l');
|
serialWrite('l');
|
||||||
serialWrite('l');
|
serialWrite('l');
|
||||||
serialWrite('o');
|
serialWrite('o');
|
||||||
|
printf("Testing backtrace\n");
|
||||||
|
test_backtrace();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user