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