dbgutil.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /*----------------------------------------------------------------------------
  2. Dbgutil.H
  3. Exported header file for Dbgutil module.
  4. Copyright (C) 1993 Microsoft Corporation
  5. All rights reserved.
  6. Authors:
  7. kennt Kenn Takara
  8. GaryBu Gary S. Burd
  9. History:
  10. 05/07/93 suryanr Created.
  11. 06/09/93 kennt Reorganized.
  12. 07/06/93 kennt YAR (Yet Another Reorg), refactoring code
  13. ----------------------------------------------------------------------------*/
  14. #ifndef _DBGUTIL_H
  15. #define _DBGUTIL_H
  16. //#ifndef _UTILCORE_H
  17. //#include "utilcore.h"
  18. //#endif
  19. #ifdef __cplusplus
  20. extern "C" {
  21. #else
  22. #define NOENTRYEXITTRACE 1
  23. #endif
  24. #if defined(_DEBUG) && !defined(DEBUG)
  25. #define DEBUG
  26. #endif
  27. #define DBG_STRING(var, val) \
  28. static TCHAR var[] = TEXT(val);
  29. #define DBG_STRING_NL(var, val) \
  30. static TCHAR var[] = TEXT(val "\r\n");
  31. #ifndef DllExport
  32. #define DllExport __declspec ( dllexport )
  33. #endif
  34. #ifndef EXPORT
  35. #define EXPORT
  36. #endif
  37. #define DBG_API(type) DllExport type FAR PASCAL EXPORT
  38. #define DBG_APIV(type) DllExport type FAR CDECL EXPORT
  39. /*---------------------------------------------------------------------------
  40. IfBUILD macros
  41. ---------------------------------------------------------------------------*/
  42. #ifdef DEBUG
  43. #define IfDebug(x) x
  44. #define IfNotDebug(x)
  45. #else
  46. #define IfDebug(x)
  47. #define IfNotDebug(x) x
  48. #endif
  49. #ifdef RELEASE
  50. #define IfRelease(x) x
  51. #define IfNotRelease(x)
  52. #else
  53. #define IfRelease(x)
  54. #define IfNotRelease(x) x
  55. #endif
  56. /*---------------------------------------------------------------------------
  57. Assert
  58. ---------------------------------------------------------------------------*/
  59. #define Panic() Assert0(FDbgFalse(), TEXT("Panic"))
  60. #define Panic0(szFmt) Assert0(FDbgFalse(), TEXT(szFmt))
  61. #define Panic1(szFmt, p1) Assert1(FDbgFalse(), TEXT(szFmt), p1)
  62. #define Panic2(szFmt, p1, p2) Assert2(FDbgFalse(), TEXT(szFmt), p1, p2)
  63. #define Panic3(szFmt, p1, p2, p3) Assert3(FDbgFalse(), TEXT(szFmt), p1, p2, p3)
  64. #define Panic4(szFmt, p1, p2, p3, p4) Assert4(FDbgFalse(), TEXT(szFmt), p1, p2, p3, p4)
  65. #define Panic5(szFmt, p1, p2, p3, p4, p5) Assert5(FDbgFalse(), TEXT(szFmt), p1, p2, p3, p4, p5)
  66. #define SideAssert(f) Verify(f)
  67. #define AssertSz(f, sz) Assert0(f, TEXT(sz))
  68. #if !defined(DEBUG) && !defined(DEBUGASSERT)
  69. #define Verify(f) ((void)(f))
  70. #define Assert(f) ((void)0)
  71. #define Assert0(f, szFmt) ((void)0)
  72. #define Assert1(f, szFmt, p1) ((void)0)
  73. #define Assert2(f, szFmt, p1, p2) ((void)0)
  74. #define Assert3(f, szFmt, p1, p2, p3) ((void)0)
  75. #define Assert4(f, szFmt, p1, p2, p3, p4) ((void)0)
  76. #define Assert5(f, szFmt, p1, p2, p3, p4, p5) ((void)0)
  77. #define AssertFL0(szFile, iLine, f, szFmt) ((void)0)
  78. #else //!defined(DEBUG) && !defined(DEBUGASSERT)
  79. #ifndef THIS_FILE
  80. #define THIS_FILE __FILE__
  81. #endif
  82. #define Verify(f) Assert(f)
  83. DBG_APIV(void) DbgAssert(LPCTSTR szFileName, int iLine, LPCTSTR szFmt, ...);
  84. // If you use the utilna.lib version of util (No Assert), you must define
  85. // the following function
  86. void DoAssert(LPCSTR szFile, int iLine, LPCSTR szAssert);
  87. #ifdef FDBGFALSE_API
  88. DBG_API(BOOL) FDbgFalse(void);
  89. #else
  90. #define FDbgFalse() (0)
  91. #endif
  92. #define Assert(f) \
  93. do { DBG_STRING(_sz, #f) \
  94. DBG_STRING(_szFmt, "%s") \
  95. if (!(f)) DbgAssert(THIS_FILE, __LINE__,_szFmt,(LPSTR)_sz); } while (FDbgFalse())
  96. #define Assert0(f, szFmt) \
  97. do { DBG_STRING(_sz, szFmt)\
  98. if (!(f)) DbgAssert(THIS_FILE, __LINE__, _sz); } while (FDbgFalse())
  99. #define Assert1(f, szFmt, p1) \
  100. do { DBG_STRING(_sz, szFmt)\
  101. if (!(f)) DbgAssert(THIS_FILE, __LINE__, _sz, p1); } while (FDbgFalse())
  102. #define Assert2(f, szFmt, p1, p2) \
  103. do { DBG_STRING(_sz, szFmt)\
  104. if (!(f)) DbgAssert(THIS_FILE, __LINE__, _sz, p1, p2); } while (FDbgFalse())
  105. #define Assert3(f, szFmt, p1, p2, p3) \
  106. do { DBG_STRING(_sz, szFmt)\
  107. if (!(f)) DbgAssert(THIS_FILE, __LINE__, _sz, p1, p2, p3); } while (FDbgFalse())
  108. #define Assert4(f, szFmt, p1, p2, p3, p4) \
  109. do { DBG_STRING(_sz, szFmt)\
  110. if (!(f)) DbgAssert(THIS_FILE, __LINE__, _sz, p1, p2, p3, p4); } while (FDbgFalse())
  111. #define Assert5(f, szFmt, p1, p2, p3, p4, p5) \
  112. do { DBG_STRING(_sz, szFmt)\
  113. if (!(f)) DbgAssert(THIS_FILE, __LINE__, _sz, p1, p2, p3, p4, p5); } while (FDbgFalse())
  114. #define AssertFL0(szFile, iLine, f, szFmt) \
  115. do { DBG_STRING(_sz, szFmt)\
  116. if (!(f)) DbgAssert(szFile, iLine, _sz); } while (FDbgFalse())
  117. #endif //else - !defined(DEBUG) && !defined(DEBUGASSERT)
  118. /*---------------------------------------------------------------------------
  119. Trace
  120. ---------------------------------------------------------------------------*/
  121. #if !defined(DEBUG) && !defined(DEBUGTRACE)
  122. #ifdef __cplusplus
  123. inline void CDECL DbgTrace(LPTSTR, ...) {}
  124. #define Trace_ 1 ? (void)0 : ::DbgTrace
  125. #endif
  126. #define ODS(sz) /* nothing */
  127. #define Trace0(szFmt) ((void)0)
  128. #define Trace1(szFmt, p1) ((void)0)
  129. #define Trace2(szFmt, p1, p2) ((void)0)
  130. #define Trace3(szFmt, p1, p2, p3) ((void)0)
  131. #define Trace4(szFmt, p1, p2, p3, p4) ((void)0)
  132. #define Trace5(szFmt, p1, p2, p3, p4, p5) ((void)0)
  133. #define TraceN0(szFmt) ((void)0)
  134. #define TraceN1(szFmt, p1) ((void)0)
  135. #define TraceN2(szFmt, p1, p2) ((void)0)
  136. #define TraceN3(szFmt, p1, p2, p3) ((void)0)
  137. #define TraceN4(szFmt, p1, p2, p3, p4) ((void)0)
  138. #define TraceN5(szFmt, p1, p2, p3, p4, p5) ((void)0)
  139. #define DBG_PROC_ENTRY(szFunctionName) /* nothing */
  140. #else //!defined(DEBUG) && !defined(DEBUGTRACE)
  141. DBG_API(void) OutputTrace(LPCTSTR szTrace);
  142. DBG_APIV(void) DbgTrace(LPTSTR szFormat, ...);
  143. DBG_API(void) DbgTraceV(LPCTSTR szFormat, char FAR *pvargs);
  144. #define ODS(sz) OutputDebugString(sz)
  145. // Trace_ can be called if you are too lazy to count your arguments and call
  146. // the appropriate TraceN macro.
  147. #define Trace_ ::DbgTrace
  148. #define Trace0(szFmt) \
  149. do { DBG_STRING_NL(_sz, szFmt) DbgTrace(_sz); } while (FDbgFalse())
  150. #define Trace1(szFmt, p1) \
  151. do { DBG_STRING_NL(_sz, szFmt) DbgTrace(_sz, p1); } while (FDbgFalse())
  152. #define Trace2(szFmt, p1, p2) \
  153. do { DBG_STRING_NL(_sz, szFmt) DbgTrace(_sz, p1, p2); } while (FDbgFalse())
  154. #define Trace3(szFmt, p1, p2, p3) \
  155. do { DBG_STRING_NL(_sz, szFmt) DbgTrace(_sz, p1, p2, p3); } while (FDbgFalse())
  156. #define Trace4(szFmt, p1, p2, p3, p4) \
  157. do { DBG_STRING_NL(_sz, szFmt) DbgTrace(_sz, p1, p2, p3, p4); } while (FDbgFalse())
  158. #define Trace5(szFmt, p1, p2, p3, p4, p5) \
  159. do { DBG_STRING_NL(_sz, szFmt) DbgTrace(_sz, p1, p2, p3, p4, p5); } while (FDbgFalse())
  160. #define TraceN0(szFmt) \
  161. do { DBG_STRING(_sz, szFmt) DbgTrace(_sz); } while (FDbgFalse())
  162. #define TraceN1(szFmt, p1) \
  163. do { DBG_STRING(_sz, szFmt) DbgTrace(_sz, p1); } while (FDbgFalse())
  164. #define TraceN2(szFmt, p1, p2) \
  165. do { DBG_STRING(_sz, szFmt) DbgTrace(_sz, p1, p2); } while (FDbgFalse())
  166. #define TraceN3(szFmt, p1, p2, p3) \
  167. do { DBG_STRING(_sz, szFmt) DbgTrace(_sz, p1, p2, p3); } while (FDbgFalse())
  168. #define TraceN4(szFmt, p1, p2, p3, p4) \
  169. do { DBG_STRING(_sz, szFmt) DbgTrace(_sz, p1, p2, p3, p4); } while (FDbgFalse())
  170. #define TraceN5(szFmt, p1, p2, p3, p4, p5) \
  171. do { DBG_STRING(_sz, szFmt) DbgTrace(_sz, p1, p2, p3, p4, p5); } while (FDbgFalse())
  172. #ifndef NOENTRYEXITTRACE
  173. //
  174. // @class This class is used in the DBG_PROC_ENTRY macro below.
  175. //
  176. class DbgProcEntryClass
  177. {
  178. public:
  179. DbgProcEntryClass(LPCSTR szFunctionName) { m_lpszName = szFunctionName; Trace1("> Enter %s", szFunctionName); }
  180. ~DbgProcEntryClass() { Trace1("< Exit %s", m_lpszName); }
  181. private:
  182. LPCSTR m_lpszName;
  183. };
  184. //
  185. // @func Macro that causes the name of a function to get printed to debug output when the function is entered
  186. // and when it is exited. This is done by using C++ contructor and destructor. Place the call to DBG_PROC_ENTRY
  187. // at the to of each function that you wish to see debug traces for its entry and exit. The uCategory parameter
  188. // is used to clasify the module that this function is in.
  189. //
  190. #define DBG_PROC_ENTRY(szFunctionName) DbgProcEntryClass _DbgProcEntryClassObject(szFunctionName)
  191. #else
  192. #define DBG_PROC_ENTRY(szFunctionName) /* nothing */
  193. #endif //NOENTRYEXITTRACE
  194. #endif //else - !defined(DEBUG) && !defined(DEBUGTRACE)
  195. /*---------------------------------------------------------------------------
  196. Debug Options Structure and APIs
  197. ---------------------------------------------------------------------------*/
  198. #ifdef DEBUG
  199. typedef struct dbiTag
  200. {
  201. // Trace enable
  202. BOOL fDoTrace;
  203. // Startup with NO tls trace buffering
  204. int itlsTraceRGB;
  205. // No special trace function (defaults to OutputDebugString if NULL)
  206. void (CALLBACK * pfnTrace)(LPCTSTR);
  207. // UI Assert enable (determines whether DoAssert will be called)
  208. // Asserts will always be output as Trace (as per trace settings)
  209. BOOL fShowAsserts;
  210. // Number of asserts since startup
  211. ULONG cAssert;
  212. // Trigger assert on allocation failure
  213. BOOL fAssertOnAllocFail;
  214. // This setting determines whether an assert calls DbgStop,
  215. // which triggers an INT 3. If no debugger is running, the INT 3
  216. // is handled internally, and execution continues.
  217. BOOL fStopOnAssert;
  218. } DebugInfo;
  219. typedef struct
  220. {
  221. DWORD cchBuf;
  222. DWORD ichStart;
  223. DWORD ichEnd;
  224. char rgch[1];
  225. } DbgTraceBuf;
  226. extern DebugInfo g_dbi;
  227. #endif
  228. /*---------------------------------------------------------------------------
  229. Misc
  230. ---------------------------------------------------------------------------*/
  231. #ifdef DEBUG
  232. DBG_API(void) DbgStop(void);
  233. DBG_API(BOOL) FDbgFail(void);
  234. DBG_API(long) DbgSetFail(long iFail);
  235. DBG_API(long) DbgGetFail();
  236. // Call this function first with (fSecondChunk = FALSE), then with
  237. // (fSecondChunk = TRUE) to get the full trace buffer output
  238. // If TLS trace buffering is not enabled, these will return error strings.
  239. #ifdef __cplusplus
  240. #define ITLSTRACE itlsTrace = (DWORD)-1
  241. #endif
  242. DBG_API(DWORD) DbgSetThreadTraceBuffer(DWORD ITLSTRACE);
  243. DBG_API(const char *) DbgGetTraceBuffer(BOOL fSecondChunk);
  244. DBG_API(BOOL) DbgSetTraceBuffer(void *rgbTrace, int cbTrace);
  245. #endif //DEBUG
  246. #ifdef __cplusplus
  247. } // extern "C"
  248. #endif
  249. #endif // _DBGUTIL_H