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.

303 lines
8.6 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // cppdbg.hpp
  4. //
  5. // C++-only debugging support.
  6. //
  7. // Copyright (C) Microsoft Corporation, 1997.
  8. //
  9. //----------------------------------------------------------------------------
  10. #ifndef _CPPDBG_HPP_
  11. #define _CPPDBG_HPP_
  12. #if DBG
  13. #include <stdarg.h>
  14. typedef unsigned int UINT;
  15. //
  16. // Mask bits common to all modules.
  17. //
  18. #define DBG_MASK_NO_PREFIX 0x80000000
  19. #define DBG_MASK_FORCE 0x40000000
  20. // Mask bits checked against output mask.
  21. #define DBG_MASK_CHECK (~(DBG_MASK_NO_PREFIX | \
  22. DBG_MASK_FORCE))
  23. // Forced continuation mask.
  24. #define DBG_MASK_FORCE_CONT (DBG_MASK_NO_PREFIX | DBG_MASK_FORCE)
  25. //
  26. // Failure control bits for assert and HRESULT failures.
  27. //
  28. #define DBG_FAILURE_BREAK 0x00000001
  29. #define DBG_FAILURE_OUTPUT 0x00000002
  30. #define DBG_FAILURE_PROMPT 0x00000004
  31. #define DBG_FAILURE_FILENAME_ONLY 0x00000008
  32. //
  33. // Overall output control bits.
  34. //
  35. #define DBG_OUTPUT_SUPPRESS 0x00000001
  36. #define DBG_OUTPUT_ALL_MATCH 0x00000002
  37. //----------------------------------------------------------------------------
  38. //
  39. // DebugModule
  40. //
  41. //----------------------------------------------------------------------------
  42. struct DebugModuleFlags
  43. {
  44. UINT uFlag;
  45. char *pName;
  46. };
  47. // Declares a DebugModuleFlags entry.
  48. #define DBG_DECLARE_MODFLAG(Group, Name) \
  49. Group ## _ ## Name, #Name
  50. enum
  51. {
  52. DBG_ASSERT_FLAGS,
  53. DBG_HR_FLAGS,
  54. DBG_OUTPUT_FLAGS,
  55. DBG_OUTPUT_MASK,
  56. DBG_USER_FLAGS,
  57. DBG_FLAGS_COUNT
  58. };
  59. class DebugModule
  60. {
  61. public:
  62. DebugModule(char *pModule, char *pPrefix,
  63. DebugModuleFlags *pOutputMasks, UINT uOutputMask,
  64. DebugModuleFlags *pUserFlags, UINT uUserFlags);
  65. void Out(char *pFmt, ...);
  66. void OutMask(UINT uMask, char *pFmt, ...)
  67. {
  68. if ((uMask & DBG_MASK_FORCE) ||
  69. ((m_uFlags[DBG_OUTPUT_FLAGS] & DBG_OUTPUT_ALL_MATCH) &&
  70. (uMask & m_uFlags[DBG_OUTPUT_MASK] & DBG_MASK_CHECK) == uMask) ||
  71. ((m_uFlags[DBG_OUTPUT_FLAGS] & DBG_OUTPUT_ALL_MATCH) == 0 &&
  72. (uMask & m_uFlags[DBG_OUTPUT_MASK] & DBG_MASK_CHECK) != 0))
  73. {
  74. va_list Args;
  75. va_start(Args, pFmt);
  76. OutVa(uMask, pFmt, Args);
  77. va_end(Args);
  78. }
  79. }
  80. void AssertFailed(char *pExp);
  81. void AssertFailedMsg(char *pFmt, ...);
  82. void HrStmtFailed(HRESULT hr);
  83. HRESULT HrExpFailed(HRESULT hr);
  84. void SetFileLine(char *pFile, int iLine)
  85. {
  86. m_pFile = pFile;
  87. m_iLine = iLine;
  88. }
  89. void Prompt(char *pFmt, ...);
  90. UINT GetFlags(int iIdx)
  91. {
  92. return m_uFlags[iIdx];
  93. }
  94. void SetFlags(int iIdx, UINT uValue)
  95. {
  96. m_uFlags[iIdx] = uValue;
  97. }
  98. private:
  99. void OutVa(UINT uMask, char *pFmt, va_list Args);
  100. void AssertFailedVa(char *pFmt, va_list Args, BOOL bNewLine);
  101. HKEY OpenDebugKey(void);
  102. UINT GetRegUint(HKEY hKey, char *pValue, UINT uDefault);
  103. BOOL SetRegUint(HKEY hKey, char *pValue, UINT uValue);
  104. void ReadReg(void);
  105. void WriteReg(void);
  106. UINT ParseUint(char *pString, DebugModuleFlags *pFlags);
  107. void OutUint(char *pName, DebugModuleFlags *pFlags, UINT uValue);
  108. void AdvanceCols(int iCols);
  109. void ShowFlags(char *pName, DebugModuleFlags *pFlags);
  110. char *PathFile(char *pPath);
  111. BOOL OutPathFile(char *pPrefix, UINT uFailureFlags);
  112. void HrFailure(HRESULT hr, char *pPrefix);
  113. char *HrString(HRESULT hr);
  114. // Module information given.
  115. char *m_pModule;
  116. char *m_pPrefix;
  117. // Flag descriptions and values.
  118. DebugModuleFlags *m_pModFlags[DBG_FLAGS_COUNT];
  119. UINT m_uFlags[DBG_FLAGS_COUNT];
  120. // Temporary file and line number storage.
  121. char *m_pFile;
  122. int m_iLine;
  123. // Output column during multiline display.
  124. int m_iModuleStartCol;
  125. int m_iCol;
  126. int m_iStartCol;
  127. };
  128. //----------------------------------------------------------------------------
  129. //
  130. // Support macros.
  131. //
  132. //----------------------------------------------------------------------------
  133. #define DBG_MODULE(Prefix) Prefix ## _Debug
  134. // Put this in one source file.
  135. #define DBG_DECLARE_ONCE(Module, Prefix, pOutputMasks, uOutputMask, \
  136. pUserFlags, uUserFlags) \
  137. DebugModule DBG_MODULE(Prefix)(#Module, #Prefix, \
  138. pOutputMasks, uOutputMask, \
  139. pUserFlags, uUserFlags)
  140. // Put this in your derived debugging header.
  141. #define DBG_DECLARE_HEADER(Prefix) \
  142. extern DebugModule DBG_MODULE(Prefix)
  143. // Put this in every file.
  144. #define DBG_DECLARE_FILE() \
  145. static char *g_pStaticDebugFile = __FILE__
  146. #define DBG_DECLARE_DPF(Prefix, Args) \
  147. DBG_MODULE(Prefix).Out Args
  148. #define DBG_DECLARE_DPFM(Prefix, Args) \
  149. DBG_MODULE(Prefix).OutMask Args
  150. #define DBG_DECLARE_ASSERT(Prefix, Exp) \
  151. if (!(Exp)) \
  152. { DBG_MODULE(Prefix).SetFileLine(g_pStaticDebugFile, __LINE__); \
  153. DBG_MODULE(Prefix).AssertFailed(#Exp); } \
  154. else 0
  155. #define DBG_DECLARE_ASSERTMSG(Prefix, Exp, Args) \
  156. if (!(Exp)) \
  157. { DBG_MODULE(Prefix).SetFileLine(g_pStaticDebugFile, __LINE__); \
  158. DBG_MODULE(Prefix).AssertFailedMsg Args ; } \
  159. else 0
  160. #define DBG_DECLARE_VERIFY(Prefix, Exp) \
  161. DBG_DECLARE_ASSERT(Prefix, Exp)
  162. #define DBG_DECLARE_VERIFYMSG(Prefix, Exp, Args)\
  163. DBG_DECLARE_ASSERTMSG(Prefix, Exp, Args)
  164. #define DBG_DECLARE_PROMPT(Prefix, Args) \
  165. DBG_MODULE(Prefix).Prompt Args
  166. #define DBG_DECLARE_GETFLAGS(Prefix, Idx) \
  167. DBG_MODULE(Prefix).GetFlags(Idx)
  168. #define DBG_DECLARE_SETFLAGS(Prefix, Idx, Value) \
  169. DBG_MODULE(Prefix).SetFlags(Idx, Value)
  170. //
  171. // These macros assume a variable 'hr' exists.
  172. //
  173. // HRESULT test in expression form.
  174. #define DBG_DECLARE_HRCHK(Prefix, Exp) \
  175. ((hr = (Exp)) != S_OK ? \
  176. (DBG_MODULE(Prefix).SetFileLine(g_pStaticDebugFile, __LINE__), \
  177. DBG_MODULE(Prefix).HrExpFailed(hr)) : hr)
  178. // HRESULT test in if/then form.
  179. #define DBGI_DECLARE_HRIF(Prefix, Exp, DoFail) \
  180. if ((hr = (Exp)) != S_OK) \
  181. { DBG_MODULE(Prefix).SetFileLine(g_pStaticDebugFile, __LINE__); \
  182. DBG_MODULE(Prefix).HrStmtFailed(hr); \
  183. DoFail; } \
  184. else hr
  185. #define DBG_DECLARE_HRGO(Prefix, Exp, Label) \
  186. DBGI_DECLARE_HRIF(Prefix, Exp, goto Label)
  187. #define DBG_DECLARE_HRERR(Prefix, Exp) \
  188. DBG_DECLARE_HRGO(Prefix, Exp, HR_Err)
  189. #define DBG_DECLARE_HRRET(Prefix, Exp) \
  190. DBGI_DECLARE_HRIF(Prefix, Exp, return hr)
  191. #else // #if DBG
  192. //
  193. // Empty macros for free builds.
  194. //
  195. #define DBG_MODULE(Prefix) 0
  196. #define DBG_DECLARE_ONCE(Module, Prefix, pOutputMasks, uOutputMask, \
  197. pUserFlags, uUserFlags)
  198. #define DBG_DECLARE_HEADER(Prefix)
  199. #define DBG_DECLARE_FILE()
  200. #define DBG_DECLARE_DPF(Prefix, Args)
  201. #define DBG_DECLARE_DPFM(Prefix, Args)
  202. #define DBG_DECLARE_ASSERT(Prefix, Exp)
  203. #define DBG_DECLARE_ASSERTMSG(Prefix, Exp, Args)
  204. #define DBG_DECLARE_PROMPT(Prefix, Args)
  205. #define DBG_DECLARE_GETFLAGS(Prefix, Idx) 0
  206. #define DBG_DECLARE_SETFLAGS(Prefix, Idx, Value)
  207. //
  208. // Macros which evaluate to code on free builds.
  209. //
  210. #define DBG_DECLARE_VERIFY(Prefix, Exp) (Exp)
  211. #define DBG_DECLARE_VERIFYMSG(Prefix, Exp, Args) (Exp)
  212. #define DBG_DECLARE_HRCHK(Prefix, Exp) \
  213. (hr = (Exp))
  214. #define DBGI_DECLARE_HRIF(Prefix, Exp, DoFail) \
  215. if ((hr = (Exp)) != S_OK) DoFail; else hr
  216. #define DBG_DECLARE_HRGO(Prefix, Exp, Label) \
  217. DBGI_DECLARE_HRIF(Prefix, Exp, goto Label)
  218. #define DBG_DECLARE_HRERR(Prefix, Exp) \
  219. DBG_DECLARE_HRGO(Prefix, Exp, HR_Err)
  220. #define DBG_DECLARE_HRRET(Prefix, Exp) \
  221. DBGI_DECLARE_HRIF(Prefix, Exp, return hr)
  222. #endif // #if DBG
  223. //----------------------------------------------------------------------------
  224. //
  225. // Global debug module.
  226. //
  227. //----------------------------------------------------------------------------
  228. DBG_DECLARE_HEADER(G);
  229. #define GDPF(Args) DBG_DECLARE_DPF(G, Args)
  230. #define GDPFM(Args) DBG_DECLARE_DPFM(G, Args)
  231. #define GASSERT(Exp) DBG_DECLARE_ASSERT(G, Exp)
  232. #define GASSERTMSG(Exp, Args) DBG_DECLARE_ASSERTMSG(G, Exp, Args)
  233. #define GVERIFY(Exp) DBG_DECLARE_VERIFY(G, Exp)
  234. #define GVERIFYMSG(Exp) DBG_DECLARE_VERIFYMSG(G, Exp, Args)
  235. #define GPROMPT(Args) DBG_DECLARE_PROMPT(G, Args)
  236. #define GGETFLAGS(Idx) DBG_DECLARE_GETFLAGS(G, Idx)
  237. #define GSETFLAGS(Idx, Value) DBG_DECLARE_SETFLAGS(G, Idx, Value)
  238. #define GHRCHK(Exp) DBG_DECLARE_HRCHK(G, Exp)
  239. #define GHRGO(Exp, Label) DBG_DECLARE_HRGO(G, Exp, Label)
  240. #define GHRERR(Exp) DBG_DECLARE_HRERR(G, Exp)
  241. #define GHRRET(Exp) DBG_DECLARE_HRRET(G, Exp)
  242. #endif // #ifndef _CPPDBG_HPP_