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