1 /*
2  * kmp_debug.c -- debug utilities for the Guide library
3  */
4 
5 
6 //===----------------------------------------------------------------------===//
7 //
8 //                     The LLVM Compiler Infrastructure
9 //
10 // This file is dual licensed under the MIT and the University of Illinois Open
11 // Source Licenses. See LICENSE.txt for details.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 
16 #include "kmp.h"
17 #include "kmp_debug.h" /* really necessary? */
18 #include "kmp_i18n.h"
19 #include "kmp_io.h"
20 
21 #ifdef KMP_DEBUG
22 void
23 __kmp_debug_printf_stdout( char const * format, ... )
24 {
25     va_list ap;
26     va_start( ap, format );
27 
28     __kmp_vprintf( kmp_out, format, ap );
29 
30     va_end(ap);
31 }
32 #endif
33 
34 void
35 __kmp_debug_printf( char const * format, ... )
36 {
37     va_list ap;
38     va_start( ap, format );
39 
40     __kmp_vprintf( kmp_err, format, ap );
41 
42     va_end( ap );
43 }
44 
45 #ifdef KMP_USE_ASSERT
46     int
47     __kmp_debug_assert(
48         char const *  msg,
49         char const *  file,
50         int           line
51     ) {
52 
53         if ( file == NULL ) {
54             file = KMP_I18N_STR( UnknownFile );
55         } else {
56             // Remove directories from path, leave only file name. File name is enough, there is no need
57             // in bothering developers and customers with full paths.
58             char const * slash = strrchr( file, '/' );
59             if ( slash != NULL ) {
60                 file = slash + 1;
61             }; // if
62         }; // if
63 
64         #ifdef KMP_DEBUG
65             __kmp_acquire_bootstrap_lock( & __kmp_stdio_lock );
66             __kmp_debug_printf( "Assertion failure at %s(%d): %s.\n", file, line, msg );
67             __kmp_release_bootstrap_lock( & __kmp_stdio_lock );
68             #ifdef USE_ASSERT_BREAK
69                 #if KMP_OS_WINDOWS
70                     DebugBreak();
71                 #endif
72             #endif // USE_ASSERT_BREAK
73             #ifdef USE_ASSERT_STALL
74                 /*    __kmp_infinite_loop(); */
75                 for(;;);
76             #endif // USE_ASSERT_STALL
77             #ifdef USE_ASSERT_SEG
78                 {
79                     int volatile * ZERO = (int*) 0;
80                     ++ (*ZERO);
81                 }
82             #endif // USE_ASSERT_SEG
83         #endif
84 
85         __kmp_msg(
86             kmp_ms_fatal,
87             KMP_MSG( AssertionFailure, file, line ),
88             KMP_HNT( SubmitBugReport ),
89             __kmp_msg_null
90         );
91 
92         return 0;
93 
94     } // __kmp_debug_assert
95 
96 #endif // KMP_USE_ASSERT
97 
98 /* Dump debugging buffer to stderr */
99 void
100 __kmp_dump_debug_buffer( void )
101 {
102     if ( __kmp_debug_buffer != NULL ) {
103         int i;
104         int dc = __kmp_debug_count;
105         char *db = & __kmp_debug_buffer[ (dc % __kmp_debug_buf_lines) * __kmp_debug_buf_chars ];
106         char *db_end = & __kmp_debug_buffer[ __kmp_debug_buf_lines * __kmp_debug_buf_chars ];
107         char *db2;
108 
109         __kmp_acquire_bootstrap_lock( & __kmp_stdio_lock );
110         __kmp_printf_no_lock( "\nStart dump of debugging buffer (entry=%d):\n",
111                  dc % __kmp_debug_buf_lines );
112 
113         for ( i = 0; i < __kmp_debug_buf_lines; i++ ) {
114 
115             if ( *db != '\0' ) {
116                 /* Fix up where no carriage return before string termination char */
117                 for ( db2 = db + 1; db2 < db + __kmp_debug_buf_chars - 1; db2 ++) {
118                     if ( *db2 == '\0' ) {
119                         if ( *(db2-1) != '\n' ) { *db2 = '\n'; *(db2+1) = '\0'; }
120                         break;
121                     }
122                 }
123                 /* Handle case at end by shortening the printed message by one char if necessary */
124                 if ( db2 == db + __kmp_debug_buf_chars - 1 &&
125                      *db2 == '\0' && *(db2-1) != '\n' ) {
126                     *(db2-1) = '\n';
127                 }
128 
129                 __kmp_printf_no_lock( "%4d: %.*s", i, __kmp_debug_buf_chars, db );
130                 *db = '\0'; /* only let it print once! */
131             }
132 
133             db += __kmp_debug_buf_chars;
134             if ( db >= db_end )
135                 db = __kmp_debug_buffer;
136         }
137 
138         __kmp_printf_no_lock( "End dump of debugging buffer (entry=%d).\n\n",
139                  ( dc+i-1 ) % __kmp_debug_buf_lines );
140         __kmp_release_bootstrap_lock( & __kmp_stdio_lock );
141     }
142 }
143