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
+