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.

274 lines
6.9 KiB

  1. /*----------------------------------------------------------------------------
  2. dbgtrace.c
  3. Debug trace functions.
  4. Copyright (C) Microsoft Corporation, 1993 - 1999
  5. All rights reserved.
  6. Authors:
  7. suryanr Suryanarayanan Raman
  8. GaryBu Gary S. Burd
  9. History:
  10. 05/11/93 suryanr Created
  11. 06/18/93 GaryBu Convert to C.
  12. 07/21/93 KennT Code Reorg
  13. 07/26/94 SilvanaR Trace Buffer
  14. 27 oct 95 garykac DBCS_FILE_CHECK debug file: BEGIN_STRING_OK
  15. ----------------------------------------------------------------------------*/
  16. #include "stdafx.h"
  17. #include <string.h>
  18. #include <stdio.h>
  19. #include <stdarg.h>
  20. #include <time.h>
  21. #include <stdarg.h>
  22. #include <tchar.h>
  23. #include "dbgutil.h"
  24. #include "tfschar.h"
  25. #include "atlconv.h"
  26. #ifdef _DEBUG
  27. #define new DEBUG_NEW
  28. #undef THIS_FILE
  29. static char THIS_FILE[] = __FILE__;
  30. #endif
  31. #if 0
  32. DBG_API(BOOL) FDbgFalse(void)
  33. {
  34. return FALSE;
  35. }
  36. #endif
  37. #ifdef DEBUG
  38. /*!--------------------------------------------------------------------------
  39. DbgFmtPgm
  40. builds a string with the filename and line number
  41. Author: EricDav
  42. ---------------------------------------------------------------------------*/
  43. DBG_APIV(LPCTSTR) DbgFmtFileLine ( const char * szFn, int line )
  44. {
  45. USES_CONVERSION;
  46. const TCHAR * ptszFn = A2CT(szFn);
  47. const TCHAR * pszTail = ptszFn + ::_tcslen( ptszFn );
  48. static TCHAR szBuff [100];
  49. for ( ; pszTail > ptszFn ; pszTail-- )
  50. {
  51. if ( *pszTail == '\\' || *pszTail == ':' )
  52. {
  53. pszTail++;
  54. break;
  55. }
  56. }
  57. ::wsprintf( szBuff, _T("[%s:%d] "), pszTail, line );
  58. return szBuff;
  59. }
  60. /*!--------------------------------------------------------------------------
  61. DbgTrace
  62. Trace string with args.
  63. Author: suryanr
  64. ---------------------------------------------------------------------------*/
  65. DBG_APIV(void) DbgTrace(LPCTSTR szFileLine, LPTSTR szFormat, ...)
  66. {
  67. TCHAR szBuffer[1024];
  68. va_list args;
  69. va_start(args, szFormat);
  70. wvsprintf(szBuffer, szFormat, args);
  71. OutputDebugString(szFileLine);
  72. OutputDebugString(szBuffer);
  73. va_end(args);
  74. }
  75. #define MAX_ASSERT_INFO 32
  76. #define MAX_ASSERT_FILE_LEN 64
  77. struct ASSERT_INFO {
  78. char szFile[MAX_ASSERT_FILE_LEN];
  79. int iLine;
  80. };
  81. static ASSERT_INFO s_rgAssertInfo[MAX_ASSERT_INFO] = {0};
  82. static int s_iAssertInfo = 0;
  83. /*!--------------------------------------------------------------------------
  84. DbgAssert
  85. Display assert dialog.
  86. Author: GaryBu, kennt
  87. ---------------------------------------------------------------------------*/
  88. DBG_APIV(void) DbgAssert(LPCSTR szFile, int iLine, LPCTSTR szFmt, ...)
  89. {
  90. va_list arg;
  91. TCHAR sz[1024];
  92. int iloc;
  93. int ival;
  94. TCHAR *pch = sz;
  95. TCHAR *pchHead;
  96. static BOOL s_fInDbgAssert = FALSE;
  97. BOOL fQuit;
  98. MSG msgT;
  99. // -- begin Ctrl-Ignore support ---------------------------------------
  100. // check if this assert is disabled (user has hit Ctrl-Ignore on this
  101. // assert this session).
  102. for (int i = s_iAssertInfo; i--;)
  103. if (lstrcmpA(szFile, s_rgAssertInfo[i].szFile) == 0 &&
  104. iLine == s_rgAssertInfo[i].iLine)
  105. // this assert is disabled
  106. return;
  107. // -- end Ctrl-Ignore support -----------------------------------------
  108. DBG_STRING(szTitle, "NT Networking Snapin Assert")
  109. DBG_STRING(szFileLineFmt, "%S @ line %d\n\n")
  110. pch += wsprintf(pch, (LPCTSTR)szFileLineFmt, szFile, iLine);
  111. pchHead = pch;
  112. // Add location to the output.
  113. if (szFmt)
  114. {
  115. *pch++ = '"';
  116. va_start(arg, szFmt);
  117. pch += wvsprintf(pch, szFmt, arg);
  118. va_end(arg);
  119. // Remove trailing newlines...
  120. while (*(pch-1) == '\n')
  121. --pch;
  122. *pch++ = '"';
  123. *pch++ = '\n';
  124. }
  125. else
  126. *pch++ = ' ';
  127. if (s_fInDbgAssert)
  128. {
  129. *pch = 0;
  130. Trace1("Arrgg! Recursive assert: %s", (LPTSTR) sz);
  131. MessageBeep(0);MessageBeep(0);
  132. return;
  133. }
  134. s_fInDbgAssert = TRUE;
  135. *pch++ = '\n';
  136. *pch = 0;
  137. Trace2("%s: %s", (LPTSTR) szTitle, (LPTSTR) sz);
  138. repost_assert:
  139. // Is there a WM_QUIT message in the queue, if so remove it.
  140. #define WM_QUIT 0x0012
  141. fQuit = ::PeekMessage(&msgT, NULL, WM_QUIT, WM_QUIT, PM_REMOVE);
  142. ival = MessageBox(NULL, sz, szTitle,
  143. MB_TASKMODAL|MB_ICONHAND|MB_ABORTRETRYIGNORE|MB_DEFBUTTON3);
  144. // If there was a quit message, add it back into the queue
  145. if (fQuit)
  146. ::PostQuitMessage((int)msgT.wParam);
  147. switch (ival)
  148. {
  149. case 0:
  150. Trace0("Failed to create message box on assert.\n");
  151. // Fallthrough
  152. case IDRETRY:
  153. // Hard break to cause just-in-time to fire (DbgStop doesn't)
  154. s_fInDbgAssert = FALSE;
  155. DebugBreak();
  156. return;
  157. case IDIGNORE:
  158. // -- begin Shift-Ignore support ------------------------------
  159. // use Shift-Ignore to copy assert text to clipboard.
  160. if ((GetKeyState(VK_SHIFT) & 0x8000) != 0)
  161. {
  162. if (OpenClipboard(0))
  163. {
  164. HGLOBAL hData;
  165. LPTSTR lpstr;
  166. hData = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE,
  167. (lstrlen(sz)+1)*sizeof(TCHAR));
  168. if (hData)
  169. {
  170. lpstr = (LPTSTR)GlobalLock(hData);
  171. if (lpstr)
  172. {
  173. lstrcpy(lpstr, sz);
  174. GlobalUnlock(hData);
  175. EmptyClipboard();
  176. // Windows takes ownership of hData
  177. SetClipboardData(CF_TEXT, hData);
  178. }
  179. else
  180. {
  181. GlobalFree(hData);
  182. MessageBox(NULL, _T("Error locking memory handle."), szTitle, MB_OK);
  183. }
  184. }
  185. else
  186. MessageBox(NULL, _T("Not enough memory."), szTitle, MB_OK);
  187. CloseClipboard();
  188. }
  189. else
  190. MessageBox(NULL, _T("Cannot access clipboard."), szTitle, MB_OK);
  191. goto repost_assert;
  192. }
  193. // -- end Shift-Ignore support --------------------------------
  194. // -- begin Ctrl-Ignore support -------------------------------
  195. // check if user hit Ctrl-Ignore to disable this assert for the
  196. // rest of this session.
  197. if ((GetKeyState(VK_CONTROL) & 0x8000) != 0)
  198. if (s_iAssertInfo < MAX_ASSERT_INFO)
  199. {
  200. // add this assert to list of asserts to disable
  201. s_rgAssertInfo[s_iAssertInfo].iLine = iLine;
  202. lstrcpynA(s_rgAssertInfo[s_iAssertInfo].szFile, szFile, MAX_ASSERT_FILE_LEN);
  203. s_rgAssertInfo[s_iAssertInfo].szFile[MAX_ASSERT_FILE_LEN-1] = 0;
  204. s_iAssertInfo++;
  205. }
  206. else
  207. {
  208. // max asserts disabled already, warn user
  209. MessageBox(NULL, _T("Cannot disable that assert; ")
  210. _T("already disabled max number of asserts (32)."),
  211. szTitle, MB_OK);
  212. }
  213. // -- end Ctrl-Ignore support ---------------------------------
  214. s_fInDbgAssert = FALSE;
  215. return;
  216. case IDABORT:
  217. ExitProcess(1);
  218. break;
  219. }
  220. Trace1("Panic! Dropping out of DbgAssert: %s", (LPSTR) sz);
  221. s_fInDbgAssert = FALSE;
  222. // A generic way of bringing up the debugger
  223. DebugBreak();
  224. }
  225. DBG_API(HRESULT) HrReportExit(HRESULT hr, LPCTSTR szName)
  226. {
  227. if (!FHrOK(hr))
  228. {
  229. Trace2("%s returned 0x%08lx\n", szName, hr);
  230. }
  231. return hr;
  232. }
  233. #endif