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.

305 lines
7.5 KiB

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