xref: /reactos/sdk/lib/rtl/assert.c (revision 2ea56af2)
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         /* Prompt for action */
46         DbgPrompt("Break repeatedly, break Once, Ignore, "
47                   "terminate Process or terminate Thread (boipt)? ",
48                   Action,
49                   sizeof(Action));
50         switch (Action[0])
51         {
52             /* Break repeatedly / Break once */
53             case 'B': case 'b':
54             case 'O': case 'o':
55                 DbgPrint("Execute '.cxr %p' to dump context\n", &Context);
56                 /* Do a breakpoint, then prompt again or return */
57                 DbgBreakPoint();
58                 if ((Action[0] == 'B') || (Action[0] == 'b'))
59                     break;
60                 /* else ('O','o'): fall through */
61 
62             /* Ignore: Return to caller */
63             case 'I': case 'i':
64                 return;
65 
66             /* Terminate current process */
67             case 'P': case 'p':
68                 ZwTerminateProcess(ZwCurrentProcess(), STATUS_UNSUCCESSFUL);
69                 break;
70 
71             /* Terminate current thread */
72             case 'T': case 't':
73                 ZwTerminateThread(ZwCurrentThread(), STATUS_UNSUCCESSFUL);
74                 break;
75 
76             /* Unrecognized: Prompt again */
77             default:
78                 break;
79         }
80     }
81 
82     /* Shouldn't get here */
83     DbgBreakPoint();
84     ZwTerminateProcess(ZwCurrentProcess(), STATUS_UNSUCCESSFUL);
85 }
86