diff options
Diffstat (limited to 'src/debug.cpp')
-rw-r--r-- | src/debug.cpp | 170 |
1 files changed, 39 insertions, 131 deletions
diff --git a/src/debug.cpp b/src/debug.cpp index ae2ffadc3..8647160b1 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -26,8 +26,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <stdlib.h> #include <cstring> #include <map> -#include "jthread/jmutex.h" -#include "jthread/jmutexautolock.h" +#include <sstream> +#include "threading/mutex.h" +#include "threading/mutex_auto_lock.h" #include "config.h" #ifdef _MSC_VER @@ -36,98 +37,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #endif -/* - Debug output -*/ - -#define DEBUGSTREAM_COUNT 2 - -FILE *g_debugstreams[DEBUGSTREAM_COUNT] = {stderr, NULL}; - -#define DEBUGPRINT(...)\ -{\ - for(int i=0; i<DEBUGSTREAM_COUNT; i++)\ - {\ - if(g_debugstreams[i] != NULL){\ - fprintf(g_debugstreams[i], __VA_ARGS__);\ - fflush(g_debugstreams[i]);\ - }\ - }\ -} - -void debugstreams_init(bool disable_stderr, const char *filename) -{ - if(disable_stderr) - g_debugstreams[0] = NULL; - else - g_debugstreams[0] = stderr; - - 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]); -} - -class Debugbuf : public std::streambuf -{ -public: - Debugbuf(bool disable_stderr) - { - m_disable_stderr = disable_stderr; - } - - int overflow(int c) - { - for(int i=0; i<DEBUGSTREAM_COUNT; i++) - { - if(g_debugstreams[i] == stderr && m_disable_stderr) - continue; - if(g_debugstreams[i] != NULL) - (void)fwrite(&c, 1, 1, g_debugstreams[i]); - //TODO: Is this slow? - fflush(g_debugstreams[i]); - } - - return c; - } - std::streamsize xsputn(const char *s, std::streamsize n) - { -#ifdef __ANDROID__ - __android_log_print(ANDROID_LOG_VERBOSE, PROJECT_NAME, "%s", s); +#if USE_CURSES + #include "terminal_chat_console.h" #endif - for(int i=0; i<DEBUGSTREAM_COUNT; i++) - { - if(g_debugstreams[i] == stderr && m_disable_stderr) - continue; - if(g_debugstreams[i] != NULL) - (void)fwrite(s, 1, n, g_debugstreams[i]); - //TODO: Is this slow? - fflush(g_debugstreams[i]); - } - - return n; - } - -private: - bool m_disable_stderr; -}; - -Debugbuf debugbuf(false); -std::ostream dstream(&debugbuf); -Debugbuf debugbuf_no_stderr(true); -std::ostream dstream_no_stderr(&debugbuf_no_stderr); -Nullstream dummyout; /* Assert @@ -136,15 +48,16 @@ Nullstream dummyout; void sanity_check_fn(const char *assertion, const char *file, unsigned int line, const char *function) { - DEBUGPRINT("\nIn thread %lx:\n" - "%s:%u: %s: An engine assumption '%s' failed.\n", - (unsigned long)get_current_thread_id(), - file, line, function, assertion); +#if USE_CURSES + g_term_console.stopAndWaitforThread(); +#endif - debug_stacks_print(); + errorstream << std::endl << "In thread " << std::hex + << thr_get_current_thread_id() << ":" << std::endl; + errorstream << file << ":" << line << ": " << function + << ": An engine assumption '" << assertion << "' failed." << std::endl; - if(g_debugstreams[1]) - fclose(g_debugstreams[1]); + debug_stacks_print_to(errorstream); abort(); } @@ -152,15 +65,16 @@ void sanity_check_fn(const char *assertion, const char *file, void fatal_error_fn(const char *msg, const char *file, unsigned int line, const char *function) { - DEBUGPRINT("\nIn thread %lx:\n" - "%s:%u: %s: A fatal error occurred: %s\n", - (unsigned long)get_current_thread_id(), - file, line, function, msg); +#if USE_CURSES + g_term_console.stopAndWaitforThread(); +#endif - debug_stacks_print(); + errorstream << std::endl << "In thread " << std::hex + << thr_get_current_thread_id() << ":" << std::endl; + errorstream << file << ":" << line << ": " << function + << ": A fatal error occured: " << msg << std::endl; - if(g_debugstreams[1]) - fclose(g_debugstreams[1]); + debug_stacks_print_to(errorstream); abort(); } @@ -191,8 +105,10 @@ DebugStack::DebugStack(threadid_t id) void DebugStack::print(FILE *file, bool everything) { - fprintf(file, "DEBUG STACK FOR THREAD %lx:\n", - (unsigned long)threadid); + std::ostringstream os; + os << threadid; + fprintf(file, "DEBUG STACK FOR THREAD %s:\n", + os.str().c_str()); for(int i=0; i<stack_max_i; i++) { @@ -211,7 +127,7 @@ void DebugStack::print(FILE *file, bool everything) void DebugStack::print(std::ostream &os, bool everything) { - os<<"DEBUG STACK FOR THREAD "<<(unsigned long)threadid<<": "<<std::endl; + os<<"DEBUG STACK FOR THREAD "<<threadid<<": "<<std::endl; for(int i=0; i<stack_max_i; i++) { @@ -228,8 +144,15 @@ void DebugStack::print(std::ostream &os, bool everything) os<<"Probably overflown."<<std::endl; } +// Note: Using pthread_t (that is, threadid_t on POSIX platforms) as the key to +// a std::map is naughty. Formally, a pthread_t may only be compared using +// pthread_equal() - pthread_t lacks the well-ordered property needed for +// comparisons in binary searches. This should be fixed at some point by +// defining a custom comparator with an arbitrary but stable ordering of +// pthread_t, but it isn't too important since none of our supported platforms +// implement pthread_t as a non-ordinal type. std::map<threadid_t, DebugStack*> g_debug_stacks; -JMutex g_debug_stacks_mutex; +Mutex g_debug_stacks_mutex; void debug_stacks_init() { @@ -237,7 +160,7 @@ void debug_stacks_init() void debug_stacks_print_to(std::ostream &os) { - JMutexAutoLock lock(g_debug_stacks_mutex); + MutexAutoLock lock(g_debug_stacks_mutex); os<<"Debug stacks:"<<std::endl; @@ -251,29 +174,14 @@ void debug_stacks_print_to(std::ostream &os) void debug_stacks_print() { - JMutexAutoLock lock(g_debug_stacks_mutex); - - DEBUGPRINT("Debug stacks:\n"); - - for(std::map<threadid_t, DebugStack*>::iterator - i = g_debug_stacks.begin(); - i != g_debug_stacks.end(); ++i) - { - DebugStack *stack = i->second; - - for(int i=0; i<DEBUGSTREAM_COUNT; i++) - { - if(g_debugstreams[i] != NULL) - stack->print(g_debugstreams[i], true); - } - } + debug_stacks_print_to(errorstream); } DebugStacker::DebugStacker(const char *text) { - threadid_t threadid = get_current_thread_id(); + threadid_t threadid = thr_get_current_thread_id(); - JMutexAutoLock lock(g_debug_stacks_mutex); + MutexAutoLock lock(g_debug_stacks_mutex); std::map<threadid_t, DebugStack*>::iterator n; n = g_debug_stacks.find(threadid); @@ -307,7 +215,7 @@ DebugStacker::DebugStacker(const char *text) DebugStacker::~DebugStacker() { - JMutexAutoLock lock(g_debug_stacks_mutex); + MutexAutoLock lock(g_debug_stacks_mutex); if(m_overflowed == true) return; |