00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef GROOVX_RUTZ_DEBUG_CC_UTC20050626084020_DEFINED
00035 #define GROOVX_RUTZ_DEBUG_CC_UTC20050626084020_DEFINED
00036
00037 #include "rutz/debug.h"
00038 GVX_DBG_REGISTER
00039
00040 #include "rutz/backtrace.h"
00041 #include "rutz/mutex.h"
00042
00043 #include <cstdlib>
00044 #include <cstring>
00045 #include <iomanip>
00046 #include <iostream>
00047
00048 #include <cstdio>
00049 #include <cerrno>
00050
00051 namespace
00052 {
00053 const int MAX_KEYS = 1024;
00054
00055
00056 bool g_debug_line_complete = true;
00057 pthread_mutex_t g_debug_output_mutex = PTHREAD_MUTEX_INITIALIZER;
00058
00059
00060 int g_debug_next_key = 0;
00061 unsigned char g_key_levels[MAX_KEYS];
00062 const char* g_key_filenames[MAX_KEYS];
00063 pthread_mutex_t g_debug_keys_mutex = PTHREAD_MUTEX_INITIALIZER;
00064
00065 void show_position(int level, const char* where, int line_no) throw()
00066 {
00067 std::cerr << "[" << std::setw(2) << level << "] "
00068 << std::setw(20) << where << ":"
00069 << line_no << ": ";
00070 }
00071 }
00072
00073 #define EVAL_IMPL(T) \
00074 void rutz::debug::eval(const char* what, int level, \
00075 const char* where, int line_no, \
00076 bool nl, T expr) throw() \
00077 { \
00078 GVX_MUTEX_LOCK(&g_debug_output_mutex); \
00079 using std::cerr; \
00080 cerr.exceptions(std::ios::goodbit); \
00081 if (g_debug_line_complete) \
00082 { \
00083 show_position(level, where, line_no); \
00084 } \
00085 if (what) \
00086 { \
00087 cerr << "(" << #T << ") " << what << " = "; \
00088 } \
00089 cerr << expr; \
00090 if (nl) \
00091 { \
00092 cerr << "\n"; \
00093 g_debug_line_complete = true; \
00094 } \
00095 else \
00096 { \
00097 cerr << ", "; \
00098 g_debug_line_complete = false; \
00099 } \
00100 }
00101
00102 EVAL_IMPL(bool);
00103 EVAL_IMPL(char);
00104 EVAL_IMPL(unsigned char);
00105 EVAL_IMPL(short);
00106 EVAL_IMPL(unsigned short);
00107 EVAL_IMPL(int);
00108 EVAL_IMPL(unsigned int);
00109 EVAL_IMPL(long);
00110 EVAL_IMPL(unsigned long);
00111 EVAL_IMPL(float);
00112 EVAL_IMPL(double);
00113 EVAL_IMPL(const char*);
00114 EVAL_IMPL(void*);
00115
00116 void rutz::debug::dump(const char* what, int level, const char* where, int line_no) throw()
00117 {
00118 GVX_MUTEX_LOCK(&g_debug_output_mutex);
00119 std::cerr.exceptions(std::ios::goodbit);
00120 show_position(level, where, line_no);
00121 std::cerr << std::setw(15) << what << " := ";
00122 g_debug_line_complete = false;
00123 }
00124
00125 void rutz::debug::start_newline() throw()
00126 {
00127 GVX_MUTEX_LOCK(&g_debug_output_mutex);
00128 std::cerr.exceptions(std::ios::goodbit);
00129 if (!g_debug_line_complete)
00130 {
00131 std::cerr << '\n';
00132 g_debug_line_complete = true;
00133 }
00134 }
00135
00136 void rutz::debug::panic_aux(const char* what, const char* where,
00137 int line_no) throw()
00138 {
00139 fprintf(stderr, "Panic (%s:%d):\n\t%s\n\n",
00140 where, line_no, what);
00141 rutz::backtrace::current().print();
00142 abort();
00143 }
00144
00145 void rutz::debug::assert_aux(const char* what, const char* where,
00146 int line_no) throw()
00147 {
00148 fprintf(stderr, "Assertion failed (%s:%d):\n\texpected '%s'\n\n",
00149 where, line_no, what);
00150 rutz::backtrace::current().print();
00151 abort();
00152 }
00153
00154 void rutz::debug::precondition_aux(const char* what, const char* where,
00155 int line_no) throw()
00156 {
00157 fprintf(stderr, "Precondition failed (%s:%d):\n\texpected '%s'\n\n",
00158 where, line_no, what);
00159 rutz::backtrace::current().print();
00160 abort();
00161 }
00162
00163 void rutz::debug::postcondition_aux(const char* what, const char* where,
00164 int line_no) throw()
00165 {
00166 fprintf(stderr, "Postcondition failed (%s:%d):\n\texpected '%s'\n\n",
00167 where, line_no, what);
00168 rutz::backtrace::current().print();
00169 abort();
00170 }
00171
00172 void rutz::debug::invariant_aux(const char* what, const char* where,
00173 int line_no) throw()
00174 {
00175 fprintf(stderr, "Invariant failed (%s:%d):\n\texpected '%s'\n\n",
00176 where, line_no, what);
00177 rutz::backtrace::current().print();
00178 abort();
00179 }
00180
00181 int rutz::debug::create_key(const char* filename)
00182 {
00183 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00184 const int key = g_debug_next_key;
00185 g_key_filenames[key] = filename;
00186 if (g_debug_next_key < (MAX_KEYS-1))
00187 ++g_debug_next_key;
00188 return key;
00189 }
00190
00191 bool rutz::debug::is_valid_key(int key)
00192 {
00193 return key >= 0 && key < MAX_KEYS;
00194 }
00195
00196 int rutz::debug::lookup_key(const char* filename)
00197 {
00198 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00199 for (int i = 0; i < g_debug_next_key; ++i)
00200 {
00201 if (strcmp(g_key_filenames[i], filename) == 0)
00202 return i;
00203 }
00204 return -1;
00205 }
00206
00207 int rutz::debug::get_level_for_key(int key)
00208 {
00209 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00210 if (key < MAX_KEYS)
00211 return g_key_levels[key];
00212 return 0;
00213 }
00214
00215 void rutz::debug::set_level_for_key(int key, int level)
00216 {
00217 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00218 if (key <MAX_KEYS)
00219 g_key_levels[key] = level;
00220 }
00221
00222 const char* rutz::debug::get_filename_for_key(int key)
00223 {
00224 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00225 return g_key_filenames[key];
00226 }
00227
00228 void rutz::debug::set_global_level(int lev)
00229 {
00230 GVX_MUTEX_LOCK(&g_debug_keys_mutex);
00231 for (int i = 0; i < MAX_KEYS; ++i)
00232 g_key_levels[i] = (unsigned char) lev;
00233 }
00234
00235 static const char __attribute__((used)) vcid_groovx_rutz_debug_cc_utc20050626084020[] = "$Id: debug.cc 12074 2009-11-24 07:51:51Z itti $ $HeadURL: svn:
00236 #endif // !GROOVX_RUTZ_DEBUG_CC_UTC20050626084020_DEFINED