diff options
author | Perttu Ahola <celeron55@gmail.com> | 2010-11-27 01:02:21 +0200 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2010-11-27 01:02:21 +0200 |
commit | 4e249fb3fbf75f0359758760d88e22aa5b14533c (patch) | |
tree | 323087d05efbd2ace27b316d4f017cf812a31992 /src/debug.cpp | |
download | minetest-4e249fb3fbf75f0359758760d88e22aa5b14533c.tar.gz minetest-4e249fb3fbf75f0359758760d88e22aa5b14533c.tar.bz2 minetest-4e249fb3fbf75f0359758760d88e22aa5b14533c.zip |
Initial files
Diffstat (limited to 'src/debug.cpp')
-rw-r--r-- | src/debug.cpp | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/src/debug.cpp b/src/debug.cpp new file mode 100644 index 000000000..248941386 --- /dev/null +++ b/src/debug.cpp @@ -0,0 +1,189 @@ +/* +(c) 2010 Perttu Ahola <celeron55@gmail.com> +*/ + +#include "debug.h" +#include <stdio.h> +#include <stdlib.h> + +#ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN + #include <windows.h> + #define sleep_ms(x) Sleep(x) +#else + #include <unistd.h> + #define sleep_ms(x) usleep(x*1000) +#endif + +/* + Debug output +*/ + +FILE *g_debugstreams[DEBUGSTREAM_COUNT] = {stderr, NULL}; + +void debugstreams_init(bool disable_stderr, const char *filename) +{ + if(disable_stderr) + g_debugstreams[0] = NULL; + + if(filename) + g_debugstreams[1] = fopen(filename, "a"); + + if(g_debugstreams[1]) + { + fprintf(g_debugstreams[1], "\n\n-------------\n"); + fprintf(g_debugstreams[1], " Separator \n"); + fprintf(g_debugstreams[1], "-------------\n\n"); + } +} + +void debugstreams_deinit() +{ + if(g_debugstreams[1] != NULL) + fclose(g_debugstreams[1]); +} + +Debugbuf debugbuf(false); +std::ostream dstream(&debugbuf); +Debugbuf debugbuf_no_stderr(true); +std::ostream dstream_no_stderr(&debugbuf_no_stderr); +Nullstream dummyout; + +/* + Assert +*/ + +void assert_fail(const char *assertion, const char *file, + unsigned int line, const char *function) +{ + DEBUGPRINT("\nIn thread %x:\n" + "%s:%d: %s: Assertion '%s' failed.\n", + (unsigned int)get_current_thread_id(), + file, line, function, assertion); + + debug_stacks_print(); + + if(g_debugstreams[1]) + fclose(g_debugstreams[1]); + + //sleep_ms(3000); + + abort(); +} + +/* + DebugStack +*/ + +DebugStack::DebugStack(threadid_t id) +{ + threadid = id; + stack_i = 0; + stack_max_i = 0; +} + +void DebugStack::print(FILE *file, bool everything) +{ + fprintf(file, "BEGIN STACK: Debug stack for thread %x:\n", + (unsigned int)threadid); + + for(int i=0; i<stack_max_i; i++) + { + if(i == stack_i && everything == false) + continue; + + if(everything == true && i == stack_i) + fprintf(file, "END OF STACK.\n" + "! Continuing beyond stack end:\n"); + + fprintf(file, "#%d %s\n", i, stack[i]); + } + + if(stack_i == DEBUG_STACK_SIZE) + fprintf(file, "Probably overflown.\n"); +} + + +core::map<threadid_t, DebugStack*> g_debug_stacks; +JMutex g_debug_stacks_mutex; + +void debug_stacks_init() +{ + g_debug_stacks_mutex.Init(); +} + +void debug_stacks_print() +{ + JMutexAutoLock lock(g_debug_stacks_mutex); + + DEBUGPRINT("Debug stacks:\n"); + + for(core::map<threadid_t, DebugStack*>::Iterator + i = g_debug_stacks.getIterator(); + i.atEnd() == false; i++) + { + DebugStack *stack = i.getNode()->getValue(); + + for(int i=0; i<DEBUGSTREAM_COUNT; i++) + { + if(g_debugstreams[i] != NULL) + stack->print(g_debugstreams[i], true); + } + } +} + +DebugStacker::DebugStacker(const char *text) +{ + threadid_t threadid = get_current_thread_id(); + + JMutexAutoLock lock(g_debug_stacks_mutex); + + core::map<threadid_t, DebugStack*>::Node *n; + n = g_debug_stacks.find(threadid); + if(n != NULL) + { + m_stack = n->getValue(); + } + else + { + /*DEBUGPRINT("Creating new debug stack for thread %x\n", + (unsigned int)threadid);*/ + m_stack = new DebugStack(threadid); + g_debug_stacks.insert(threadid, m_stack); + } + + if(m_stack->stack_i >= DEBUG_STACK_SIZE) + { + m_overflowed = true; + } + else + { + m_overflowed = false; + + snprintf(m_stack->stack[m_stack->stack_i], + DEBUG_STACK_TEXT_SIZE, "%s", text); + m_stack->stack_i++; + if(m_stack->stack_i > m_stack->stack_max_i) + m_stack->stack_max_i = m_stack->stack_i; + } +} + +DebugStacker::~DebugStacker() +{ + JMutexAutoLock lock(g_debug_stacks_mutex); + + if(m_overflowed == true) + return; + + m_stack->stack_i--; + + if(m_stack->stack_i == 0) + { + threadid_t threadid = m_stack->threadid; + /*DEBUGPRINT("Deleting debug stack for thread %x\n", + (unsigned int)threadid);*/ + delete m_stack; + g_debug_stacks.remove(threadid); + } +} + |