xref: /reactos/sdk/lib/crt/misc/assert.c (revision 5100859e)
1 /*
2  * PROJECT:         ReactOS C runtime library
3  * LICENSE:         BSD - See COPYING.ARM in the top level directory
4  * FILE:            lib/sdk/crt/misc/assert.c
5  * PURPOSE:         _assert implementation
6  * PROGRAMMER:      Timo Kreuzer (timo.kreuzer@reactos.org)
7  */
8 
9 #include <precomp.h>
10 
11 static const char formatstr[] =
12     "Assertion failed!\n\n"
13     "Program: %s\n"
14     "File: %s\n"
15     "Line: %ld\n\n"
16     "Expression: %s\n"
17     "Press Retry to debug the application\n\0";
18 
19 void
20 _assert (
21     const char *exp,
22     const char *file,
23     unsigned line)
24 {
25     char achProgram[MAX_PATH];
26     char *pszBuffer;
27     size_t len;
28     int iResult;
29 
30     /* First common debug message */
31     FIXME("Assertion failed: %s, file %s, line %d\n", exp, file, line);
32 
33     /* Check if output should go to stderr */
34     if (((msvcrt_error_mode == _OUT_TO_DEFAULT) && (__app_type == _CONSOLE_APP)) ||
35         (msvcrt_error_mode == _OUT_TO_STDERR))
36     {
37         /* Print 'Assertion failed: x<y, file foo.c, line 45' to stderr */
38         fprintf(stderr, "Assertion failed: %s, file %s, line %u\n", exp, file, line);
39         abort();
40     }
41 
42     /* Get the file name of the module */
43     len = GetModuleFileNameA(NULL, achProgram, sizeof(achProgram));
44 
45     /* Calculate full length of the message */
46     len += sizeof(formatstr) + len + strlen(exp) + strlen(file);
47 
48     /* Allocate a buffer */
49     pszBuffer = malloc(len + 1);
50 
51     /* Format a message */
52     _snprintf(pszBuffer, len, formatstr, achProgram, file, line, exp);
53 
54     /* Display a message box */
55     iResult = __crt_MessageBoxA(pszBuffer, MB_ABORTRETRYIGNORE | MB_ICONERROR);
56 
57     /* Free the buffer */
58     free(pszBuffer);
59 
60     /* Does the user want to ignore? */
61     if (iResult == IDIGNORE)
62     {
63         /* Just return to the caller */
64         return;
65     }
66 
67     /* Does the user want to debug? */
68     if (iResult == IDRETRY)
69     {
70         /* Break and return to the caller */
71         __debugbreak();
72         return;
73     }
74 
75     /* Reset all abort flags (we don*t want another message box) and abort */
76     _set_abort_behavior(0, 0xffffffff);
77     abort();
78 }
79 
80