Leaked source code of windows server 2003
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.

434 lines
8.2 KiB

  1. // File: DebSpew.cpp
  2. #include "precomp.h"
  3. #include <confreg.h>
  4. #include <RegEntry.h>
  5. #ifdef DEBUG /* THE WHOLE FILE! */
  6. #if defined (_M_IX86)
  7. #define _DbgBreak() __asm { int 3 }
  8. #else
  9. #define _DbgBreak() DebugBreak()
  10. #endif
  11. /* Types
  12. ********/
  13. PCSTR g_pcszSpewModule = NULL;
  14. /* debug flags */
  15. typedef enum _debugdebugflags
  16. {
  17. DEBUG_DFL_ENABLE_TRACE_MESSAGES = 0x0001,
  18. DEBUG_DFL_LOG_TRACE_MESSAGES = 0x0002,
  19. DEBUG_DFL_ENABLE_CALL_TRACING = 0x0008,
  20. DEBUG_DFL_INDENT = 0x2000,
  21. ALL_DEBUG_DFLAGS = (DEBUG_DFL_ENABLE_TRACE_MESSAGES |
  22. DEBUG_DFL_LOG_TRACE_MESSAGES |
  23. DEBUG_DFL_ENABLE_CALL_TRACING |
  24. DEBUG_DFL_INDENT)
  25. }
  26. DEBUGDEBUGFLAGS;
  27. /* Global Variables
  28. *******************/
  29. #pragma data_seg(DATA_SEG_PER_INSTANCE)
  30. /* parameters used by SpewOut() */
  31. DWORD g_dwSpewFlags = 0;
  32. UINT g_uSpewSev = 0;
  33. UINT g_uSpewLine = 0;
  34. PCSTR g_pcszSpewFile = NULL;
  35. HDBGZONE ghDbgZone = NULL;
  36. /* TLS slot used to store stack depth for SpewOut() indentation */
  37. #ifdef _DBGSTACK
  38. DWORD s_dwStackDepthSlot = TLS_OUT_OF_INDEXES;
  39. /* hack stack depth counter used until s_dwStackDepthSlot is not available */
  40. ULONG_PTR s_ulcHackStackDepth = 0;
  41. #endif
  42. /* debug flags */
  43. DWORD s_dwDebugModuleFlags = 0;
  44. #pragma data_seg()
  45. /***************************** Private Functions *****************************/
  46. /* Module Prototypes
  47. ********************/
  48. BOOL IsValidSpewSev(UINT);
  49. /*
  50. ** IsValidSpewSev()
  51. **
  52. **
  53. **
  54. ** Arguments:
  55. **
  56. ** Returns:
  57. **
  58. ** Side Effects: none
  59. */
  60. BOOL IsValidSpewSev(UINT uSpewSev)
  61. {
  62. BOOL bResult;
  63. switch (uSpewSev)
  64. {
  65. case SPEW_TRACE:
  66. case SPEW_CALLTRACE:
  67. case SPEW_WARNING:
  68. case SPEW_ERROR:
  69. case SPEW_FATAL:
  70. bResult = TRUE;
  71. break;
  72. default:
  73. ERROR_OUT(("IsValidSpewSev(): Invalid debug spew severity %u.",
  74. uSpewSev));
  75. bResult = FALSE;
  76. break;
  77. }
  78. return(bResult);
  79. }
  80. /****************************** Public Functions *****************************/
  81. DWORD NMINTERNAL GetDebugOutputFlags(VOID)
  82. {
  83. return s_dwDebugModuleFlags;
  84. }
  85. VOID NMINTERNAL SetDebugOutputFlags(DWORD dw)
  86. {
  87. ASSERT(FLAGS_ARE_VALID(dw, ALL_DEBUG_DFLAGS));
  88. s_dwDebugModuleFlags = dw;
  89. // Save changed data back to registry
  90. RegEntry re(DEBUG_KEY, HKEY_LOCAL_MACHINE);
  91. re.SetValue(REGVAL_DBG_SPEWFLAGS, dw);
  92. }
  93. /*
  94. ** InitDebugModule()
  95. **
  96. **
  97. **
  98. ** Arguments:
  99. **
  100. ** Returns:
  101. **
  102. ** Side Effects: none
  103. */
  104. BOOL NMINTERNAL InitDebugModule(PCSTR pcszSpewModule)
  105. {
  106. RegEntry re(DEBUG_KEY, HKEY_LOCAL_MACHINE);
  107. s_dwDebugModuleFlags = re.GetNumber(REGVAL_DBG_SPEWFLAGS, DEFAULT_DBG_SPEWFLAGS);
  108. g_pcszSpewModule = pcszSpewModule;
  109. #ifdef _DBGSTACK
  110. ASSERT(s_dwStackDepthSlot == TLS_OUT_OF_INDEXES);
  111. s_dwStackDepthSlot = TlsAlloc();
  112. if (s_dwStackDepthSlot != TLS_OUT_OF_INDEXES)
  113. {
  114. EVAL(TlsSetValue(s_dwStackDepthSlot, (PVOID)s_ulcHackStackDepth));
  115. TRACE_OUT(("InitDebugModule(): Using thread local storage slot %lu for debug stack depth counter.",
  116. s_dwStackDepthSlot));
  117. }
  118. else
  119. {
  120. WARNING_OUT(("InitDebugModule(): TlsAlloc() failed to allocate thread local storage for debug stack depth counter."));
  121. }
  122. #endif
  123. if (NULL == ghDbgZone)
  124. {
  125. PSTR rgsz[4];
  126. rgsz[0] = (PSTR) pcszSpewModule;
  127. ASSERT(0 == ZONE_WARNING);
  128. rgsz[1+ZONE_WARNING] = "Warning";
  129. ASSERT(1 == ZONE_TRACE);
  130. rgsz[1+ZONE_TRACE] = "Trace";
  131. ASSERT(2 == ZONE_FUNCTION);
  132. rgsz[1+ZONE_FUNCTION] = "Function";
  133. // Initialize standard debug settings with warning enabled by default
  134. DbgInitEx(&ghDbgZone, rgsz, 3, 0x01);
  135. }
  136. return TRUE;
  137. }
  138. /*
  139. ** ExitDebugModule()
  140. **
  141. **
  142. **
  143. ** Arguments:
  144. **
  145. ** Returns:
  146. **
  147. ** Side Effects: none
  148. */
  149. void NMINTERNAL ExitDebugModule(void)
  150. {
  151. #ifdef _DBGSTACK
  152. if (s_dwStackDepthSlot != TLS_OUT_OF_INDEXES)
  153. {
  154. s_ulcHackStackDepth = ((ULONG_PTR)TlsGetValue(s_dwStackDepthSlot));
  155. /* Leave s_ulcHackStackDepth == 0 if TlsGetValue() fails. */
  156. EVAL(TlsFree(s_dwStackDepthSlot));
  157. s_dwStackDepthSlot = TLS_OUT_OF_INDEXES;
  158. }
  159. #endif
  160. g_pcszSpewModule = NULL;
  161. DBGDEINIT(&ghDbgZone);
  162. }
  163. /*
  164. ** StackEnter()
  165. **
  166. **
  167. **
  168. ** Arguments:
  169. **
  170. ** Returns:
  171. **
  172. ** Side Effects: none
  173. */
  174. void NMINTERNAL StackEnter(void)
  175. {
  176. #ifdef _DBGSTACK
  177. if (s_dwStackDepthSlot != TLS_OUT_OF_INDEXES)
  178. {
  179. ULONG_PTR ulcDepth;
  180. ulcDepth = ((ULONG_PTR)TlsGetValue(s_dwStackDepthSlot));
  181. ASSERT(ulcDepth < ULONG_MAX);
  182. EVAL(TlsSetValue(s_dwStackDepthSlot, (PVOID)(ulcDepth + 1)));
  183. }
  184. else
  185. {
  186. ASSERT(s_ulcHackStackDepth < ULONG_MAX);
  187. s_ulcHackStackDepth++;
  188. }
  189. #endif
  190. return;
  191. }
  192. /*
  193. ** StackLeave()
  194. **
  195. **
  196. **
  197. ** Arguments:
  198. **
  199. ** Returns:
  200. **
  201. ** Side Effects: none
  202. */
  203. void NMINTERNAL StackLeave(void)
  204. {
  205. #ifdef _DBGSTACK
  206. if (s_dwStackDepthSlot != TLS_OUT_OF_INDEXES)
  207. {
  208. ULONG_PTR ulcDepth;
  209. ulcDepth = ((ULONG_PTR)TlsGetValue(s_dwStackDepthSlot));
  210. if (EVAL(ulcDepth > 0))
  211. EVAL(TlsSetValue(s_dwStackDepthSlot, (PVOID)(ulcDepth - 1)));
  212. }
  213. else
  214. {
  215. if (EVAL(s_ulcHackStackDepth > 0))
  216. s_ulcHackStackDepth--;
  217. }
  218. #endif
  219. return;
  220. }
  221. /*
  222. ** GetStackDepth()
  223. **
  224. **
  225. **
  226. ** Arguments:
  227. **
  228. ** Returns:
  229. **
  230. ** Side Effects: none
  231. */
  232. ULONG_PTR NMINTERNAL GetStackDepth(void)
  233. {
  234. ULONG_PTR ulcDepth = 0;
  235. #ifdef _DBGSTACK
  236. if (s_dwStackDepthSlot != TLS_OUT_OF_INDEXES)
  237. ulcDepth = (ULONG)((ULONG_PTR)TlsGetValue(s_dwStackDepthSlot));
  238. else
  239. ulcDepth = s_ulcHackStackDepth;
  240. #endif
  241. return(ulcDepth);
  242. }
  243. /* _ D B G Z P R I N T M S G */
  244. /*-------------------------------------------------------------------------
  245. %%Function: _DbgZPrintMsg
  246. -------------------------------------------------------------------------*/
  247. static VOID _DbgZPrintMsg(UINT iZone, PSTR pszFormat, va_list arglist)
  248. {
  249. PCSTR pcszSpewPrefix;
  250. char szModule[128];
  251. if (g_pcszSpewModule)
  252. {
  253. switch (iZone)
  254. {
  255. case ZONE_TRACE:
  256. pcszSpewPrefix = "Trace";
  257. break;
  258. case ZONE_FUNCTION:
  259. pcszSpewPrefix = "Func ";
  260. break;
  261. case ZONE_WARNING:
  262. pcszSpewPrefix = "Warn ";
  263. break;
  264. default:
  265. pcszSpewPrefix = "?????";
  266. break;
  267. }
  268. wsprintfA(szModule, "%s:%s", g_pcszSpewModule, pcszSpewPrefix);
  269. }
  270. else
  271. {
  272. // No module nonsense, empty prefix
  273. *szModule = 0;
  274. }
  275. if (IS_FLAG_CLEAR(s_dwDebugModuleFlags, DEBUG_DFL_INDENT))
  276. {
  277. // Don't indent output
  278. DbgPrintf(szModule, pszFormat, arglist);
  279. }
  280. else
  281. {
  282. PCSTR pcszIndent;
  283. ULONG_PTR ulcStackDepth;
  284. char szFormat[512];
  285. static char _szSpewLeader[] = " ";
  286. ulcStackDepth = GetStackDepth();
  287. if (ulcStackDepth > sizeof(_szSpewLeader))
  288. ulcStackDepth = sizeof(_szSpewLeader);
  289. pcszIndent = _szSpewLeader + sizeof(_szSpewLeader) - ulcStackDepth;
  290. wsprintfA(szFormat, "%s%s", pcszIndent, pszFormat);
  291. DbgPrintf(szModule, szFormat, arglist);
  292. }
  293. }
  294. VOID WINAPI DbgZPrintError(PSTR pszFormat,...)
  295. {
  296. va_list v1;
  297. va_start(v1, pszFormat);
  298. _DbgZPrintMsg(ZONE_WARNING, pszFormat, v1);
  299. va_end(v1);
  300. _DbgBreak();
  301. }
  302. VOID WINAPI DbgZPrintWarning(PSTR pszFormat,...)
  303. {
  304. if (GETZONEMASK(ghDbgZone) & ZONE_WARNING_FLAG)
  305. {
  306. va_list v1;
  307. va_start(v1, pszFormat);
  308. _DbgZPrintMsg(ZONE_WARNING, pszFormat, v1);
  309. va_end(v1);
  310. }
  311. }
  312. VOID WINAPI DbgZPrintTrace(PSTR pszFormat,...)
  313. {
  314. if (GETZONEMASK(ghDbgZone) & ZONE_TRACE_FLAG)
  315. {
  316. va_list v1;
  317. va_start(v1, pszFormat);
  318. _DbgZPrintMsg(ZONE_TRACE, pszFormat, v1);
  319. va_end(v1);
  320. }
  321. }
  322. VOID WINAPI DbgZPrintFunction(PSTR pszFormat,...)
  323. {
  324. if (GETZONEMASK(ghDbgZone) & ZONE_FUNCTION_FLAG)
  325. {
  326. va_list v1;
  327. va_start(v1, pszFormat);
  328. _DbgZPrintMsg(ZONE_FUNCTION, pszFormat, v1);
  329. va_end(v1);
  330. }
  331. }
  332. #endif /* DEBUG */
  333.