1 /* 2 (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) 3 (c) Copyright 2000-2004 Convergence (integrated media) GmbH 4 5 All rights reserved. 6 7 Written by Denis Oliver Kropp <dok@directfb.org>, 8 Andreas Hundt <andi@fischlustig.de>, 9 Sven Neumann <neo@directfb.org>, 10 Ville Syrjälä <syrjala@sci.fi> and 11 Claudio Ciccani <klan@users.sf.net>. 12 13 This library is free software; you can redistribute it and/or 14 modify it under the terms of the GNU Lesser General Public 15 License as published by the Free Software Foundation; either 16 version 2 of the License, or (at your option) any later version. 17 18 This library is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 Lesser General Public License for more details. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this library; if not, write to the 25 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 26 Boston, MA 02111-1307, USA. 27 */ 28 29 #ifndef __DIRECT__DEBUG_H__ 30 #define __DIRECT__DEBUG_H__ 31 32 #include <direct/build.h> 33 34 #include <stdio.h> 35 #include <errno.h> 36 37 #include <direct/clock.h> 38 #include <direct/conf.h> 39 #include <direct/log.h> 40 #include <direct/messages.h> 41 #include <direct/system.h> 42 #include <direct/thread.h> 43 #include <direct/trace.h> 44 #include <direct/types.h> 45 46 47 typedef struct { 48 unsigned int age; 49 bool enabled; 50 bool registered; 51 52 const char *name; 53 const char *description; 54 55 int name_len; 56 } DirectDebugDomain; 57 58 void direct_debug_config_domain( const char *name, bool enable ); 59 60 bool direct_debug_check_domain( DirectDebugDomain *domain ); 61 62 63 #if DIRECT_BUILD_TEXT 64 65 #define D_DEBUG_DOMAIN(identifier,name,description) \ 66 static DirectDebugDomain identifier __attribute__((unused)) \ 67 = { 0, false, false, name, description, sizeof(name) - 1 } 68 69 void direct_debug_at_always( DirectDebugDomain *domain, 70 const char *format, ... ) D_FORMAT_PRINTF(2); 71 72 #define d_debug_at( domain, ... ) direct_debug_at_always( &domain, __VA_ARGS__ ) 73 74 75 #if DIRECT_BUILD_DEBUGS 76 77 void direct_debug( const char *format, ... ) D_FORMAT_PRINTF(1); 78 79 void direct_debug_at( DirectDebugDomain *domain, 80 const char *format, ... ) D_FORMAT_PRINTF(2); 81 82 void direct_debug_enter( DirectDebugDomain *domain, 83 const char *func, 84 const char *file, 85 int line, 86 const char *format, ... ) D_FORMAT_PRINTF(5); 87 88 void direct_debug_exit( DirectDebugDomain *domain, 89 const char *func, 90 const char *file, 91 int line, 92 const char *format, ... ) D_FORMAT_PRINTF(5); 93 94 void direct_break( const char *func, 95 const char *file, 96 int line, 97 const char *format, ... ) D_FORMAT_PRINTF(4); 98 99 void direct_assertion( const char *exp, 100 const char *func, 101 const char *file, 102 int line ); 103 104 void direct_assumption( const char *exp, 105 const char *func, 106 const char *file, 107 int line ); 108 #endif 109 110 #if DIRECT_BUILD_DEBUG || defined(DIRECT_ENABLE_DEBUG) || defined(DIRECT_FORCE_DEBUG) 111 112 #define D_DEBUG_ENABLED (1) 113 114 #define D_DEBUG(...) \ 115 do { \ 116 if (!direct_config || direct_config->debug) \ 117 direct_debug( __VA_ARGS__ ); \ 118 } while (0) 119 120 121 #define D_DEBUG_AT(d,...) \ 122 do { \ 123 direct_debug_at( &d, __VA_ARGS__ ); \ 124 } while (0) 125 126 #define D_DEBUG_ENTER(d,...) \ 127 do { \ 128 direct_debug_enter( &d, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__ ); \ 129 } while (0) 130 131 #define D_DEBUG_EXIT(d,...) \ 132 do { \ 133 direct_debug_exit( &d, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__ ); \ 134 } while (0) 135 136 #define D_ASSERT(exp) \ 137 do { \ 138 if (!(exp)) \ 139 direct_assertion( #exp, __FUNCTION__, __FILE__, __LINE__ ); \ 140 } while (0) 141 142 143 #define D_ASSUME(exp) \ 144 do { \ 145 if (!(exp)) \ 146 direct_assumption( #exp, __FUNCTION__, __FILE__, __LINE__ ); \ 147 } while (0) 148 149 150 #define D_BREAK(...) \ 151 do { \ 152 direct_break( __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__ ); \ 153 } while (0) 154 155 #define D_DEBUG_CHECK(d) \ 156 direct_debug_check_domain( &d ) 157 158 #elif defined(DIRECT_MINI_DEBUG) 159 160 /* 161 * Mini debug mode, only D_DEBUG_AT, no domain filters, simple assertion 162 */ 163 164 #define D_DEBUG_ENABLED (2) 165 166 #define D_DEBUG_AT(d,...) \ 167 do { \ 168 if (direct_config->debug) direct_debug_at_always( &d, __VA_ARGS__ ); \ 169 } while (0) 170 171 #define D_CHECK(exp, aa) \ 172 do { \ 173 if (!(exp)) { \ 174 long long millis = direct_clock_get_millis(); \ 175 const char *name = direct_thread_self_name(); \ 176 \ 177 direct_log_printf( NULL, \ 178 "(!) [%-15s %3lld.%03lld] (%5d) *** " #aa " [%s] failed *** [%s:%d in %s()]\n", \ 179 name ? name : " NO NAME ", millis / 1000LL, millis % 1000LL, \ 180 direct_gettid(), #exp, __FILE__, __LINE__, __FUNCTION__ ); \ 181 \ 182 direct_trace_print_stack( NULL ); \ 183 } \ 184 } while (0) 185 186 #define D_ASSERT(exp) D_CHECK(exp, Assertion) 187 #define D_ASSUME(exp) D_CHECK(exp, Assumption) 188 189 #define D_DEBUG_CHECK(d) \ 190 direct_config->debug 191 192 #endif /* MINI_DEBUG / DIRECT_BUILD_DEBUG || DIRECT_ENABLE_DEBUG || DIRECT_FORCE_DEBUG */ 193 194 #endif /* DIRECT_BUILD_TEXT */ 195 196 197 /* 198 * Fallback definitions, e.g. without DIRECT_BUILD_TEXT or DIRECT_ENABLE_DEBUG 199 */ 200 201 #ifndef D_DEBUG_ENABLED 202 #define D_DEBUG_ENABLED (0) 203 #endif 204 205 #ifndef D_DEBUG 206 #define D_DEBUG(...) do {} while (0) 207 #endif 208 209 #ifndef D_DEBUG_AT 210 #define D_DEBUG_AT(d,...) do {} while (0) 211 #endif 212 213 #ifndef D_DEBUG_ENTER 214 #define D_DEBUG_ENTER(d,...) do {} while (0) 215 #endif 216 217 #ifndef D_DEBUG_EXIT 218 #define D_DEBUG_EXIT(d,...) do {} while (0) 219 #endif 220 221 #ifndef D_ASSERT 222 #define D_ASSERT(exp) do {} while (0) 223 #endif 224 225 #ifndef D_ASSUME 226 #define D_ASSUME(exp) do {} while (0) 227 #endif 228 229 #ifndef D_DEBUG_CHECK 230 #define D_DEBUG_CHECK(d) false 231 #endif 232 233 #ifndef D_BREAK 234 #define D_BREAK(...) do {} while (0) 235 #endif 236 237 #ifndef d_debug_at 238 #define d_debug_at( domain, ... ) do {} while (0) 239 #endif 240 241 #ifndef D_DEBUG_DOMAIN 242 #define D_DEBUG_DOMAIN(i,n,d) 243 #endif 244 245 246 247 /* 248 * Magic Assertions & Utilities 249 */ 250 251 #define D_MAGIC(spell) ( (((spell)[sizeof(spell)*8/9] << 24) | \ 252 ((spell)[sizeof(spell)*7/9] << 16) | \ 253 ((spell)[sizeof(spell)*6/9] << 8) | \ 254 ((spell)[sizeof(spell)*5/9] )) ^ \ 255 (((spell)[sizeof(spell)*4/9] << 24) | \ 256 ((spell)[sizeof(spell)*3/9] << 16) | \ 257 ((spell)[sizeof(spell)*2/9] << 8) | \ 258 ((spell)[sizeof(spell)*1/9] )) ) 259 260 261 #define D_MAGIC_SET(o,m) do { \ 262 D_ASSERT( (o) != NULL ); \ 263 D_ASSUME( (o)->magic != D_MAGIC(#m) ); \ 264 \ 265 (o)->magic = D_MAGIC(#m); \ 266 } while (0) 267 268 #define D_MAGIC_SET_ONLY(o,m) do { \ 269 D_ASSERT( (o) != NULL ); \ 270 \ 271 (o)->magic = D_MAGIC(#m); \ 272 } while (0) 273 274 #define D_MAGIC_ASSERT(o,m) do { \ 275 D_ASSERT( (o) != NULL ); \ 276 D_ASSERT( (o)->magic == D_MAGIC(#m) ); \ 277 } while (0) 278 279 #define D_MAGIC_ASSUME(o,m) do { \ 280 D_ASSUME( (o) != NULL ); \ 281 if (o) \ 282 D_ASSUME( (o)->magic == D_MAGIC(#m) ); \ 283 } while (0) 284 285 #define D_MAGIC_ASSERT_IF(o,m) do { \ 286 if (o) \ 287 D_ASSERT( (o)->magic == D_MAGIC(#m) ); \ 288 } while (0) 289 290 #define D_MAGIC_CLEAR(o) do { \ 291 D_ASSERT( (o) != NULL ); \ 292 D_ASSUME( (o)->magic != 0 ); \ 293 \ 294 (o)->magic = 0; \ 295 } while (0) 296 297 298 #endif 299 300