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.

131 lines
3.1 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. assert.c
  5. Abstract:
  6. This module implements the RtlAssert function that is referenced by the
  7. debugging version of the ASSERT macro defined in NTDEF.H
  8. Author:
  9. Steve Wood (stevewo) 03-Oct-1989
  10. Revision History:
  11. Jay Krell (a-JayK) November 2000
  12. added RtlAssert2, support for __FUNCTION__ (lost the change to ntrtl.w, will reapply later)
  13. added break Once instead of the usual dumb Break repeatedly
  14. --*/
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <zwapi.h>
  18. //
  19. // RtlAssert is not called unless the caller is compiled with DBG non-zero
  20. // therefore it does no harm to always have this routine in the kernel.
  21. // This allows checked drivers to be thrown on the system and have their
  22. // asserts be meaningful.
  23. //
  24. #define RTL_ASSERT_ALWAYS_ENABLED 1
  25. #ifdef _X86_
  26. #pragma optimize("y", off) // RtlCaptureContext needs EBP to be correct
  27. #endif
  28. #undef RtlAssert
  29. #undef RtlAssert2
  30. VOID
  31. NTAPI
  32. RtlAssert2(
  33. IN CONST CHAR* FailedAssertion,
  34. IN CONST CHAR* FileName,
  35. IN ULONG LineNumber,
  36. IN CONST CHAR* Message OPTIONAL,
  37. IN CONST CHAR* Function OPTIONAL
  38. )
  39. {
  40. #if DBG || RTL_ASSERT_ALWAYS_ENABLED
  41. char Response[ 2 ];
  42. #ifndef BLDR_KERNEL_RUNTIME
  43. CONTEXT Context;
  44. RtlCaptureContext( &Context );
  45. #endif
  46. while (TRUE) {
  47. DbgPrint( "\n*** Assertion failed: %s%s\n*** %s%s%sSource File: %s, line %ld\n\n",
  48. Message ? Message : "",
  49. FailedAssertion,
  50. Function ? "Function: " : "",
  51. Function ? Function : "",
  52. Function ? ", " : "",
  53. FileName,
  54. LineNumber
  55. );
  56. DbgPrompt( "Break repeatedly, break Once, Ignore, terminate Process, or terminate Thread (boipt)? ",
  57. Response,
  58. sizeof( Response )
  59. );
  60. switch (Response[0]) {
  61. case 'B':
  62. case 'b':
  63. case 'O':
  64. case 'o':
  65. #ifndef BLDR_KERNEL_RUNTIME
  66. DbgPrint( "Execute '.cxr %p' to dump context\n", &Context);
  67. #endif
  68. DbgBreakPoint();
  69. if (Response[0] == 'o' || Response[0] == 'O')
  70. return;
  71. break;
  72. case 'I':
  73. case 'i':
  74. return;
  75. case 'P':
  76. case 'p':
  77. ZwTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
  78. break;
  79. case 'T':
  80. case 't':
  81. ZwTerminateThread( NtCurrentThread(), STATUS_UNSUCCESSFUL );
  82. break;
  83. }
  84. }
  85. DbgBreakPoint();
  86. ZwTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
  87. #endif
  88. }
  89. //
  90. // Keep this for binary compatibility.
  91. //
  92. VOID
  93. NTAPI
  94. RtlAssert(
  95. IN PVOID FailedAssertion,
  96. IN PVOID FileName,
  97. IN ULONG LineNumber,
  98. IN PCHAR Message OPTIONAL
  99. )
  100. {
  101. #if DBG || RTL_ASSERT_ALWAYS_ENABLED
  102. RtlAssert2(FailedAssertion, FileName, LineNumber, Message, NULL);
  103. #endif
  104. }
  105. #ifdef _X86_
  106. #pragma optimize("", on)
  107. #endif