2 (c) 2010 Perttu Ahola <celeron55@gmail.com>
6 Debug stack and assertion
14 #include <jmutexautolock.h>
16 #include "common_irrlicht.h"
22 #if (defined(WIN32) || defined(_WIN32_WCE))
23 typedef DWORD threadid_t;
24 #define __NORETURN __declspec(noreturn)
25 #define __FUNCTION_NAME __FUNCTION__
27 typedef pthread_t threadid_t;
28 #define __NORETURN __attribute__ ((__noreturn__))
29 #define __FUNCTION_NAME __PRETTY_FUNCTION__
32 inline threadid_t get_current_thread_id()
34 #if (defined(WIN32) || defined(_WIN32_WCE))
35 return GetCurrentThreadId();
37 return pthread_self();
45 #define DEBUGSTREAM_COUNT 2
47 extern FILE *g_debugstreams[DEBUGSTREAM_COUNT];
49 extern void debugstreams_init(bool disable_stderr, const char *filename);
50 extern void debugstreams_deinit();
52 #define DEBUGPRINT(...)\
54 for(int i=0; i<DEBUGSTREAM_COUNT; i++)\
56 if(g_debugstreams[i] != NULL){\
57 fprintf(g_debugstreams[i], __VA_ARGS__);\
58 fflush(g_debugstreams[i]);\
63 class Debugbuf : public std::streambuf
66 Debugbuf(bool disable_stderr)
68 m_disable_stderr = disable_stderr;
73 for(int i=0; i<DEBUGSTREAM_COUNT; i++)
75 if(g_debugstreams[i] == stderr && m_disable_stderr)
77 if(g_debugstreams[i] != NULL)
78 fwrite(&c, 1, 1, g_debugstreams[i]);
80 fflush(g_debugstreams[i]);
85 int xsputn(const char *s, int n)
87 for(int i=0; i<DEBUGSTREAM_COUNT; i++)
89 if(g_debugstreams[i] == stderr && m_disable_stderr)
91 if(g_debugstreams[i] != NULL)
92 fwrite(s, 1, n, g_debugstreams[i]);
94 fflush(g_debugstreams[i]);
101 bool m_disable_stderr;
104 // This is used to redirect output to /dev/null
105 class Nullstream : public std::ostream {
114 extern Debugbuf debugbuf;
115 extern std::ostream dstream;
116 extern std::ostream dstream_no_stderr;
117 extern Nullstream dummyout;
123 __NORETURN extern void assert_fail(
124 const char *assertion, const char *file,
125 unsigned int line, const char *function);
127 #define ASSERT(expr)\
130 : assert_fail(#expr, __FILE__, __LINE__, __FUNCTION_NAME))
132 #define assert(expr) ASSERT(expr)
138 #define DEBUG_STACK_SIZE 50
139 #define DEBUG_STACK_TEXT_SIZE 300
143 DebugStack(threadid_t id);
144 void print(FILE *file, bool everything);
147 char stack[DEBUG_STACK_SIZE][DEBUG_STACK_TEXT_SIZE];
148 int stack_i; // Points to the lowest empty position
149 int stack_max_i; // Highest i that was seen
152 extern core::map<threadid_t, DebugStack*> g_debug_stacks;
153 extern JMutex g_debug_stacks_mutex;
155 extern void debug_stacks_init();
156 extern void debug_stacks_print();
161 DebugStacker(const char *text);
170 char __buf[DEBUG_STACK_TEXT_SIZE];\
172 DEBUG_STACK_TEXT_SIZE, __VA_ARGS__);\
173 DebugStacker __debug_stacker(__buf);