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.

117 lines
2.9 KiB

  1. /*++
  2. Copyright (c) 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 (JayKrell) 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. March 2002 removed RtlAssert2
  15. --*/
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <zwapi.h>
  19. //
  20. // RtlAssert is not called unless the caller is compiled with DBG non-zero
  21. // therefore it does no harm to always have this routine in the kernel.
  22. // This allows checked drivers to be thrown on the system and have their
  23. // asserts be meaningful.
  24. //
  25. #define RTL_ASSERT_ALWAYS_ENABLED 1
  26. #ifdef _X86_
  27. #pragma optimize("y", off) // RtlCaptureContext needs EBP to be correct
  28. #endif
  29. #undef RtlAssert
  30. typedef CONST CHAR * PCSTR;
  31. NTSYSAPI
  32. VOID
  33. NTAPI
  34. RtlAssert(
  35. PVOID VoidFailedAssertion,
  36. PVOID VoidFileName,
  37. ULONG LineNumber,
  38. PCHAR MutableMessage
  39. )
  40. {
  41. #if DBG || RTL_ASSERT_ALWAYS_ENABLED
  42. char Response[ 2 ];
  43. CONST PCSTR FailedAssertion = (PCSTR)VoidFailedAssertion;
  44. CONST PCSTR FileName = (PCSTR)VoidFileName;
  45. CONST PCSTR Message = (PCSTR)MutableMessage;
  46. #ifndef BLDR_KERNEL_RUNTIME
  47. CONTEXT Context;
  48. RtlCaptureContext( &Context );
  49. #endif
  50. while (TRUE) {
  51. DbgPrint( "\n*** Assertion failed: %s%s\n*** Source File: %s, line %ld\n\n",
  52. Message ? Message : "",
  53. FailedAssertion,
  54. FileName,
  55. LineNumber
  56. );
  57. DbgPrompt( "Break repeatedly, break Once, Ignore, terminate Process, or terminate Thread (boipt)? ",
  58. Response,
  59. sizeof( Response )
  60. );
  61. switch (Response[0]) {
  62. case 'B':
  63. case 'b':
  64. case 'O':
  65. case 'o':
  66. #ifndef BLDR_KERNEL_RUNTIME
  67. DbgPrint( "Execute '.cxr %p' to dump context\n", &Context);
  68. #endif
  69. DbgBreakPoint();
  70. if (Response[0] == 'o' || Response[0] == 'O')
  71. return;
  72. break;
  73. case 'I':
  74. case 'i':
  75. return;
  76. case 'P':
  77. case 'p':
  78. ZwTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
  79. break;
  80. case 'T':
  81. case 't':
  82. ZwTerminateThread( NtCurrentThread(), STATUS_UNSUCCESSFUL );
  83. break;
  84. }
  85. }
  86. DbgBreakPoint();
  87. ZwTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL );
  88. #endif
  89. }
  90. #ifdef _X86_
  91. #pragma optimize("", on)
  92. #endif