3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #define WIN32_LEAN_AND_MEAN
28 #define sleep_ms(x) Sleep(x)
31 #define sleep_ms(x) usleep(x*1000)
38 FILE *g_debugstreams[DEBUGSTREAM_COUNT] = {stderr, NULL};
40 void debugstreams_init(bool disable_stderr, const char *filename)
43 g_debugstreams[0] = NULL;
46 g_debugstreams[1] = fopen(filename, "a");
50 fprintf(g_debugstreams[1], "\n\n-------------\n");
51 fprintf(g_debugstreams[1], " Separator \n");
52 fprintf(g_debugstreams[1], "-------------\n\n");
56 void debugstreams_deinit()
58 if(g_debugstreams[1] != NULL)
59 fclose(g_debugstreams[1]);
62 Debugbuf debugbuf(false);
63 std::ostream dstream(&debugbuf);
64 Debugbuf debugbuf_no_stderr(true);
65 std::ostream dstream_no_stderr(&debugbuf_no_stderr);
72 void assert_fail(const char *assertion, const char *file,
73 unsigned int line, const char *function)
75 DEBUGPRINT("\nIn thread %x:\n"
76 "%s:%d: %s: Assertion '%s' failed.\n",
77 (unsigned int)get_current_thread_id(),
78 file, line, function, assertion);
83 fclose(g_debugstreams[1]);
94 DebugStack::DebugStack(threadid_t id)
101 void DebugStack::print(FILE *file, bool everything)
103 fprintf(file, "DEBUG STACK FOR THREAD %x:\n",
104 (unsigned int)threadid);
106 for(int i=0; i<stack_max_i; i++)
108 if(i == stack_i && everything == false)
112 fprintf(file, "#%d %s\n", i, stack[i]);
114 fprintf(file, "(Leftover data: #%d %s)\n", i, stack[i]);
117 if(stack_i == DEBUG_STACK_SIZE)
118 fprintf(file, "Probably overflown.\n");
122 core::map<threadid_t, DebugStack*> g_debug_stacks;
123 JMutex g_debug_stacks_mutex;
125 void debug_stacks_init()
127 g_debug_stacks_mutex.Init();
130 void debug_stacks_print()
132 JMutexAutoLock lock(g_debug_stacks_mutex);
134 DEBUGPRINT("Debug stacks:\n");
136 for(core::map<threadid_t, DebugStack*>::Iterator
137 i = g_debug_stacks.getIterator();
138 i.atEnd() == false; i++)
140 DebugStack *stack = i.getNode()->getValue();
142 for(int i=0; i<DEBUGSTREAM_COUNT; i++)
144 if(g_debugstreams[i] != NULL)
145 stack->print(g_debugstreams[i], true);
150 DebugStacker::DebugStacker(const char *text)
152 threadid_t threadid = get_current_thread_id();
154 JMutexAutoLock lock(g_debug_stacks_mutex);
156 core::map<threadid_t, DebugStack*>::Node *n;
157 n = g_debug_stacks.find(threadid);
160 m_stack = n->getValue();
164 /*DEBUGPRINT("Creating new debug stack for thread %x\n",
165 (unsigned int)threadid);*/
166 m_stack = new DebugStack(threadid);
167 g_debug_stacks.insert(threadid, m_stack);
170 if(m_stack->stack_i >= DEBUG_STACK_SIZE)
176 m_overflowed = false;
178 snprintf(m_stack->stack[m_stack->stack_i],
179 DEBUG_STACK_TEXT_SIZE, "%s", text);
181 if(m_stack->stack_i > m_stack->stack_max_i)
182 m_stack->stack_max_i = m_stack->stack_i;
186 DebugStacker::~DebugStacker()
188 JMutexAutoLock lock(g_debug_stacks_mutex);
190 if(m_overflowed == true)
195 if(m_stack->stack_i == 0)
197 threadid_t threadid = m_stack->threadid;
198 /*DEBUGPRINT("Deleting debug stack for thread %x\n",
199 (unsigned int)threadid);*/
201 g_debug_stacks.remove(threadid);