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.

379 lines
15 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: F3DEBUG.H
  7. //
  8. // Contains: Debugging stuff -- uses MSHTML's mshtmdbg.dll for debugging
  9. // utilities.
  10. //
  11. // Stolen from Trident
  12. //
  13. //--------------------------------------------------------------------------
  14. #include <mshtmdbg.h>
  15. //--------------------------------------------------------------------------
  16. // Assert, Verify && WHEN_DBG
  17. //--------------------------------------------------------------------------
  18. #if defined(_M_IX86)
  19. #define F3DebugBreak() _asm { int 3 }
  20. #else
  21. #define F3DebugBreak() DebugBreak()
  22. #endif
  23. #if DBG != 1
  24. #define Verify(x) x
  25. #define Assert(x)
  26. #define AssertSz(x, sz)
  27. #define IF_DBG(x)
  28. #define WHEN_DBG(x)
  29. #define IF_NOT_DBG(x) x
  30. #define WHEN_NOT_DBG(x) x
  31. #define StartupAssert(x)
  32. #define AssertThreadDisable(fb)
  33. #else // #if DBG != 1
  34. #define AssertThreadDisable(fDisable) DbgExAssertThreadDisable(fDisable)
  35. extern DWORD g_dwFALSE;
  36. #define Verify(x) Assert(x)
  37. #define Assert(x) do { if (!((DWORD_PTR)(x)|g_dwFALSE) && DbgExAssertImpl(__FILE__, __LINE__, #x))\
  38. F3DebugBreak(); } while (g_dwFALSE)
  39. #define AssertSz(x, sz) do { if (!((DWORD_PTR)(x)|g_dwFALSE) && DbgExAssertImpl(__FILE__, __LINE__, sz))\
  40. F3DebugBreak(); } while (g_dwFALSE)
  41. #define AssertLocSz(x, File, Line, sz) do { if (!((DWORD_PTR)(x)|g_dwFALSE) && DbgExAssertImpl(File, Line, sz))\
  42. F3DebugBreak(); } while (g_dwFALSE)
  43. #define IF_DBG(x) x
  44. #define WHEN_DBG(x) x
  45. #define IF_NOT_DBG(x)
  46. #define WHEN_NOT_DBG(x)
  47. #define concat_name(x, y) x##y
  48. #define concat_line_impl(x, y) concat_name(x, y)
  49. #define concat_LINE(x) concat_line_impl(x, __LINE__)
  50. //
  51. // Startup assertion:
  52. // The assertion is called by initializing a global variable with
  53. // a function that performs the assertion and returns 1. The name
  54. // of the global variable and function name are suffixed with the
  55. // line number to make them unique. Unfortunatly, one cannot just
  56. // write StartupAssert_##__LINE__, because __LINE__ is not an
  57. // argument to the macro and so the expansion is, e.g. StartupAssert__##53.
  58. // So we indirect through another macro which concatenates its
  59. // two arguments.
  60. //
  61. #define StartupAssert(x) \
  62. static int \
  63. concat_LINE(StartupAssert_) () \
  64. { \
  65. Assert(x); \
  66. return 1; \
  67. } \
  68. \
  69. static int concat_LINE(g_StartupAssert_) = concat_LINE(StartupAssert_)() \
  70. #endif // #if DBG != 1
  71. //--------------------------------------------------------------------------
  72. // Trace Tags
  73. //--------------------------------------------------------------------------
  74. #if DBG != 1
  75. #define TraceTag(x)
  76. #define TraceTagEx(x)
  77. #define TaggedTraceListEx(tag, usFlags, szFmt, valMarker)
  78. #define TraceCallers(tag, iStart, cTotal)
  79. #define DeclareTag(tag, szOwner, szDescription)
  80. #define DeclareTagOther(tag, szOwner, szDescription)
  81. #define ExternTag(tag)
  82. #define IsTagEnabled(tag) FALSE
  83. #define EnableTag(tag, fEnable)
  84. #define SetDiskFlag(tag, fSendToDisk)
  85. #define SetBreakFlag(tag, fBreak)
  86. #define FindTag(szTagDesc) NULL
  87. #define PerfDbgTag(tag, szOwner, szDescrip) \
  88. PerfTag(tag, szOwner, szDescrip)
  89. #define PerfDbgExtern(tag) \
  90. PerfExtern(tag)
  91. #define PerfDbgLog(tag,pv,f) PerfLog(tag,pv,f)
  92. #define PerfDbgLog1(tag,pv,f,a1) PerfLog1(tag,pv,f,a1)
  93. #define PerfDbgLog2(tag,pv,f,a1,a2) PerfLog2(tag,pv,f,a1,a2)
  94. #define PerfDbgLog3(tag,pv,f,a1,a2,a3) PerfLog3(tag,pv,f,a1,a2,a3)
  95. #define PerfDbgLog4(tag,pv,f,a1,a2,a3,a4) PerfLog4(tag,pv,f,a1,a2,a3,a4)
  96. #define PerfDbgLog5(tag,pv,f,a1,a2,a3,a4,a5) PerfLog5(tag,pv,f,a1,a2,a3,a4,a5)
  97. #define PerfDbgLog6(tag,pv,f,a1,a2,a3,a4,a5,a6) PerfLog6(tag,pv,f,a1,a2,a3,a4,a5,a6)
  98. #define PerfDbgLog7(tag,pv,f,a1,a2,a3,a4,a5,a6,a7) PerfLog7(tag,pv,f,a1,a2,a3,a4,a5,a6,a7)
  99. #define PerfDbgLog8(tag,pv,f,a1,a2,a3,a4,a5,a6,a7,a8) PerfLog8(tag,pv,f,a1,a2,a3,a4,a5,a6,a7,a8)
  100. #define PerfDbgLog9(tag,pv,f,a1,a2,a3,a4,a5,a6,a7,a8,a9) PerfLog9(tag,pv,f,a1,a2,a3,a4,a5,a6,a7,a8,a9)
  101. #define PerfDbgLogN(x) PerfLogFn x
  102. #define IsPerfDbgEnabled(tag) IsPerfEnabled(tag)
  103. #else
  104. #define TraceTag(x) \
  105. do \
  106. { \
  107. if (TaggedTrace x) \
  108. F3DebugBreak(); \
  109. } while (g_dwFALSE)
  110. #define TraceTagEx(x) \
  111. do \
  112. { \
  113. if (TaggedTraceEx x) \
  114. F3DebugBreak(); \
  115. } while (g_dwFALSE)
  116. #define TraceCallers(tag, iStart, cTotal) \
  117. TaggedTraceCallers(tag, iStart, cTotal)
  118. #define DeclareTag(tag, szOwner, szDescrip) \
  119. TRACETAG tag(DbgExTagRegisterTrace(szOwner, szDescrip, FALSE));
  120. #define DeclareTagOther(tag, szOwner, szDescrip) \
  121. TRACETAG tag(DbgExTagRegisterOther(szOwner, szDescrip, FALSE));
  122. #define ExternTag(tag) extern TRACETAG tag;
  123. #define PerfDbgTag(tag, szOwner, szDescrip) DeclareTag(tag, szOwner, szDescrip)
  124. #define PerfDbgExtern(tag) ExternTag(tag)
  125. #define PerfDbgLog(tag,pv,f) if (IsPerfDbgEnabled(tag)) PerfDbgLogFn(tag,pv,f)
  126. #define PerfDbgLog1(tag,pv,f,a1) if (IsPerfDbgEnabled(tag)) PerfDbgLogFn(tag,pv,f,a1)
  127. #define PerfDbgLog2(tag,pv,f,a1,a2) if (IsPerfDbgEnabled(tag)) PerfDbgLogFn(tag,pv,f,a1,a2)
  128. #define PerfDbgLog3(tag,pv,f,a1,a2,a3) if (IsPerfDbgEnabled(tag)) PerfDbgLogFn(tag,pv,f,a1,a2,a3)
  129. #define PerfDbgLog4(tag,pv,f,a1,a2,a3,a4) if (IsPerfDbgEnabled(tag)) PerfDbgLogFn(tag,pv,f,a1,a2,a3,a4)
  130. #define PerfDbgLog5(tag,pv,f,a1,a2,a3,a4,a5) if (IsPerfDbgEnabled(tag)) PerfDbgLogFn(tag,pv,f,a1,a2,a3,a4,a5)
  131. #define PerfDbgLog6(tag,pv,f,a1,a2,a3,a4,a5,a6) if (IsPerfDbgEnabled(tag)) PerfDbgLogFn(tag,pv,f,a1,a2,a3,a4,a5,a6)
  132. #define PerfDbgLog7(tag,pv,f,a1,a2,a3,a4,a5,a6,a7) if (IsPerfDbgEnabled(tag)) PerfDbgLogFn(tag,pv,f,a1,a2,a3,a4,a5,a6,a7)
  133. #define PerfDbgLog8(tag,pv,f,a1,a2,a3,a4,a5,a6,a7,a8) if (IsPerfDbgEnabled(tag)) PerfDbgLogFn(tag,pv,f,a1,a2,a3,a4,a5,a6,a7,a8)
  134. #define PerfDbgLog9(tag,pv,f,a1,a2,a3,a4,a5,a6,a7,a8,a9) if (IsPerfDbgEnabled(tag)) PerfDbgLogFn(tag,pv,f,a1,a2,a3,a4,a5,a6,a7,a8,a9)
  135. #define PerfDbgLogN(x) PerfDbgLogFn x
  136. #define IsPerfDbgEnabled(tag) IsTagEnabled(tag)
  137. int __cdecl PerfDbgLogFn(int tag, void * pvObj, char * pchFmt, ...);
  138. // Tag trace functions
  139. #define TaggedTrace DbgExTaggedTrace
  140. #define TaggedTraceEx DbgExTaggedTraceEx
  141. #define TaggedTraceListEx DbgExTaggedTraceListEx
  142. #define TaggedTraceCallers DbgExTaggedTraceCallers
  143. // TaggedTraceEx usFlags parameter defines
  144. #define TAG_NONAME 0x01
  145. #define TAG_NONEWLINE 0x02
  146. #define TAG_USECONSOLE 0x04
  147. #define TAG_INDENT 0x08
  148. #define TAG_OUTDENT 0x10
  149. // Register a new tag.
  150. // Standard tags
  151. #define tagError DbgExTagError()
  152. #define tagWarning DbgExTagWarning()
  153. #define tagThread DbgExTagThread()
  154. #define tagAssertExit DbgExTagAssertExit()
  155. #define tagAssertStacks DbgExTagAssertStacks()
  156. #define tagMemoryStrict DbgExTagMemoryStrict()
  157. #define tagCoMemoryStrict DbgExTagCoMemoryStrict()
  158. #define tagMemoryStrictTail DbgExTagMemoryStrictTail()
  159. #define tagMemoryStrictAlign DbgExTagMemoryStrictAlign()
  160. #define tagOLEWatch DbgExTagOLEWatch()
  161. #define tagPerf DbgExTagPerf()
  162. // Get/Set tag enabled status.
  163. #define IsTagEnabled DbgExIsTagEnabled
  164. #define EnableTag DbgExEnableTag
  165. #define SetDiskFlag DbgExSetDiskFlag
  166. #define SetBreakFlag DbgExSetBreakFlag
  167. #define FindTag DbgExFindTag
  168. #endif
  169. //--------------------------------------------------------------------------
  170. // Memory Allocation
  171. //--------------------------------------------------------------------------
  172. #if DBG != 1
  173. #define DbgPreAlloc(cb) cb
  174. #define DbgPostAlloc(pv) pv
  175. #define DbgPreFree(pv) pv
  176. #define DbgPostFree()
  177. #define DbgPreRealloc(pv, cb, ppv) cb
  178. #define DbgPostRealloc(pv) pv
  179. #define DbgPreGetSize(pv) pv
  180. #define DbgPostGetSize(cb) cb
  181. #define DbgPreDidAlloc(pv) pv
  182. #define DbgPostDidAlloc(pv, fAct) fAct
  183. #define DbgMemoryTrackDisable(fb)
  184. #define DbgCoMemoryTrackDisable(fb)
  185. #define DbgMemoryBlockTrackDisable(pv)
  186. #define CHECK_HEAP()
  187. #else
  188. #define DbgPreAlloc DbgExPreAlloc
  189. #define DbgPostAlloc DbgExPostAlloc
  190. #define DbgPreFree DbgExPreFree
  191. #define DbgPostFree DbgExPostFree
  192. #define DbgPreRealloc DbgExPreRealloc
  193. #define DbgPostRealloc DbgExPostRealloc
  194. #define DbgPreGetSize DbgExPreGetSize
  195. #define DbgPostGetSize DbgExPostGetSize
  196. #define DbgPreDidAlloc DbgExPreDidAlloc
  197. #define DbgPostDidAlloc DbgExPostDidAlloc
  198. #define DbgMemoryTrackDisable DbgExMemoryTrackDisable
  199. #define DbgCoMemoryTrackDisable DbgExCoMemoryTrackDisable
  200. #define DbgMemoryBlockTrackDisable DbgExMemoryBlockTrackDisable
  201. //
  202. // Use the CHECK_HEAP macro to do thorough heap validation.
  203. //
  204. BOOL CheckSmallBlockHeap();
  205. #define CHECK_HEAP() Assert(DbgExValidateInternalHeap() && CheckSmallBlockHeap() && "Corrupted heap!")
  206. #endif
  207. //+---------------------------------------------------------------------
  208. // Interface tracing.
  209. //----------------------------------------------------------------------
  210. #if DBG == 1 && !defined(WIN16)
  211. #define DbgTrackItf DbgExTrackItf
  212. #else
  213. #define DbgTrackItf(iid, pch, fTrackOnQi, ppv)
  214. #endif
  215. //--------------------------------------------------------------------------
  216. // Failure testing
  217. //--------------------------------------------------------------------------
  218. #if DBG == 1 && defined(__cplusplus)
  219. #define SetSimFailCounts DbgExSetSimFailCounts
  220. #define GetFailCount DbgExGetFailCount
  221. #define TraceFailL DbgExTraceFailL
  222. #define TraceWin32L DbgExTraceWin32L
  223. #define TraceHR DbgExTraceHR
  224. #define TraceOLE DbgExTraceOLE
  225. #define TraceEnter DbgExTraceEnter
  226. #define TraceExit DbgExTraceExit
  227. template <class t> inline t
  228. TraceFail(t errExpr, LONG_PTR errTest, BOOL fIgnore, LPSTR pstrExpr, LPSTR pstrFile, int line)
  229. {
  230. return (t) DbgExTraceFailL((LONG_PTR) errExpr, errTest, fIgnore, pstrExpr, pstrFile, line);
  231. }
  232. template <class t> inline t
  233. TraceWin32(t errExpr, LONG_PTR errTest, BOOL fIgnore, LPSTR pstrExpr, LPSTR pstrFile, int line)
  234. {
  235. return (t) DbgExTraceWin32L((LONG_PTR) errExpr, errTest, fIgnore, pstrExpr, pstrFile, line);
  236. }
  237. // disabled TraceEnter, we don't need it at this time
  238. #undef TraceEnter
  239. #define TraceEnter(x, y, z) NULL
  240. #define TFAIL(e, x) (TraceEnter(#x, __FILE__, __LINE__), TraceFail( (x), (e), FALSE, #x, __FILE__, __LINE__))
  241. #define TW32(e, x) (TraceEnter(#x, __FILE__, __LINE__), TraceWin32((x), (e), FALSE, #x, __FILE__, __LINE__))
  242. #define THR(x) (TraceEnter(#x, __FILE__, __LINE__), TraceHR((x), FALSE, #x, __FILE__, __LINE__))
  243. #define TFAIL_NOTRACE(e, x) (x)
  244. #define TW32_NOTRACE(e, x) (x)
  245. #define THR_NOTRACE(x) (x)
  246. #define IGNORE_FAIL(e, x) (TraceEnter(#x, __FILE__, __LINE__), (void) TraceFail((x), (e), TRUE, #x, __FILE__, __LINE__))
  247. #define IGNORE_W32(e,x) (TraceEnter(#x, __FILE__, __LINE__), (void) TraceWin32((x), (e), TRUE, #x, __FILE__, __LINE__))
  248. #define IGNORE_HR(x) (TraceEnter(#x, __FILE__, __LINE__), (void) TraceHR((x), TRUE, #x, __FILE__, __LINE__))
  249. #else // #if DBG == 1
  250. #define SetSimFailCounts(firstFailure, cInterval)
  251. #define TFAIL(e, x) (x)
  252. #define TW32(e, x) (x)
  253. #define THR(x) (x)
  254. #define TFAIL_NOTRACE(e, x) (x)
  255. #define TW32_NOTRACE(e, x) (x)
  256. #define THR_NOTRACE(x) (x)
  257. #define IGNORE_FAIL(e, x) (x)
  258. #define IGNORE_W32(e,x) (x)
  259. #define IGNORE_HR(x) (x)
  260. #endif // #if DBG == 1
  261. //+-------------------------------------------------------------------------
  262. // Return tracing
  263. //--------------------------------------------------------------------------
  264. #if DBG == 1
  265. #define SRETURN(hr) \
  266. return DbgExCheckAndReturnResult((hr), TRUE, __FILE__, __LINE__, -1)
  267. #define RRETURN(hr) \
  268. return DbgExCheckAndReturnResult((hr), TRUE, __FILE__, __LINE__, 0)
  269. #define RRETURN1(hr, s1) \
  270. return DbgExCheckAndReturnResult((hr), TRUE, __FILE__, __LINE__, 1, (s1))
  271. #define RRETURN2(hr, s1, s2) \
  272. return DbgExCheckAndReturnResult((hr), TRUE, __FILE__, __LINE__, 2, (s1), (s2))
  273. #define RRETURN3(hr, s1, s2, s3) \
  274. return DbgExCheckAndReturnResult((hr), TRUE, __FILE__, __LINE__, 3, (s1), (s2), (s3))
  275. #define RRETURN4(hr, s1, s2, s3, s4) \
  276. return DbgExCheckAndReturnResult((hr), TRUE, __FILE__, __LINE__, 4, (s1), (s2), (s3), (s4))
  277. #define SRETURN_NOTRACE(hr) \
  278. return DbgExCheckAndReturnResult((hr), FALSE, __FILE__, __LINE__, -1)
  279. #define RRETURN_NOTRACE(hr) \
  280. return DbgExCheckAndReturnResult((hr), FALSE, __FILE__, __LINE__, 0)
  281. #define RRETURN1_NOTRACE(hr, s1) \
  282. return DbgExCheckAndReturnResult((hr), FALSE, __FILE__, __LINE__, 1, (s1))
  283. #define RRETURN2_NOTRACE(hr, s1, s2) \
  284. return DbgExCheckAndReturnResult((hr), FALSE, __FILE__, __LINE__, 2, (s1), (s2))
  285. #define RRETURN3_NOTRACE(hr, s1, s2, s3) \
  286. return DbgExCheckAndReturnResult((hr), FALSE, __FILE__, __LINE__, 3, (s1), (s2), (s3))
  287. #define RRETURN4_NOTRACE(hr, s1, s2, s3, s4) \
  288. return DbgExCheckAndReturnResult((hr), FALSE, __FILE__, __LINE__, 4, (s1), (s2), (s3), (s4))
  289. #else // DBG == 0
  290. #define SRETURN(hr) return (hr)
  291. #define RRETURN(hr) return (hr)
  292. #define RRETURN1(hr, s1) return (hr)
  293. #define RRETURN2(hr, s1, s2) return (hr)
  294. #define RRETURN3(hr, s1, s2, s3) return (hr)
  295. #define RRETURN4(hr, s1, s2, s3, s4)return (hr)
  296. #define SRETURN_NOTRACE(hr) return (hr)
  297. #define RRETURN_NOTRACE(hr) return (hr)
  298. #define RRETURN1_NOTRACE(hr, s1) return (hr)
  299. #define RRETURN2_NOTRACE(hr, s1, s2) return (hr)
  300. #define RRETURN3_NOTRACE(hr, s1, s2, s3) return (hr)
  301. #define RRETURN4_NOTRACE(hr, s1, s2, s3, s4)return (hr)
  302. #endif // DBG
  303. //+-------------------------------------------------------------------------
  304. // Stack Spew
  305. //--------------------------------------------------------------------------
  306. #ifdef USE_STACK_SPEW
  307. EXTERN_C void InitChkStk(DWORD);
  308. #pragma check_stack(on)
  309. #endif