1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Run-Time Library 4 * PURPOSE: Implements RtlAssert used by the ASSERT 5 * and ASSERTMSG debugging macros 6 * FILE: lib/rtl/assert.c 7 * PROGRAMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) 8 */ 9 10 /* INCLUDES *****************************************************************/ 11 12 #include <rtl.h> 13 #define NDEBUG 14 #include <debug.h> 15 16 /* PUBLIC FUNCTIONS **********************************************************/ 17 18 /* 19 * @implemented 20 */ 21 VOID 22 NTAPI 23 RtlAssert(IN PVOID FailedAssertion, 24 IN PVOID FileName, 25 IN ULONG LineNumber, 26 IN PCHAR Message OPTIONAL) 27 { 28 CHAR Action[2]; 29 CONTEXT Context; 30 31 /* Capture caller's context for the debugger */ 32 RtlCaptureContext(&Context); 33 34 /* Enter prompt loop */ 35 for (;;) 36 { 37 /* Print the assertion */ 38 DbgPrint("\n*** Assertion failed: %s%s\n" 39 "*** Source File: %s, line %lu\n\n", 40 Message != NULL ? Message : "", 41 (PSTR)FailedAssertion, 42 (PSTR)FileName, 43 LineNumber); 44 45 /* Check for reactos specific flag (set by rosautotest) */ 46 if (RtlGetNtGlobalFlags() & FLG_DISABLE_DEBUG_PROMPTS) 47 { 48 RtlRaiseStatus(STATUS_ASSERTION_FAILURE); 49 } 50 51 /* Prompt for action */ 52 DbgPrompt("Break repeatedly, break Once, Ignore, " 53 "terminate Process or terminate Thread (boipt)? ", 54 Action, 55 sizeof(Action)); 56 switch (Action[0]) 57 { 58 /* Break repeatedly / Break once */ 59 case 'B': case 'b': 60 case 'O': case 'o': 61 DbgPrint("Execute '.cxr %p' to dump context\n", &Context); 62 /* Do a breakpoint, then prompt again or return */ 63 DbgBreakPoint(); 64 if ((Action[0] == 'B') || (Action[0] == 'b')) 65 break; 66 /* else ('O','o'): fall through */ 67 68 /* Ignore: Return to caller */ 69 case 'I': case 'i': 70 return; 71 72 /* Terminate current process */ 73 case 'P': case 'p': 74 ZwTerminateProcess(ZwCurrentProcess(), STATUS_UNSUCCESSFUL); 75 break; 76 77 /* Terminate current thread */ 78 case 'T': case 't': 79 ZwTerminateThread(ZwCurrentThread(), STATUS_UNSUCCESSFUL); 80 break; 81 82 /* Unrecognized: Prompt again */ 83 default: 84 break; 85 } 86 } 87 88 /* Shouldn't get here */ 89 DbgBreakPoint(); 90 ZwTerminateProcess(ZwCurrentProcess(), STATUS_UNSUCCESSFUL); 91 } 92