debug.h 12 KB

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