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.

225 lines
6.2 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: assert.c
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 4-03-95 RichardW Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "debuglib.h"
  18. typedef ULONG (NTAPI * DBGPROMPT)(PCH, PCH, ULONG);
  19. #define DSYSASSERT_FAILED 0x00000001
  20. #define DSYSASSERT_ERROR 0x00000002
  21. #define DSYSASSERT_WARN 0x00000004
  22. DWORD __AssertInfoLevel = DSYSASSERT_FAILED;
  23. DebugModule __AssertModule = {NULL, &__AssertInfoLevel, 0, 7,
  24. NULL, 0, 0, "Assert",
  25. {"FAILED", "Error", "Warning", "",
  26. "", "", "", "",
  27. "", "", "", "", "", "", "", "",
  28. "", "", "", "", "", "", "", "",
  29. "", "", "", "", "", "", "", "" }
  30. };
  31. DebugModule * __pAssertModule = &__AssertModule;
  32. VOID
  33. __AssertDebugOut(
  34. ULONG Mask,
  35. CHAR * Format,
  36. ... )
  37. {
  38. va_list ArgList;
  39. va_start(ArgList, Format);
  40. _DebugOut( __pAssertModule, Mask, Format, ArgList);
  41. }
  42. BOOL
  43. DbgpStartDebuggerOnMyself(BOOL UseKernelDebugger)
  44. {
  45. WCHAR cch[80];
  46. STARTUPINFO StartupInfo;
  47. PROCESS_INFORMATION ProcessInformation;
  48. SECURITY_ATTRIBUTES sa;
  49. HANDLE hEvent;
  50. sa.nLength = sizeof(sa);
  51. sa.lpSecurityDescriptor = &DbgpPartySd;
  52. sa.bInheritHandle = TRUE;
  53. hEvent = CreateEvent(&sa, TRUE, FALSE, NULL);
  54. swprintf(cch, TEXT("ntsd %s -p %ld -e %ld -g"), (UseKernelDebugger ? "-d" : ""),
  55. GetCurrentProcessId(), hEvent);
  56. ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
  57. StartupInfo.cb = sizeof(STARTUPINFO);
  58. if (!UseKernelDebugger)
  59. {
  60. StartupInfo.lpDesktop = TEXT("WinSta0\\Default");
  61. }
  62. if (CreateProcess( NULL,
  63. cch,
  64. NULL,
  65. NULL,
  66. TRUE,
  67. HIGH_PRIORITY_CLASS,
  68. NULL,
  69. NULL,
  70. &StartupInfo,
  71. &ProcessInformation) )
  72. {
  73. CloseHandle(ProcessInformation.hProcess);
  74. CloseHandle(ProcessInformation.hThread);
  75. WaitForSingleObject(hEvent, 60000);
  76. CloseHandle(hEvent);
  77. return(TRUE);
  78. }
  79. else
  80. {
  81. __AssertDebugOut( DSYSASSERT_ERROR, "Could not start debugger '%ws', %d\n", cch, GetLastError());
  82. return(FALSE);
  83. }
  84. }
  85. VOID
  86. _DsysAssertEx(
  87. PVOID FailedAssertion,
  88. PVOID FileName,
  89. ULONG LineNumber,
  90. PCHAR Message,
  91. ULONG ContinueCode
  92. )
  93. {
  94. CHAR Response[2];
  95. HMODULE hNtDll;
  96. DBGPROMPT DbgPromptFn;
  97. if (DbgpHeader)
  98. {
  99. __pAssertModule->pHeader = DbgpHeader;
  100. if (DbgpHeader->fDebug & DEBUG_DISABLE_ASRT)
  101. {
  102. __AssertDebugOut( DSYSASSERT_WARN, "Assertion at %s:%d disabled\n",
  103. FileName, LineNumber);
  104. return;
  105. }
  106. }
  107. if (Message)
  108. __AssertDebugOut( DSYSASSERT_FAILED, "%s: %s (%s:%d)\n",
  109. Message, FailedAssertion, FileName, LineNumber);
  110. else
  111. __AssertDebugOut( DSYSASSERT_FAILED, "%s (%s:%d)\n",
  112. FailedAssertion, FileName, LineNumber);
  113. switch (ContinueCode)
  114. {
  115. case DSYSDBG_ASSERT_BREAK:
  116. __AssertDebugOut( DSYSASSERT_FAILED, "\tBreakpoint\n");
  117. DebugBreak();
  118. break;
  119. case DSYSDBG_ASSERT_CONTINUE:
  120. __AssertDebugOut( DSYSASSERT_WARN, "\tContinuing\n");
  121. return;
  122. case DSYSDBG_ASSERT_SUSPEND:
  123. __AssertDebugOut( DSYSASSERT_WARN, "\tSuspending Thread %d\n", GetCurrentThreadId());
  124. SuspendThread(GetCurrentThread());
  125. return;
  126. case DSYSDBG_ASSERT_KILL:
  127. __AssertDebugOut( DSYSASSERT_WARN, "\tKill Thread (exit %x)\n", NtCurrentTeb()->LastStatusValue);
  128. TerminateThread(GetCurrentThread(), NtCurrentTeb()->LastStatusValue);
  129. return;
  130. case DSYSDBG_ASSERT_DEBUGGER:
  131. if (IsDebuggerPresent())
  132. {
  133. DebugBreak();
  134. }
  135. else
  136. {
  137. if (DbgpHeader)
  138. {
  139. if ((DbgpHeader->fDebug & DEBUG_PROMPTS) == 0)
  140. {
  141. DbgpStartDebuggerOnMyself(DbgpHeader->fDebug & DEBUG_USE_KDEBUG);
  142. DebugBreak();
  143. break;
  144. }
  145. }
  146. hNtDll = LoadLibrary(TEXT("ntdll.dll"));
  147. if (hNtDll)
  148. {
  149. DbgPromptFn = (DBGPROMPT) GetProcAddress(hNtDll, "DbgPrompt");
  150. }
  151. else
  152. {
  153. DbgPromptFn = NULL;
  154. }
  155. while (TRUE)
  156. {
  157. if (DbgPromptFn)
  158. {
  159. DbgPromptFn( "Start Debugger, Break, Ignore (dbi)?",
  160. Response, sizeof(Response));
  161. switch (Response[0])
  162. {
  163. case 'i':
  164. case 'I':
  165. return;
  166. case 'd':
  167. case 'D':
  168. DbgpStartDebuggerOnMyself(DbgpHeader ? (DbgpHeader->fDebug & DEBUG_USE_KDEBUG) : TRUE );
  169. case 'b':
  170. case 'B':
  171. DebugBreak();
  172. return;
  173. }
  174. }
  175. else
  176. {
  177. DbgpStartDebuggerOnMyself(TRUE);
  178. DebugBreak();
  179. return;
  180. }
  181. }
  182. }
  183. break;
  184. default:
  185. __AssertDebugOut( DSYSASSERT_ERROR, "Unknown continue code for assert: %d\n",
  186. ContinueCode);
  187. return;
  188. }
  189. }