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.

480 lines
15 KiB

  1. //====== Assertion/Debug output APIs =================================
  2. #undef CDECL
  3. #define CDECL _cdecl
  4. #if defined(DECLARE_DEBUG) && defined(DEBUG)
  5. //
  6. // Declare module-specific debug strings
  7. //
  8. // When including this header in your private header file, do not
  9. // define DECLARE_DEBUG. But do define DECLARE_DEBUG in one of the
  10. // source files in your project, and then include this header file.
  11. //
  12. // You may also define the following:
  13. //
  14. // SZ_DEBUGINI - the .ini file used to set debug flags
  15. // SZ_DEBUGSECTION - the section in the .ini file specific to
  16. // the module component.
  17. // SZ_MODULE - ansi version of the name of your module.
  18. //
  19. //
  20. // (These are deliberately CHAR)
  21. EXTERN_C const CHAR FAR c_szCcshellIniFile[] = SZ_DEBUGINI;
  22. EXTERN_C const CHAR FAR c_szCcshellIniSecDebug[] = SZ_DEBUGSECTION;
  23. EXTERN_C const WCHAR FAR c_wszTrace[] = L"t " TEXTW(SZ_MODULE) L" ";
  24. EXTERN_C const WCHAR FAR c_wszErrorDbg[] = L"err " TEXTW(SZ_MODULE) L" ";
  25. EXTERN_C const WCHAR FAR c_wszWarningDbg[] = L"wn " TEXTW(SZ_MODULE) L" ";
  26. EXTERN_C const WCHAR FAR c_wszAssertMsg[] = TEXTW(SZ_MODULE) L" Assert: ";
  27. EXTERN_C const WCHAR FAR c_wszAssertFailed[] = TEXTW(SZ_MODULE) L" Assert %s, line %d: (%s)\r\n";
  28. // (These are deliberately CHAR)
  29. EXTERN_C const CHAR FAR c_szTrace[] = "t " SZ_MODULE " ";
  30. EXTERN_C const CHAR FAR c_szErrorDbg[] = "err " SZ_MODULE " ";
  31. EXTERN_C const CHAR FAR c_szWarningDbg[] = "wn " SZ_MODULE " ";
  32. EXTERN_C const CHAR FAR c_szAssertMsg[] = SZ_MODULE " Assert: ";
  33. EXTERN_C const CHAR FAR c_szAssertFailed[] = SZ_MODULE " Assert %s, line %d: (%s)\r\n";
  34. #endif // DECLARE_DEBUG && DEBUG
  35. #if defined(DECLARE_DEBUG) && defined(PRODUCT_PROF)
  36. EXTERN_C const CHAR FAR c_szCcshellIniFile[] = SZ_DEBUGINI;
  37. EXTERN_C const CHAR FAR c_szCcshellIniSecDebug[] = SZ_DEBUGSECTION;
  38. #endif
  39. #ifdef __cplusplus
  40. extern "C" {
  41. #endif
  42. #if !defined(DECLARE_DEBUG)
  43. //
  44. // Debug macros and validation code
  45. //
  46. #undef Assert
  47. #undef AssertE
  48. #undef AssertMsg
  49. #undef AssertStrLen
  50. #undef DebugMsg
  51. #undef FullDebugMsg
  52. #undef ASSERT
  53. #undef EVAL
  54. // Access these globals to determine which debug flags are set.
  55. // These globals are modified by CcshellGetDebugFlags(), which
  56. // reads an .ini file and sets the appropriate flags.
  57. //
  58. // g_dwDumpFlags - bits are application specific. Typically
  59. // used for dumping structures.
  60. // g_dwBreakFlags - uses BF_* flags. The remaining bits are
  61. // application specific. Used to determine
  62. // when to break into the debugger.
  63. // g_dwTraceFlags - uses TF_* flags. The remaining bits are
  64. // application specific. Used to display
  65. // debug trace messages.
  66. // g_dwFuncTraceFlags - bits are application specific. When
  67. // TF_FUNC is set, CcshellFuncMsg uses this
  68. // value to determine which function traces
  69. // to display.
  70. // g_dwProtoype - bits are application specific. Use it for
  71. // anything.
  72. // g_dwProfileCAP - bits are application specific. Used to
  73. // control ICECAP profiling.
  74. //
  75. extern DWORD g_dwDumpFlags;
  76. extern DWORD g_dwBreakFlags;
  77. extern DWORD g_dwTraceFlags;
  78. #ifdef DEBUG
  79. extern DWORD g_dwPrototype;
  80. #else
  81. #define g_dwPrototype 0
  82. #endif
  83. extern DWORD g_dwFuncTraceFlags;
  84. #if defined(DEBUG) || defined(PRODUCT_PROF)
  85. BOOL CcshellGetDebugFlags(void);
  86. #else
  87. #define CcshellGetDebugFlags() 0
  88. #endif
  89. // Break flags for g_dwBreakFlags
  90. #define BF_ONVALIDATE 0x00000001 // Break on assertions or validation
  91. #define BF_ONAPIENTER 0x00000002 // Break on entering an API
  92. #define BF_ONERRORMSG 0x00000004 // Break on TF_ERROR
  93. #define BF_ONWARNMSG 0x00000008 // Break on TF_WARNING
  94. // Trace flags for g_dwTraceFlags
  95. #define TF_ALWAYS 0xFFFFFFFF
  96. #define TF_NEVER 0x00000000
  97. #define TF_WARNING 0x00000001
  98. #define TF_ERROR 0x00000002
  99. #define TF_GENERAL 0x00000004 // Standard messages
  100. #define TF_FUNC 0x00000008 // Trace function calls
  101. // (Upper 28 bits reserved for custom use per-module)
  102. // Old, archaic debug flags.
  103. // BUGBUG (scotth): the following flags will be phased out over time.
  104. #ifdef DM_TRACE
  105. #undef DM_TRACE
  106. #undef DM_WARNING
  107. #undef DM_ERROR
  108. #endif
  109. #define DM_TRACE TF_GENERAL // OBSOLETE Trace messages
  110. #define DM_WARNING TF_WARNING // OBSOLETE Warning
  111. #define DM_ERROR TF_ERROR // OBSOLETE Error
  112. // Use this macro to declare message text that will be placed
  113. // in the CODE segment (useful if DS is getting full)
  114. //
  115. // Ex: DEBUGTEXT(szMsg, "Invalid whatever: %d");
  116. //
  117. #define DEBUGTEXT(sz, msg) /* ;Internal */ \
  118. static const TCHAR sz[] = msg;
  119. #ifndef NOSHELLDEBUG // Others have own versions of these.
  120. #ifdef DEBUG
  121. #ifdef WIN16
  122. #define DEBUG_BREAK { _asm int 3 }
  123. #else
  124. #ifdef _X86_
  125. // Use int 3 so we stop immediately in the source
  126. #define DEBUG_BREAK { _asm int 3 }
  127. #else
  128. #define DEBUG_BREAK DebugBreak();
  129. #endif
  130. #endif
  131. // Prototypes for debug functions
  132. void CcshellStackEnter(void);
  133. void CcshellStackLeave(void);
  134. BOOL CDECL CcshellAssertFailedA(LPCSTR szFile, int line, LPCSTR pszEval, BOOL bBreak);
  135. BOOL CDECL CcshellAssertFailedW(LPCWSTR szFile, int line, LPCWSTR pwszEval, BOOL bBreak);
  136. void CDECL CcshellDebugMsgW(DWORD mask, LPCWSTR pszMsg, ...);
  137. void CDECL CcshellDebugMsgA(DWORD mask, LPCSTR pszMsg, ...);
  138. void CDECL CcshellFuncMsgW(DWORD mask, LPCWSTR pszMsg, ...);
  139. void CDECL CcshellFuncMsgA(DWORD mask, LPCSTR pszMsg, ...);
  140. void CDECL CcshellAssertMsgW(BOOL bAssert, LPCWSTR pszMsg, ...);
  141. void CDECL CcshellAssertMsgA(BOOL bAssert, LPCSTR pszMsg, ...);
  142. void CDECL _AssertMsgA(BOOL f, LPCSTR pszMsg, ...);
  143. void CDECL _AssertMsgW(BOOL f, LPCWSTR pszMsg, ...);
  144. void CDECL _DebugMsgA(DWORD flag, LPCSTR psz, ...);
  145. void CDECL _DebugMsgW(DWORD flag, LPCWSTR psz, ...);
  146. void _AssertStrLenA(LPCSTR pszStr, int iLen);
  147. void _AssertStrLenW(LPCWSTR pwzStr, int iLen);
  148. #ifdef UNICODE
  149. #define CcshellAssertFailed CcshellAssertFailedW
  150. #define CcshellDebugMsg CcshellDebugMsgW
  151. #define CcshellFuncMsg CcshellFuncMsgW
  152. #define CcshellAssertMsg CcshellAssertMsgW
  153. #define _AssertMsg _AssertMsgW
  154. #define _AssertStrLen _AssertStrLenW
  155. #define _DebugMsg _DebugMsgW
  156. #else
  157. #define CcshellAssertFailed CcshellAssertFailedA
  158. #define CcshellDebugMsg CcshellDebugMsgA
  159. #define CcshellFuncMsg CcshellFuncMsgA
  160. #define CcshellAssertMsg CcshellAssertMsgA
  161. #define _AssertMsg _AssertMsgA
  162. #define _AssertStrLen _AssertStrLenA
  163. #define _DebugMsg _DebugMsgA
  164. #endif
  165. // Explanation of debug macros:
  166. //
  167. // ----
  168. // Assert(f)
  169. // ASSERT(f)
  170. //
  171. // Generates a "Assert file.c, line x (eval)" message if f is NOT true.
  172. // The g_dwBreakFlags global governs whether the function DebugBreaks.
  173. //
  174. // ----
  175. // AssertE(f)
  176. //
  177. // Works like Assert, except (f) is also executed in the retail
  178. // version as well.
  179. //
  180. // ----
  181. // EVAL(f)
  182. //
  183. // Evaluates the expression (f). The expression is always evaluated,
  184. // even in retail builds. But the macro only asserts in the debug
  185. // build. This macro may only be used on logical expressions, eg:
  186. //
  187. // if (EVAL(exp))
  188. // // do something
  189. //
  190. // ----
  191. // TraceMsg(mask, sz, args...)
  192. //
  193. // Generate wsprintf-formatted msg using specified trace mask.
  194. // The g_dwTraceFlags global governs whether message is displayed.
  195. //
  196. // The sz parameter is always ANSI; TraceMsg correctly converts it
  197. // to unicode if necessary. This is so you don't have to wrap your
  198. // debug strings with TEXT().
  199. //
  200. // ----
  201. // DebugMsg(mask, sz, args...)
  202. //
  203. // OBSOLETE!
  204. // Like TraceMsg, except you must wrap the sz parameter with TEXT().
  205. //
  206. // ----
  207. // AssertMsg(bAssert, sz, args...)
  208. //
  209. // Generate wsprintf-formatted msg if the assertion is false.
  210. // The g_dwBreakFlags global governs whether the function DebugBreaks.
  211. //
  212. // The sz parameter is always ANSI; AssertMsg correctly converts it
  213. // to unicode if necessary. This is so you don't have to wrap your
  214. // debug strings with TEXT().
  215. //
  216. #define ASSERT(f) \
  217. { \
  218. DEBUGTEXT(szFile, TEXT(__FILE__)); \
  219. if (!(f) && CcshellAssertFailed(szFile, __LINE__, TEXT(#f), FALSE)) \
  220. DEBUG_BREAK; \
  221. }
  222. #ifdef DISALLOW_Assert
  223. #define Assert(f) Dont_use_Assert___Use_ASSERT
  224. #else
  225. #define Assert(f) ASSERT(f)
  226. #endif
  227. #define AssertE(f) ASSERT(f)
  228. #define EVAL(exp) \
  229. ((exp) || (CcshellAssertFailed(TEXT(__FILE__), __LINE__, TEXT(#exp), TRUE), 0))
  230. // Use TraceMsg instead of DebugMsg. DebugMsg is obsolete.
  231. #define AssertMsg _AssertMsg
  232. #define AssertStrLen _AssertStrLen
  233. #define AssertStrLenA _AssertStrLenA
  234. #define AssertStrLenW _AssertStrLenW
  235. #ifdef DISALLOW_DebugMsg
  236. #define DebugMsg Dont_use_DebugMsg___Use_TraceMsg
  237. #else
  238. #define DebugMsg _DebugMsg
  239. #endif
  240. #ifdef FULL_DEBUG
  241. #define FullDebugMsg _DebugMsg
  242. #else
  243. #define FullDebugMsg 1 ? (void)0 : (void)
  244. #endif
  245. #define Dbg_SafeStrA(psz) (SAFECAST(psz, LPCSTR), (psz) ? (psz) : "NULL string")
  246. #ifndef WIN16
  247. #define Dbg_SafeStrW(psz) (SAFECAST(psz, LPCWSTR), (psz) ? (psz) : L"NULL string")
  248. #else
  249. #define Dbg_SafeStrW(psz) (SAFECAST(psz, LPCWSTR), (psz) ? (psz) : TEXT("NULL string"))
  250. #endif
  251. #ifdef UNICODE
  252. #define Dbg_SafeStr Dbg_SafeStrW
  253. #else
  254. #define Dbg_SafeStr Dbg_SafeStrA
  255. #endif
  256. #define ASSERT_MSGW CcshellAssertMsgW
  257. #define ASSERT_MSGA CcshellAssertMsgA
  258. #define ASSERT_MSG CcshellAssertMsg
  259. #define TraceMsgW CcshellDebugMsgW
  260. #define TraceMsgA CcshellDebugMsgA
  261. #define TraceMsg CcshellDebugMsg
  262. #define FUNC_MSG CcshellFuncMsg
  263. // Debug function enter
  264. // DBG_ENTER(flag, fn) -- Generates a function entry debug spew for
  265. // a function
  266. //
  267. #define DBG_ENTER(flagFTF, fn) \
  268. (FUNC_MSG(flagFTF, " > " #fn "()"), \
  269. CcshellStackEnter())
  270. // DBG_ENTER_TYPE(flag, fn, dw, pfnStrFromType) -- Generates a function entry debug
  271. // spew for functions that accept <type>.
  272. //
  273. #define DBG_ENTER_TYPE(flagFTF, fn, dw, pfnStrFromType) \
  274. (FUNC_MSG(flagFTF, " < " #fn "(..., %s, ...)", (LPCTSTR)pfnStrFromType(dw)), \
  275. CcshellStackEnter())
  276. // DBG_ENTER_SZ(flag, fn, sz) -- Generates a function entry debug spew for
  277. // a function that accepts a string as one of its
  278. // parameters.
  279. //
  280. #define DBG_ENTER_SZ(flagFTF, fn, sz) \
  281. (FUNC_MSG(flagFTF, " > " #fn "(..., \"%s\",...)", Dbg_SafeStr(sz)), \
  282. CcshellStackEnter())
  283. // Debug function exit
  284. // DBG_EXIT(flag, fn) -- Generates a function exit debug spew
  285. //
  286. #define DBG_EXIT(flagFTF, fn) \
  287. (CcshellStackLeave(), \
  288. FUNC_MSG(flagFTF, " < " #fn "()"))
  289. // DBG_EXIT_TYPE(flag, fn, dw, pfnStrFromType) -- Generates a function exit debug
  290. // spew for functions that return <type>.
  291. //
  292. #define DBG_EXIT_TYPE(flagFTF, fn, dw, pfnStrFromType) \
  293. (CcshellStackLeave(), \
  294. FUNC_MSG(flagFTF, " < " #fn "() with %s", (LPCTSTR)pfnStrFromType(dw)))
  295. // DBG_EXIT_INT(flag, fn, us) -- Generates a function exit debug spew for
  296. // functions that return an INT.
  297. //
  298. #define DBG_EXIT_INT(flagFTF, fn, n) \
  299. (CcshellStackLeave(), \
  300. FUNC_MSG(flagFTF, " < " #fn "() with %d", (int)(n)))
  301. // DBG_EXIT_BOOL(flag, fn, b) -- Generates a function exit debug spew for
  302. // functions that return a boolean.
  303. //
  304. #define DBG_EXIT_BOOL(flagFTF, fn, b) \
  305. (CcshellStackLeave(), \
  306. FUNC_MSG(flagFTF, " < " #fn "() with %s", (b) ? (LPTSTR)TEXT("TRUE") : (LPTSTR)TEXT("FALSE")))
  307. // DBG_EXIT_UL(flag, fn, ul) -- Generates a function exit debug spew for
  308. // functions that return a ULONG.
  309. //
  310. #define DBG_EXIT_UL(flagFTF, fn, ul) \
  311. (CcshellStackLeave(), \
  312. FUNC_MSG(flagFTF, " < " #fn "() with %#08lx", (ULONG)(ul)))
  313. #define DBG_EXIT_DWORD DBG_EXIT_UL
  314. // DBG_EXIT_HRES(flag, fn, hres) -- Generates a function exit debug spew for
  315. // functions that return an HRESULT.
  316. //
  317. #define DBG_EXIT_HRES(flagFTF, fn, hres) DBG_EXIT_TYPE(flagFTF, fn, hres, Dbg_GetHRESULTName)
  318. #else // DEBUG
  319. #define Assert(f)
  320. #define AssertE(f) (f)
  321. #define ASSERT(f)
  322. #define AssertMsg 1 ? (void)0 : (void)
  323. #define AssertStrLen(lpStr, iLen)
  324. #define DebugMsg 1 ? (void)0 : (void)
  325. #define FullDebugMsg 1 ? (void)0 : (void)
  326. #define EVAL(exp) ((exp) != 0)
  327. #define Dbg_SafeStr 1 ? (void)0 : (void)
  328. #define TraceMsgA 1 ? (void)0 : (void)
  329. #define TraceMsgW 1 ? (void)0 : (void)
  330. #ifdef UNICODE
  331. #define TraceMsg TraceMsgW
  332. #else
  333. #define TraceMsg TraceMsgA
  334. #endif
  335. #define FUNC_MSG 1 ? (void)0 : (void)
  336. #define ASSERT_MSGA TraceMsgA
  337. #define ASSERT_MSGW TraceMsgW
  338. #define ASSERT_MSG TraceMsg
  339. #define DBG_ENTER(flagFTF, fn)
  340. #define DBG_ENTER_TYPE(flagFTF, fn, dw, pfn)
  341. #define DBG_ENTER_SZ(flagFTF, fn, sz)
  342. #define DBG_EXIT(flagFTF, fn)
  343. #define DBG_EXIT_INT(flagFTF, fn, n)
  344. #define DBG_EXIT_BOOL(flagFTF, fn, b)
  345. #define DBG_EXIT_UL(flagFTF, fn, ul)
  346. #define DBG_EXIT_DWORD DBG_EXIT_UL
  347. #define DBG_EXIT_TYPE(flagFTF, fn, dw, pfn)
  348. #define DBG_EXIT_HRES(flagFTF, fn, hres)
  349. #endif // DEBUG
  350. #endif // NOSHELLDEBUG
  351. //
  352. // Debug dump helper functions
  353. //
  354. #ifdef DEBUG
  355. LPCTSTR Dbg_GetCFName(UINT ucf);
  356. LPCTSTR Dbg_GetHRESULTName(HRESULT hr);
  357. LPCTSTR Dbg_GetREFIIDName(REFIID riid);
  358. LPCTSTR Dbg_GetVTName(VARTYPE vt);
  359. #else
  360. #define Dbg_GetCFName(ucf) (void)0
  361. #define Dbg_GetHRESULTName(hr) (void)0
  362. #define Dbg_GetREFIIDName(riid) (void)0
  363. #define Dbg_GetVTName(vt) (void)0
  364. #endif // DEBUG
  365. // Parameter validation macros
  366. #include "validate.h"
  367. #endif // DECLARE_DEBUG
  368. #ifdef PRODUCT_PROF
  369. int __stdcall StartCAP(void); // start profiling
  370. int __stdcall StopCAP(void); // stop profiling until StartCAP
  371. int __stdcall SuspendCAP(void); // suspend profiling until ResumeCAP
  372. int __stdcall ResumeCAP(void); // resume profiling
  373. int __stdcall StartCAPAll(void); // process-wide start profiling
  374. int __stdcall StopCAPAll(void); // process-wide stop profiling
  375. int __stdcall SuspendCAPAll(void); // process-wide suspend profiling
  376. int __stdcall ResumeCAPAll(void); // process-wide resume profiling
  377. void __stdcall MarkCAP(long lMark); // write mark to MEA
  378. extern DWORD g_dwProfileCAP;
  379. #else
  380. #define StartCAP() 0
  381. #define StopCAP() 0
  382. #define SuspendCAP() 0
  383. #define ResumeCAP() 0
  384. #define StartCAPAll() 0
  385. #define StopCAPAll() 0
  386. #define SuspendCAPAll() 0
  387. #define ResumeCAPAll() 0
  388. #define MarkCAP(n) 0
  389. #define g_dwProfileCAP 0
  390. #endif
  391. #ifdef __cplusplus
  392. };
  393. #endif