Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

282 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. debug.h
  5. Abstract:
  6. Debugging support for the DirSync project. None of these
  7. generate any code in the retail build.
  8. Environment:
  9. User mode
  10. Revision History:
  11. 03/18/98 -srinivac-
  12. Created it
  13. --*/
  14. #ifndef _DEBUG_H_
  15. #define _DEBUG_H_
  16. #ifdef __cplusplus
  17. extern "C" {
  18. #endif
  19. #if DBG
  20. //
  21. // External functions
  22. //
  23. STDAPI_(PCSTR) StripDirPrefixA(PCSTR);
  24. //
  25. // This variable maintains the current debug level. Any calls to generate
  26. // debug messages succeeds if the requested level is greater than or equal
  27. // to the current level.
  28. //
  29. extern DWORD gdwDebugLevel;
  30. //
  31. // List of debug levels for gdwDebugLevel
  32. //
  33. #define DBG_LEVEL_VERBOSE 0x00000001
  34. #define DBG_LEVEL_INFO 0x00000002
  35. #define DBG_LEVEL_WARNING 0x00000003
  36. #define DBG_LEVEL_ERROR 0x00000004
  37. //
  38. // Internal macros. Don't call these directly
  39. //
  40. #define CHECK_DBG_LEVEL(level) ((level) >= gdwDebugLevel)
  41. #define DBGMSG(level, msg) \
  42. { \
  43. if (CHECK_DBG_LEVEL(level)) \
  44. { \
  45. DbgPrint("DirSync(%d): %s(%u): ", \
  46. GetCurrentThreadId(), \
  47. StripDirPrefixA(__FILE__), __LINE__); \
  48. DbgPrint msg; \
  49. } \
  50. }
  51. #define DBGPRINT(level, msg) \
  52. { \
  53. if (CHECK_DBG_LEVEL(level)) \
  54. { \
  55. DbgPrint msg; \
  56. } \
  57. }
  58. //
  59. // These are the main macros that you'll be using in your code.
  60. // Note that you should enclose the msg in additional
  61. // paranthesis as shown in the example below.
  62. //
  63. // WARNING(("Out of memory"));
  64. // ERR(("Incorrect return value: %d", rc));
  65. //
  66. #define VERBOSE(msg) DBGMSG(DBG_LEVEL_VERBOSE, msg)
  67. #define INFO(msg) DBGMSG(DBG_LEVEL_INFO, msg)
  68. #define WARNING(msg) DBGMSG(DBG_LEVEL_WARNING, msg)
  69. #define ERR(msg) DBGMSG(DBG_LEVEL_ERROR, msg)
  70. #define ERR_RIP(msg) DBGMSG(DBG_LEVEL_ERROR, msg);RIP()
  71. #define RIP() DebugBreak()
  72. #define DEBUGOUT(msg) DbgPrint msg
  73. //
  74. // These macros are used for asserting certain conditions. They are
  75. // independent of the debugging level.
  76. // These also require additional paranthesis to enclose the msg as
  77. // shown below.
  78. //
  79. // ASSERT(x > 0);
  80. // ASSERTMSG(x > 0, ("x less than 0: x=%d", x));
  81. //
  82. #ifdef ASSERT
  83. #undef ASSERT
  84. #undef ASSERTMSG
  85. #endif
  86. #define ASSERT(expr) \
  87. { \
  88. if (!(expr)) \
  89. { \
  90. DbgPrint("DirSync(%d): Assert: %s(%u)\n", \
  91. GetCurrentThreadId(), \
  92. StripDirPrefixA(__FILE__), __LINE__); \
  93. DebugBreak(); \
  94. } \
  95. }
  96. #define ASSERTMSG(expr, msg) \
  97. { \
  98. if (!(expr)) \
  99. { \
  100. DbgPrint("DirSync(%d): Assert: %s(%u)\n", \
  101. GetCurrentThreadId(), \
  102. StripDirPrefixA(__FILE__), __LINE__); \
  103. DbgPrint msg; \
  104. DbgPrint("\n"); \
  105. DebugBreak(); \
  106. } \
  107. }
  108. #else // !DBG
  109. #define DBGMSG(level, msg)
  110. #define VERBOSE(msg)
  111. #define INFO(msg)
  112. #define WARNING(msg)
  113. #define ERR(msg)
  114. #define ERR_RIP(msg)
  115. #define RIP()
  116. #define DEBUGOUT(msg)
  117. #define ASSERT(expr)
  118. #define ASSERTMSG(expr, msg)
  119. #endif
  120. //
  121. // The following macros let you enable debugging on a per feature basis.
  122. // To use these macros, here is what you should do:
  123. //
  124. // At the beginning of the file (after header includes):
  125. //
  126. // 1. Define a bit constant for each capability you want to debug
  127. // 2. For each feature, add the following line
  128. // DEFINE_FEATURE_FLAGS(featurename, flags);
  129. // where flags is a bit-wise OR of the capabilities you want to debug for
  130. // that feature
  131. // 3. In your code add the following line wherever you want debug messages
  132. // FEATURE_DEBUG(featurename, flag, (msg));
  133. //
  134. // E.g. let us say I am implementing a memory manager, and I would like to
  135. // trace memory allocations and frees. Here is what I would do
  136. //
  137. // #define FLAG_ALLOCATE 1
  138. // #define FLAG_FREE 2
  139. //
  140. // DEFINE_FEATURE_FLAGS(MemMgr, FLAG_ALLOCATE);
  141. //
  142. // void *MemAlloc(DWORD dwSize)
  143. // {
  144. // FEATURE_DEBUG(MemMgr, FLAG_ALLOCATE, ("Memory of size %d allocated", dwSize));
  145. // ...
  146. // }
  147. //
  148. // void MemFree(void *pvMem)
  149. // {
  150. // FEATURE_DEBUG(MemMgr, FKAG_FREE, ("Memory freed"));
  151. // ...
  152. // }
  153. //
  154. // Note that I have set this up to send only alloc messages to the debugger,
  155. // but I can break into the debugger and modify dwMemMgrDbgFlags to
  156. // send free messages as well.
  157. //
  158. // Once component testing of a feature is completed, flags parameter in
  159. // DEFINE_FEATURE_FLAGS should be changed to 0, so by default this feature
  160. // does not send debug messages to the debugger.
  161. //
  162. #if DBG
  163. //
  164. // Global debug flag that can used to set values to all other flags
  165. //
  166. extern DWORD gdwGlobalDbgFlags;
  167. #define DEFINE_FEATURE_FLAGS(feature, flags) \
  168. DWORD gdw##feature##DbgFlags = (flags)
  169. #define EXTERN_FEATURE_FLAGS(feature) \
  170. extern DWORD gdw##feature##DbgFlags
  171. #define FEATURE_DEBUG(feature, flag, msg) \
  172. { \
  173. if (gdw##feature##DbgFlags & (flag) || \
  174. gdwGlobalDbgFlags & (flag)) \
  175. { \
  176. DbgPrint msg; \
  177. } \
  178. }
  179. #define FEATURE_DEBUG_FN(feature, flag, func) \
  180. { \
  181. if (gdw##feature##DbgFlags & (flag) || \
  182. gdwGlobalDbgFlags & (flag)) \
  183. { \
  184. func; \
  185. } \
  186. }
  187. #define FLAG_INFO 0x01
  188. #define FLAG_VERBOSE 0x02
  189. #define FLAG_FNTRACE 0x04
  190. #define FLAG_FULLTRACE 0xFFFF
  191. #else // !DBG
  192. #define DEFINE_FEATURE_FLAGS(feature, flags)
  193. #define EXTERN_FEATURE_FLAGS(feature)
  194. #define FEATURE_DEBUG(feature, flag, msg)
  195. #define FEATURE_DEBUG_FN(feature, flag, func)
  196. #endif // !DBG
  197. //
  198. // Macros for error handling
  199. //
  200. #define BAIL_ON_FAILURE(hr) \
  201. if (FAILED(hr)) \
  202. { \
  203. goto error; \
  204. }
  205. #define BAIL_ON_FAILURE_WITH_MSG(err, msg) \
  206. if (FAILED(hr)) \
  207. { \
  208. ERR(msg); \
  209. goto error; \
  210. }
  211. #define BAIL_ON_NULL(ptr) \
  212. if ((ptr) == NULL) \
  213. { \
  214. ERR(("Error allocating memory\n")); \
  215. hr = E_OUTOFMEMORY; \
  216. goto error; \
  217. }
  218. #define BAIL() goto error
  219. #ifdef __cplusplus
  220. }
  221. #endif
  222. #endif // ifndef _DEBUG_H_