xref: /reactos/sdk/lib/rtl/assert.c (revision 0c2cdcae)
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