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.

342 lines
8.2 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. dbgstate.hxx
  6. Abstract:
  7. auto log
  8. Author:
  9. Larry Zhu (LZhu) December 8, 2001
  10. Revision History:
  11. --*/
  12. #ifndef _DBGSTATE_HXX_
  13. #define _DBGSTATE_HXX_
  14. /********************************************************************
  15. Automatic status logging.
  16. Use TNtStatus instead of NTSTATUS:
  17. NTSTATUS Status; -> TNtStatus Status;
  18. NTSTATUS Status = ERROR_ACCESS_DENIED -> TNtStatus Status = ERROR_ACCESS_DENIED;
  19. Status = ERROR_SUCCESS -> Status DBGNOCHK = ERROR_SUCCESS;
  20. Status = xxx; -> Status DBGCHK = xxx;
  21. if(Status){ -> if(Status != 0){
  22. Anytime Status is set, the DBGCHK macro must be added before
  23. the '=.'
  24. If the variable must be set to a failure value at compile time
  25. and logging is therefore not needed, then the DBGNOCHK macro
  26. should be used.
  27. There is a method to control the wether a message is
  28. printed if an error value is assigned as well as 3 "benign"
  29. errors that can be ignored.
  30. DBGCFG(Status, DBG_ERROR);
  31. DBGCFG1(Status, DBG_ERROR, ERROR_ACCESS_DENIED);
  32. DBGCFG2(Status, DBG_ERROR, ERROR_INVALID_HANDLE, ERROR_ARENA_TRASHED);
  33. DBGCFG3(Status, DBG_ERROR, ERROR_INVALID_HANDLE, ERROR_ARENA_TRASHED, ERROR_NOT_ENOUGH_MEMORY);
  34. ********************************************************************/
  35. #ifndef COUNTOF
  36. #define COUNTOF(s) ( sizeof( (s) ) / sizeof( *(s) ) )
  37. #endif // COUNTOF
  38. #ifdef DBG
  39. #include <eh.h>
  40. #include <tchar.h>
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <assert.h>
  44. #ifndef ASSERT
  45. #define ASSERT( exp ) assert((exp))
  46. #endif // #ifndef ASSERT
  47. #define DBGCHK .pSetInfo(__LINE__, TEXT(__FILE__))
  48. #define DBGNOCHK .pNoChk()
  49. #define DBGCFG1(TStatusX, Safe1) (TStatusX).pConfig((Safe1))
  50. #define DBGCFG2(TStatusX, Safe1, Safe2) (TStatusX).pConfig((Safe1), (Safe2))
  51. #define DBGCFG3(TStatusX, Safe1, Safe2, Safe3) (TStatusX).pConfig((Safe1), (Safe2), (Safe3))
  52. /********************************************************************
  53. output macros and functions
  54. ********************************************************************/
  55. typedef struct _TDbgGlobals
  56. {
  57. UINT uMajorVersion;
  58. UINT uMinorVersion;
  59. PCTSTR pszDbgPrompt;
  60. } TDbgGlobals;
  61. extern TDbgGlobals g_DbgGlobals;
  62. VOID AutoLogOutputDebugStringPrintf(
  63. IN PCTSTR pszFmt,
  64. IN ...
  65. );
  66. #define AUTO_LOG(Msg) do { AutoLogOutputDebugStringPrintf Msg; } while (0)
  67. #define AUTO_LOG_OPEN(pszPrompt) do { g_DbgGlobals.pszDbgPrompt = (pszPrompt); } while (0)
  68. #define AUTO_LOG_CLOSE() do { g_DbgGlobals.pszDbgPrompt = NULL; } while (0)
  69. //
  70. // exception handling stuff
  71. //
  72. VOID __cdecl
  73. DbgStateC2CppExceptionTransFunc(
  74. IN UINT u,
  75. IN EXCEPTION_POINTERS* pExp
  76. );
  77. #define SET_DBGSTATE_TRANS_FUNC(pFunc) _set_se_translator((pFunc))
  78. /********************************************************************
  79. Base class
  80. ********************************************************************/
  81. template <typename TStatusCode>
  82. class TStatusBase {
  83. public:
  84. enum { kUnInitializedValue = 0xabababab };
  85. TStatusBase&
  86. pSetInfo(
  87. IN UINT uLine,
  88. IN PCTSTR pszFile
  89. )
  90. {
  91. m_uLine = uLine;
  92. m_pszFile = pszFile;
  93. return (TStatusBase&) *this;
  94. }
  95. TStatusBase&
  96. pNoChk(
  97. VOID
  98. )
  99. {
  100. m_pszFile = NULL;
  101. m_uLine = 0;
  102. return (TStatusBase&) *this;
  103. }
  104. VOID
  105. pConfig(
  106. IN TStatusCode StatusSafe1 = -1,
  107. IN TStatusCode StatusSafe2 = -1,
  108. IN TStatusCode StatusSafe3 = -1
  109. )
  110. {
  111. m_StatusSafe1 = StatusSafe1;
  112. m_StatusSafe2 = StatusSafe2;
  113. m_StatusSafe3 = StatusSafe3;
  114. }
  115. ///////////////////////////////////////////////////////////////////////////
  116. virtual
  117. ~TStatusBase(
  118. VOID
  119. )
  120. {
  121. }
  122. TStatusCode
  123. GetTStatusBase(
  124. VOID
  125. ) const
  126. {
  127. //
  128. // Assert if we are reading an UnInitalized variable.
  129. //
  130. if (m_Status == kUnInitializedValue)
  131. {
  132. AUTO_LOG((TEXT("***Read of UnInitialized TStatus variable!***\n")));
  133. ASSERT(FALSE);
  134. }
  135. //
  136. // Return the error value.
  137. //
  138. return m_Status;
  139. }
  140. operator TStatusCode(
  141. VOID
  142. ) const
  143. {
  144. return GetTStatusBase();
  145. }
  146. TStatusCode
  147. operator=(
  148. IN TStatusCode Status
  149. )
  150. {
  151. m_Status = Status;
  152. //
  153. // Do nothing if the file and line number are cleared.
  154. // This is the case when the NoChk method is used.
  155. //
  156. if (m_uLine && m_pszFile)
  157. {
  158. //
  159. // Check if we have an error, and it's not one of the accepted
  160. // "safe" errors.
  161. //
  162. if ( IsErrorSevereEnough() &&
  163. Status != m_StatusSafe1 &&
  164. Status != m_StatusSafe2 &&
  165. Status != m_StatusSafe3 )
  166. {
  167. DWORD dwPid = GetCurrentProcessId();
  168. DWORD dwTid = GetCurrentThreadId();
  169. TCHAR szBanner[MAX_PATH] = {0};
  170. _sntprintf(szBanner, COUNTOF(szBanner) - 1,
  171. g_DbgGlobals.pszDbgPrompt ? TEXT("[%d.%d %s] ") : TEXT("[%d.%d%s] "),
  172. dwPid, dwTid,
  173. g_DbgGlobals.pszDbgPrompt ? g_DbgGlobals.pszDbgPrompt : TEXT(""));
  174. AUTO_LOG((TEXT("%s[%s] %#x at %s %d\n"), szBanner, GetErrorServerityDescription(), m_Status, m_pszFile, m_uLine));
  175. }
  176. }
  177. return m_Status;
  178. }
  179. //////////////////////////////////////////////////////////////////////////
  180. virtual PCTSTR
  181. GetErrorServerityDescription(
  182. VOID
  183. ) const
  184. {
  185. return IsErrorSevereEnough() ? TEXT("ERROR") : TEXT("SUCCESSFUL");
  186. }
  187. virtual BOOL
  188. IsErrorSevereEnough(
  189. VOID
  190. ) const
  191. {
  192. return m_Status != 0; // 0 for success
  193. }
  194. /////////////////////////////////////////////////////////////////////////
  195. protected:
  196. TStatusBase(
  197. IN TStatusCode Status
  198. ) : m_Status(Status),
  199. m_StatusSafe1(-1),
  200. m_StatusSafe2(-1),
  201. m_StatusSafe3(-1),
  202. m_uLine(0),
  203. m_pszFile(NULL)
  204. {
  205. }
  206. private:
  207. TStatusCode m_Status;
  208. TStatusCode m_StatusSafe1;
  209. TStatusCode m_StatusSafe2;
  210. TStatusCode m_StatusSafe3;
  211. UINT m_uLine;
  212. PCTSTR m_pszFile;
  213. };
  214. /********************************************************************
  215. TStatusCode
  216. ********************************************************************/
  217. template <typename TStatusCode>
  218. class TStatusDerived : public TStatusBase<TStatusCode> {
  219. public:
  220. TStatusDerived(
  221. IN TStatusCode Status = kUnInitializedValue
  222. ): TStatusBase<TStatusCode>(Status)
  223. {
  224. }
  225. virtual
  226. ~TStatusDerived(
  227. VOID
  228. )
  229. {
  230. }
  231. private:
  232. TStatusDerived(const TStatusDerived& rhs);
  233. TStatusCode
  234. operator=(
  235. IN TStatusCode Status
  236. );
  237. };
  238. #else
  239. #define AUTO_LOG_LOG(Msg) // Empty
  240. #define AUTO_LOG_OPEN(pszPrompt) // Empty
  241. #define AUTO_LOG_CLOSE() // Empty
  242. /********************************************************************
  243. Non Debug version TStatusX
  244. ********************************************************************/
  245. #define DBGCHK // Empty
  246. #define DBGNOCHK // Empty
  247. #define DBGCFG(TStatusX) // Empty
  248. #define DBGCFG1(TStatusX, Safe1) // Empty
  249. #define DBGCFG2(TStatusX, Safe1, Safe2) // Empty
  250. #define DBGCFG3(TStatusX, Safe1, Safe2, Safe3) // Empty
  251. //
  252. // exception handling stuff
  253. //
  254. #define SET_DBGSTATE_TRANS_FUNC(pFunc) // Empty
  255. #endif // DBG
  256. #endif // _DBGSTATE_HXX_