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.

311 lines
7.9 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: cmdebug.cpp
  4. //
  5. // Module: Chameleon
  6. //
  7. // Synopsis: Provide the functionality of ASSERT and TRACE
  8. //
  9. // Copyright (C) Microsoft Corporation. All rights reserved.
  10. //
  11. // Author: fengsun Created 8/3/98
  12. //
  13. //+----------------------------------------------------------------------------
  14. #if ( defined(DEBUG) || defined(_DEBUG) )
  15. #ifndef UNICODE
  16. #define UNICODE
  17. #endif
  18. #include <stddef.h>
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <windows.h>
  22. #include <winuser.h>
  23. #include "debug.h"
  24. #ifndef MB_SERVICE_NOTIFICATION
  25. #define MB_SERVICE_NOTIFICATION 0
  26. #endif
  27. static long dwAssertCount = 0; // Avoid another assert while the messagebox is up
  28. //+----------------------------------------------------------------------------
  29. //
  30. // Function: TraceMessage
  31. //
  32. // Synopsis: Output debug string
  33. //
  34. // Arguments: const char *pszFmt ...- Printf style arguments list
  35. //
  36. //
  37. // Returns: Nothing
  38. //
  39. // History: fengsun Created Header 8/3/98
  40. //
  41. //+----------------------------------------------------------------------------
  42. extern "C" void TraceMessageW(const TCHAR *pszFmt, ...)
  43. {
  44. va_list valArgs;
  45. TCHAR szOutput[512];
  46. va_start(valArgs,pszFmt);
  47. wvsprintf(szOutput,pszFmt,valArgs);
  48. va_end(valArgs);
  49. lstrcat(szOutput,TEXT("\r\n"));
  50. OutputDebugString(szOutput);
  51. }
  52. //+----------------------------------------------------------------------------
  53. //
  54. // Function: AssertMessage
  55. //
  56. // Synopsis: Popup a message box for asserting failure. Has three options:
  57. // ignore/debug/abort.
  58. //
  59. // Arguments: const char *pszFile - File name
  60. // unsigned nLine - Line number
  61. // const char *pszMsg - Message in the dialog box
  62. //
  63. // Returns: Nothing
  64. //
  65. // History: fengsun Created Header 8/3/98
  66. //
  67. //+----------------------------------------------------------------------------
  68. extern "C" void AssertMessageW(const TCHAR *pszFile, unsigned nLine, const TCHAR *pszMsg)
  69. {
  70. TCHAR szOutput[1024];
  71. wsprintf(szOutput,TEXT("%s(%u) - %s\n"),pszFile,nLine,pszMsg);
  72. OutputDebugString(szOutput);
  73. wsprintf(szOutput,TEXT("%s(%u) - %s\n( Press Retry to debug )"),pszFile,nLine,pszMsg);
  74. int nCode = IDIGNORE;
  75. //
  76. // If there is no Assertion messagebox, popup one
  77. //
  78. if (dwAssertCount <2 )
  79. {
  80. dwAssertCount++;
  81. //
  82. // Title format: Assertion Failed - hello.dll
  83. //
  84. //
  85. // Find the base address of this module.
  86. //
  87. MEMORY_BASIC_INFORMATION mbi;
  88. mbi.AllocationBase = NULL; // current process by if VirtualQuery failed
  89. VirtualQuery(
  90. AssertMessageW, // any pointer with in the module
  91. &mbi,
  92. sizeof(mbi) );
  93. //
  94. // Get the module filename.
  95. //
  96. WCHAR szFileName[MAX_PATH + 1], *basename, *suffix;
  97. szFileName[0] = L'\0'; // in case of failure
  98. GetModuleFileNameW(
  99. (HINSTANCE)mbi.AllocationBase,
  100. szFileName,
  101. MAX_PATH );
  102. //
  103. // Get the filename out of the full path
  104. //
  105. for (int i=lstrlen(szFileName);i != 0 && szFileName[i-1] != L'\\'; i--)
  106. ;
  107. WCHAR szTitle[48];
  108. lstrcpyW(szTitle, L"Assertion Failed - ");
  109. lstrcpynW(&szTitle[lstrlenW(szTitle)], szFileName+i,
  110. sizeof(szTitle)/sizeof(szTitle[0]) - lstrlenW(szTitle) -1); // there is no lstrcatn
  111. nCode = MessageBoxEx(NULL,szOutput,szTitle,
  112. MB_TOPMOST | MB_ICONHAND | MB_ABORTRETRYIGNORE | MB_SERVICE_NOTIFICATION,LANG_USER_DEFAULT);
  113. dwAssertCount--;
  114. }
  115. if (nCode == IDIGNORE)
  116. {
  117. return; // ignore
  118. }
  119. else if (nCode == IDRETRY)
  120. {
  121. #ifdef _X86_
  122. //
  123. // break into the debugger .
  124. // Step out of this fuction to get to your ASSERT() code
  125. //
  126. _asm { int 3 };
  127. #else
  128. DebugBreak();
  129. #endif
  130. return; // ignore and continue in debugger to diagnose problem
  131. }
  132. // else fall through and call Abort
  133. ExitProcess((DWORD)-1);
  134. }
  135. //+----------------------------------------------------------------------------
  136. //
  137. // Function: TraceMessage
  138. //
  139. // Synopsis: Output debug string
  140. //
  141. // Arguments: const char *pszFmt ...- Printf style arguments list
  142. //
  143. //
  144. // Returns: Nothing
  145. //
  146. // History: fengsun Created Header 8/3/98
  147. //
  148. //+----------------------------------------------------------------------------
  149. extern "C" void TraceMessageA(const CHAR *pszFmt, ...)
  150. {
  151. va_list valArgs;
  152. CHAR szOutput[512];
  153. va_start(valArgs,pszFmt);
  154. wvsprintfA(szOutput,pszFmt,valArgs);
  155. va_end(valArgs);
  156. lstrcatA(szOutput,("\r\n"));
  157. OutputDebugStringA(szOutput);
  158. }
  159. //+----------------------------------------------------------------------------
  160. //
  161. // Function: AssertMessageA
  162. //
  163. // Synopsis: Popup a message box for asserting failure. Has three options:
  164. // ignore/debug/abort.
  165. //
  166. // Arguments: const char *pszFile - File name
  167. // unsigned nLine - Line number
  168. // const char *pszMsg - Message in the dialog box
  169. //
  170. // Returns: Nothing
  171. //
  172. // History: fengsun Created Header 8/3/98
  173. //
  174. //+----------------------------------------------------------------------------
  175. extern "C" void AssertMessageA(const CHAR *pszFile, unsigned nLine, const CHAR *pszMsg)
  176. {
  177. CHAR szOutput[1024];
  178. wsprintfA(szOutput,("%s(%u) - %s\n"),pszFile,nLine,pszMsg);
  179. OutputDebugStringA(szOutput);
  180. wsprintfA(szOutput,("%s(%u) - %s\n( Press Retry to debug )"),pszFile,nLine,pszMsg);
  181. int nCode = IDIGNORE;
  182. //
  183. // If there is no Assertion messagebox, popup one
  184. //
  185. if (dwAssertCount <2 )
  186. {
  187. dwAssertCount++;
  188. //
  189. // Title format: Assertion Failed - hello.dll
  190. //
  191. //
  192. // Find the base address of this module.
  193. //
  194. MEMORY_BASIC_INFORMATION mbi;
  195. mbi.AllocationBase = NULL; // current process by if VirtualQuery failed
  196. VirtualQuery(
  197. AssertMessageW, // any pointer with in the module
  198. &mbi,
  199. sizeof(mbi) );
  200. //
  201. // Get the module filename.
  202. //
  203. CHAR szFileName[MAX_PATH + 1], *basename, *suffix;
  204. szFileName[0] = '\0'; // in case of failure
  205. GetModuleFileNameA(
  206. (HINSTANCE)mbi.AllocationBase,
  207. szFileName,
  208. MAX_PATH );
  209. //
  210. // Get the filename out of the full path
  211. //
  212. for (int i=lstrlenA(szFileName);i != 0 && szFileName[i-1] != '\\'; i--)
  213. ;
  214. CHAR szTitle[48];
  215. lstrcpyA(szTitle, "Assertion Failed - ");
  216. lstrcpynA(&szTitle[lstrlenA(szTitle)], szFileName+i,
  217. sizeof(szTitle)/sizeof(szTitle[0]) - lstrlenA(szTitle) -1); // there is no lstrcatn
  218. nCode = MessageBoxExA(NULL,szOutput,szTitle,
  219. MB_TOPMOST | MB_ICONHAND | MB_ABORTRETRYIGNORE | MB_SERVICE_NOTIFICATION,LANG_USER_DEFAULT);
  220. dwAssertCount--;
  221. }
  222. dwAssertCount--;
  223. if (nCode == IDIGNORE)
  224. {
  225. return; // ignore
  226. }
  227. else if (nCode == IDRETRY)
  228. {
  229. #ifdef _X86_
  230. //
  231. // break into the debugger .
  232. // Step out of this fuction to get to your ASSERT() code
  233. //
  234. _asm { int 3 };
  235. #else
  236. DebugBreak();
  237. #endif
  238. return; // ignore and continue in debugger to diagnose problem
  239. }
  240. // else fall through and call Abort
  241. ExitProcess((DWORD)-1);
  242. }
  243. #endif //_DEBUG