diff --git a/libc/Makefile b/libc/Makefile
index c819bbaa..0a5e6358 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -121,11 +121,13 @@ wctype.o \
HOSTEDOBJS=\
access.o \
+calltrace.o \
chdir.o \
chmod.o \
chown.o \
clock.o \
close.o \
+$(CPUDIR)/calltrace.o \
$(CPUDIR)/fork.o \
$(CPUDIR)/signal.o \
$(CPUDIR)/syscall.o \
diff --git a/libc/calltrace.cpp b/libc/calltrace.cpp
new file mode 100644
index 00000000..cacff79e
--- /dev/null
+++ b/libc/calltrace.cpp
@@ -0,0 +1,43 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2012.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ calltrace.cpp
+ Traverses the stack and prints the callstack.
+
+*******************************************************************************/
+
+#include
+#include
+#include
+#include
+
+extern "C" void asm_calltrace();
+
+extern "C" void calltrace_print_function(size_t index, unsigned long ip)
+{
+ fprintf(stdout, "[pid=%i %s] %zu: 0x%lx\n", getpid(),
+ program_invocation_short_name, index, ip);
+}
+
+extern "C" void calltrace()
+{
+ fprintf(stdout, "[pid=%i %s] Calltrace: (%s)\n", getpid(),
+ program_invocation_short_name, program_invocation_name);
+ asm_calltrace();
+}
diff --git a/libc/include/calltrace.h b/libc/include/calltrace.h
new file mode 100644
index 00000000..d0d6c565
--- /dev/null
+++ b/libc/include/calltrace.h
@@ -0,0 +1,36 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2012.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ calltrace.h
+ Traverses the stack and prints the callstack.
+
+*******************************************************************************/
+
+#ifndef _CALLTRACE_H
+#define _CALLTRACE_H 1
+
+#include
+
+__BEGIN_DECLS
+
+void calltrace();
+
+__END_DECLS
+
+#endif
diff --git a/libc/x64/calltrace.s b/libc/x64/calltrace.s
new file mode 100644
index 00000000..2cd33749
--- /dev/null
+++ b/libc/x64/calltrace.s
@@ -0,0 +1,53 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ x64/calltrace.s
+ Attempts to unwind the stack and prints the code locations where functions
+ were called. This greatly aids debugging.
+
+*******************************************************************************/
+
+.global asm_calltrace
+.type asm_calltrace, @function
+asm_calltrace:
+ push %rbp
+ mov %rsp, %rbp
+ push %rbx
+ push %r12
+ xor %r12, %r12
+ mov %rbp, %rbx
+
+.Lasm_calltrace_unwind:
+ test %rbx, %rbx
+ jz .Lasm_calltrace_done
+ mov 8(%rbx), %rsi # Previous RIP
+ mov 0(%rbx), %rbx # Previous RBP
+ test %rsi, %rsi
+ jz .Lasm_calltrace_done
+ mov %r12, %rdi
+ call calltrace_print_function
+ inc %r12
+ jmp .Lasm_calltrace_unwind
+
+.Lasm_calltrace_done:
+ pop %r12
+ pop %rbx
+ pop %rbp
+ ret
+.size asm_calltrace, . - asm_calltrace
diff --git a/libc/x86/calltrace.s b/libc/x86/calltrace.s
new file mode 100644
index 00000000..3ebfa904
--- /dev/null
+++ b/libc/x86/calltrace.s
@@ -0,0 +1,55 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ x86/calltrace.s
+ Attempts to unwind the stack and prints the code locations where functions
+ were called. This greatly aids debugging.
+
+*******************************************************************************/
+
+.global asm_calltrace
+.type asm_calltrace, @function
+asm_calltrace:
+ push %ebp
+ mov %esp, %ebp
+ push %ebx
+ push %esi
+ xor %esi, %esi
+ mov %ebp, %ebx
+
+.Lasm_calltrace_unwind:
+ test %ebx, %ebx
+ jz .Lasm_calltrace_done
+ mov 4(%ebx), %ecx # Previous EIP
+ mov 0(%ebx), %ebx # Previous EBP
+ test %ecx, %ecx
+ jz .Lasm_calltrace_done
+ push %ecx
+ push %esi
+ call calltrace_print_function
+ add $8, %esp
+ inc %esi
+ jmp .Lasm_calltrace_unwind
+
+.Lasm_calltrace_done:
+ pop %esi
+ pop %ebx
+ pop %ebp
+ ret
+.size asm_calltrace, . - asm_calltrace