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.

315 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. Debug.h
  6. Abstract:
  7. New debug services for spooler.
  8. Author:
  9. Albert Ting (AlbertT) 15-Jan-1995
  10. Revision History:
  11. --*/
  12. #ifndef _DBGLOG_H
  13. #define _DBGLOG_H
  14. /********************************************************************
  15. Setting up the debug support:
  16. =============================
  17. Define a MODULE prefix string. Since this will be printed as
  18. a prefix to all debug output, it should be concise and unique.
  19. In your global header file:
  20. #define MODULE "prtlib:"
  21. Define a MODULE_DEBUG variable. This is the actual symbol
  22. that the library will use to indicate debugging level.
  23. This DWORD is broken into two bitfield WORDs: the low word
  24. indicates which levels to print to the debugger; the high word
  25. breaks into the debugger. The library takes the DebugLevel from
  26. a debug message, then ANDs it with the debug level. If the bit
  27. is on, the corresponding action (print or break) is taken.
  28. In your global header file:
  29. #define MODULE_DEBUG PrtlibDebug
  30. Finally, the actual debug variable must be defined and initialized
  31. to a default debug level. This must be done in exactly one
  32. *.c translation unit:
  33. In one of your source files:
  34. MODULE_DEBUG_INIT ( {LevelsToPrint}, {LevelsToBreak} );
  35. Adding logging to source code:
  36. ==============================
  37. The general format for debug message is:
  38. DBGMSG( {DebugLevel}, ( {args to printf} ));
  39. The DebugLevel dictates whether the level should print, break
  40. into the debugger, or just log to memory (logging always done).
  41. The args to printf must be placed in an extra set of parens,
  42. and should assume everything is ANSI. To print LPTSTRs, use
  43. the TSTR macro:
  44. DBGMSG( DBG_WARN,
  45. ( "LPTSTR "TSTR", LPSTR %s, LPWSTR %ws\n",
  46. TEXT("hello"), "hello", L"hello" ));
  47. Viewing DBGMSGs:
  48. ================
  49. Messages will print to the debugger (usermode, or kernel debugger
  50. if no usermode debugger is available) for all printable levels.
  51. To change the level, you can edit the MODULE_DEBUG variable
  52. (PrtlibDebug in the above example).
  53. By default, DBG_ERROR and DBG_WARNING messages a logged to the
  54. error log (stored at gpbterrlog). All others are stored in the
  55. trace log (gpbttracelog). These currently log to memory in
  56. a circular buffer. Use the splx.dll extension to dump these
  57. logs.
  58. At compile time, you can switch these logs to go to file rather
  59. than memory. They will be stored as the PID + index number in
  60. the default directory of the process.
  61. ********************************************************************/
  62. #ifdef __cplusplus
  63. extern "C" {
  64. #endif
  65. //
  66. // These values are strictly debug, but must be defined in the free
  67. // build because the TStatus error checking uses them as the first ctr
  68. // parameter. (During inlining they are discarded.)
  69. //
  70. #define DBG_NONE 0x0000
  71. #define DBG_INFO 0x0001
  72. #define DBG_WARN 0x0002
  73. #define DBG_WARNING 0x0002
  74. #define DBG_ERROR 0x0004
  75. #define DBG_TRACE 0x0008
  76. #define DBG_SECURITY 0x0010
  77. #define DBG_EXEC 0x0020
  78. #define DBG_PORT 0x0040
  79. #define DBG_NOTIFY 0x0080
  80. #define DBG_PAUSE 0x0100
  81. #define DBG_THREADM 0x0400
  82. #define DBG_MIN 0x0800
  83. #define DBG_TIME 0x1000
  84. #define DBG_FOLDER 0x2000
  85. #define DBG_NOHEAD 0x8000
  86. #if DBG
  87. extern DWORD MODULE_DEBUG;
  88. //
  89. // This should be used exactly once in a C file. It defines
  90. // the Debug variable, and also the DbgMsg function.
  91. //
  92. // If we are statically linking with SplLib (SplLib is a library, not
  93. // a Dll), then we will get the definition from SplLib, so don't define
  94. // it here.
  95. //
  96. #ifdef LINK_SPLLIB
  97. #define MODULE_DEBUG_INIT( print, break ) \
  98. DWORD MODULE_DEBUG = (DBG_PRINT( print ) | DBG_BREAK( break ))
  99. #else
  100. #define MODULE_DEBUG_INIT( print, break ) \
  101. VOID \
  102. DbgMsg( \
  103. LPCSTR pszMsgFormat, \
  104. ... \
  105. ) \
  106. { \
  107. CHAR szMsgText[1024]; \
  108. va_list vargs; \
  109. \
  110. va_start( vargs, pszMsgFormat ); \
  111. wvsprintfA( szMsgText, pszMsgFormat, vargs ); \
  112. va_end( vargs ); \
  113. \
  114. if( szMsgText[0] && szMsgText[0] != ' ' ){ \
  115. OutputDebugStringA( MODULE ); \
  116. } \
  117. OutputDebugStringA( szMsgText ); \
  118. } \
  119. DWORD MODULE_DEBUG = (DBG_PRINT( print ) | DBG_BREAK( break ))
  120. #endif
  121. #define DBGSTR( str ) \
  122. ((str) ? (str) : TEXT("(NULL)"))
  123. #ifdef UNICODE
  124. #define TSTR "%ws"
  125. #else
  126. #define TSTR "%s"
  127. #endif
  128. #define DBG_PRINT_MASK 0xffff
  129. #define DBG_BREAK_SHIFT 16
  130. #define DBG_PRINT(x) (x)
  131. #define DBG_BREAK(x) (((x) << DBG_BREAK_SHIFT)|(x))
  132. #define SPLASSERT(expr) \
  133. if (!(expr)) { \
  134. DbgMsg( "Failed: %s\nLine %d, %s\n", \
  135. #expr, \
  136. __LINE__, \
  137. __FILE__ ); \
  138. DebugBreak(); \
  139. }
  140. VOID
  141. vDbgSingleThreadReset(
  142. PDWORD pdwThreadId
  143. );
  144. VOID
  145. vDbgSingleThread(
  146. PDWORD pdwThreadId
  147. );
  148. VOID
  149. vDbgSingleThreadNot(
  150. PDWORD pdwThreadId
  151. );
  152. VOID
  153. DbgMsg(
  154. LPCSTR pszMsgFormat,
  155. ...
  156. );
  157. #ifdef DBGLOG
  158. #define DBGMSG( uDbgLevel, argsPrint ) \
  159. vDbgLogError( MODULE_DEBUG, \
  160. uDbgLevel, \
  161. __LINE__, \
  162. __FILE__, \
  163. MODULE, \
  164. pszDbgAllocMsgA argsPrint )
  165. LPSTR
  166. pszDbgAllocMsgA(
  167. LPCSTR pszMsgFormatA,
  168. ...
  169. );
  170. VOID
  171. vDbgLogError(
  172. UINT uDbg,
  173. UINT uDbgLevel,
  174. UINT uLine,
  175. LPCSTR pszFileA,
  176. LPCSTR pszModuleA,
  177. LPCSTR pszMsgA
  178. );
  179. #else
  180. VOID
  181. DbgBreakPoint(
  182. VOID
  183. );
  184. #define DBGMSG( Level, MsgAndArgs ) \
  185. { \
  186. if( ( (Level) & 0xFFFF ) & MODULE_DEBUG ){ \
  187. DbgMsg MsgAndArgs; \
  188. } \
  189. if( ( (Level) << 16 ) & MODULE_DEBUG ) \
  190. DbgBreakPoint(); \
  191. }
  192. #endif
  193. #define SINGLETHREAD_VAR(var) \
  194. DWORD dwSingleThread_##var
  195. #define SINGLETHREAD(var) \
  196. vDbgSingleThread(&dwSingleThread_##var)
  197. #define SINGLETHREADNOT(var) \
  198. vDbgSingleThreadNot(&dwSingleThread_##var)
  199. #define SINGLETHREADRESET(var) \
  200. vDbgSingleThreadReset(&dwSingleThread_##var)
  201. #else
  202. #define MODULE_DEBUG_INIT( print, break )
  203. #define DBGMSG( uDbgLevel, argsPrint )
  204. #define SPLASSERT(exp)
  205. #define SINGLETHREAD_VAR(var)
  206. #define SINGLETHREAD(var)
  207. #define SINGLETHREADNOT(var)
  208. #define SINGLETHREADRESET(var)
  209. #endif
  210. //
  211. // Automatic checking if an object is valid.
  212. //
  213. #if DBG
  214. VOID
  215. vWarnInvalid(
  216. PVOID pvObject,
  217. UINT uDbg,
  218. UINT uLine,
  219. LPCSTR pszFileA,
  220. LPCSTR pszModuleA
  221. );
  222. #define VALID_PTR(x) \
  223. ((( x ) && (( x )->bValid( ))) ? \
  224. TRUE : \
  225. ( vWarnInvalid( (PVOID)(x), MODULE_DEBUG, __LINE__, __FILE__, MODULE ), FALSE ))
  226. #define VALID_OBJ(x) \
  227. ((( x ).bValid( )) ? \
  228. TRUE : \
  229. ( vWarnInvalid( (PVOID)&(x), MODULE_DEBUG, __LINE__, __FILE__, MODULE ), FALSE ))
  230. #define VALID_BASE(x) \
  231. (( x::bValid( )) ? \
  232. TRUE : \
  233. ( vWarnInvalid( (PVOID)this, MODULE_DEBUG, __LINE__, __FILE__, MODULE ), FALSE ))
  234. #else
  235. #define VALID_PTR(x) \
  236. (( x ) && (( x )->bValid()))
  237. #define VALID_OBJ(x) \
  238. (( x ).bValid())
  239. #define VALID_BASE(x) \
  240. ( x::bValid( ))
  241. #endif
  242. #ifdef __cplusplus
  243. }
  244. #endif
  245. #endif // _DBGLOG_H