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