From cfbbf672473d5b45cbd52f9a94016a3551a6883d Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Fri, 2 Mar 2012 14:08:25 +0100 Subject: [PATCH] make CALLTRACE=1 to enable printing primitive calltraces upon panic. This won't work with optimizations turned fully on. Added protection against double panics. --- sortix/Makefile | 11 +++++++-- sortix/calltrace.cpp | 45 ++++++++++++++++++++++++++++++++++++ sortix/calltrace.h | 35 ++++++++++++++++++++++++++++ sortix/panic.cpp | 24 +++++++++++++++++++ sortix/x64/calltrace.s | 50 ++++++++++++++++++++++++++++++++++++++++ sortix/x86/calltrace.s | 52 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 sortix/calltrace.cpp create mode 100644 sortix/calltrace.h create mode 100644 sortix/x64/calltrace.s create mode 100644 sortix/x86/calltrace.s diff --git a/sortix/Makefile b/sortix/Makefile index 344f2d4a..d96fa872 100644 --- a/sortix/Makefile +++ b/sortix/Makefile @@ -54,12 +54,17 @@ ifeq ($(JSSORTIX),1) endif ifeq ($(PANIC_SHORT),1) DEFINES:=$(DEFINES) -DPANIC_SHORT -endif +endif ifeq ($(DISKWRITE),1) DEFINES:=$(DEFINES) -DENABLE_DISKWRITE=1 else DEFINES:=$(DEFINES) -DENABLE_DISKWRITE=0 -endif +endif +ifeq ($(CALLTRACE),1) + DEFINES:=$(DEFINES) -DENABLE_CALLTRACE=1 +else + DEFINES:=$(DEFINES) -DENABLE_CALLTRACE=0 +endif INCLUDES=-I../libmaxsi/preproc -I.. -I. CPPFLAGS=$(INCLUDES) $(DEFINES) @@ -81,6 +86,8 @@ interrupt.o \ time.o \ log.o \ utf8.o \ +calltrace.o \ +$(CPU)/calltrace.o \ panic.o \ keyboard.o \ kb/ps2.o \ diff --git a/sortix/calltrace.cpp b/sortix/calltrace.cpp new file mode 100644 index 00000000..46ab1c73 --- /dev/null +++ b/sortix/calltrace.cpp @@ -0,0 +1,45 @@ +/******************************************************************************* + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . + + calltrace.cpp + Traverses the stack and prints the callstack, which aids debugging. + +*******************************************************************************/ + +#include "platform.h" +#include "calltrace.h" + +namespace Sortix { +namespace Calltrace { + +extern "C" void calltrace(); +extern "C" void calltrace_print_function(size_t index, addr_t ip) +{ + Log::PrintF("%zu: 0x%zx\n", index, ip); +} + +void Perform() +{ + Log::PrintF("Calltrace:\n"); + calltrace(); +} + +} // namespace Calltrace +} // namespace Sortix + diff --git a/sortix/calltrace.h b/sortix/calltrace.h new file mode 100644 index 00000000..34a16591 --- /dev/null +++ b/sortix/calltrace.h @@ -0,0 +1,35 @@ +/******************************************************************************* + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . + + calltrace.h + Traverses the stack and prints the callstack, which aids debugging. + +*******************************************************************************/ + +#ifndef SORTIX_CALLTRACE_H +#define SORTIX_CALLTRACE_H + +namespace Sortix { +namespace Calltrace { +void Perform(); +} // namespace Calltrace +} // namespace Sortix + +#endif + diff --git a/sortix/panic.cpp b/sortix/panic.cpp index ccf6b6d6..e19f43c3 100644 --- a/sortix/panic.cpp +++ b/sortix/panic.cpp @@ -26,6 +26,7 @@ #include #include #include "log.h" +#include "calltrace.h" #include "panic.h" using namespace Maxsi; @@ -37,9 +38,17 @@ namespace Sortix #else bool longpanic = true; #endif + bool panicing = false; + bool doublepanic = false; void PanicInit() { + if ( panicing ) + { + Log::PrintF("Panic while panicing:\n"); + doublepanic = true; + return; + } if ( longpanic ) { Log::Print("\e[m\e[31;40m\e[2J\e[H"); @@ -71,6 +80,19 @@ namespace Sortix Log::Print("\e[m\e[31m\e[0J"); Log::Print("RED MAXSI OF DEATH\n"); } + panicing = true; + } + + void PanicCalltrace() + { + Log::Print("\n"); + Calltrace::Perform(); + } + + void PanicHooks() + { + if ( doublepanic ) { return; } + if ( ENABLE_CALLTRACE ) { PanicCalltrace(); } } void PanicHalt() @@ -85,6 +107,7 @@ namespace Sortix { PanicInit(); Log::Print(Error); + PanicHooks(); PanicHalt(); } @@ -95,6 +118,7 @@ namespace Sortix va_start(list, Format); Log::PrintFV(Format, list); va_end(list); + PanicHooks(); PanicHalt(); } } diff --git a/sortix/x64/calltrace.s b/sortix/x64/calltrace.s new file mode 100644 index 00000000..d2997826 --- /dev/null +++ b/sortix/x64/calltrace.s @@ -0,0 +1,50 @@ +/******************************************************************************* + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . + + x64/calltrace.s + Attempts to unwind the stack and prints the code locations where functions + were called. This greatly aids debugging. + +*******************************************************************************/ + +.section .text + +.global calltrace +.type calltrace, @function +calltrace: + push %rbp + movq %rsp, %rbp + xorl %edi, %edi + movq %rbp, %rbx + +calltrace_unwind: + testq %rbx, %rbx + jz calltrace_done + movq 8(%rbx), %rsi # Previous RIP + movq 0(%rbx), %rbx # Previous RBP + pushq %rdi + call calltrace_print_function + popq %rdi + incq %rdi + jmp calltrace_unwind + +calltrace_done: + popq %rbp + retq + diff --git a/sortix/x86/calltrace.s b/sortix/x86/calltrace.s new file mode 100644 index 00000000..92e37f3d --- /dev/null +++ b/sortix/x86/calltrace.s @@ -0,0 +1,52 @@ +/******************************************************************************* + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . + + x86/calltrace.s + Attempts to unwind the stack and prints the code locations where functions + were called. This greatly aids debugging. + +*******************************************************************************/ + +.section .text + +.global calltrace +.type calltrace, @function +calltrace: + push %ebp + movl %esp, %ebp + xorl %edi, %edi + movl %ebp, %ebx + +calltrace_unwind: + testl %ebx, %ebx + jz calltrace_done + movl 4(%ebx), %esi # Previous EIP + movl 0(%ebx), %ebx # Previous EBP + pushl %esi + pushl %edi + call calltrace_print_function + popl %edi + addl $4, %esp + incl %edi + jmp calltrace_unwind + +calltrace_done: + popl %ebp + retl +