MySQL 8.1.0
Source Code Documentation
ut0dbg.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 1994, 2023, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is also distributed with certain software (including but not
10limited to OpenSSL) that is licensed under separate terms, as designated in a
11particular file or component or in included license documentation. The authors
12of MySQL hereby grant you an additional permission to link the program and
13your derivative works with the separately licensed software that they have
14included with MySQL.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25*****************************************************************************/
26
27/** @file include/ut0dbg.h
28 Debug utilities for Innobase
29
30 Created 1/30/1994 Heikki Tuuri
31 **********************************************************************/
32
33#ifndef ut0dbg_h
34#define ut0dbg_h
35
36#include "my_compiler.h"
37
38/* Do not include univ.i because univ.i includes this. */
39
40#include <cstdio>
41#include <functional>
42
43/** Set a callback function to be called before exiting.
44@param[in] callback user callback function */
45void ut_set_assert_callback(std::function<void()> &callback);
46
47/** Report a failed assertion.
48@param[in] expr The failed assertion
49@param[in] file Source file containing the assertion
50@param[in] line Line number of the assertion */
51[[noreturn]] void ut_dbg_assertion_failed(const char *expr, const char *file,
52 uint64_t line);
53
54/** Abort execution if EXPR does not evaluate to nonzero.
55@param EXPR assertion expression that should hold */
56#define ut_a(EXPR) \
57 do { \
58 if (unlikely(false == (bool)(EXPR))) { \
59 ut_dbg_assertion_failed(#EXPR, __FILE__, __LINE__); \
60 } \
61 } while (0)
62
63/** Abort execution. */
64#define ut_error ut_dbg_assertion_failed(0, __FILE__, __LINE__)
65
66#ifdef UNIV_DEBUG
67/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
68#define ut_ad(EXPR) ut_a(EXPR)
69/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
70#define ut_d(EXPR) EXPR
71/** Opposite of ut_d(). Does nothing if UNIV_DEBUG is defined. */
72#define ut_o(EXPR)
73#else
74/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
75#define ut_ad(EXPR)
76/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
77#define ut_d(EXPR)
78/** Opposite of ut_d(). Does nothing if UNIV_DEBUG is defined. */
79#define ut_o(EXPR) EXPR
80#endif
81
82/** Debug crash point */
83#ifdef UNIV_DEBUG
84#define DBUG_INJECT_CRASH(prefix, count) \
85 do { \
86 char buf[64]; \
87 snprintf(buf, sizeof buf, prefix "_%u", count); \
88 DBUG_EXECUTE_IF(buf, DBUG_SUICIDE();); \
89 } while (0)
90
91#define DBUG_INJECT_CRASH_WITH_LOG_FLUSH(prefix, count) \
92 do { \
93 char buf[64]; \
94 snprintf(buf, sizeof buf, prefix "_%u", count); \
95 DBUG_EXECUTE_IF(buf, log_buffer_flush_to_disk(); DBUG_SUICIDE();); \
96 } while (0)
97
98#else
99#define DBUG_INJECT_CRASH(prefix, count)
100#define DBUG_INJECT_CRASH_WITH_LOG_FLUSH(prefix, count)
101#endif
102
103/** Silence warnings about an unused variable by doing a null assignment.
104@param A the unused variable */
105#define UT_NOT_USED(A) std::ignore = A
106
107#if defined(HAVE_SYS_TIME_H) && defined(HAVE_SYS_RESOURCE_H)
108
109#define HAVE_UT_CHRONO_T
110
111#include <sys/resource.h>
112#include <sys/time.h>
113#include <sys/types.h>
114
115/** A "chronometer" used to clock snippets of code.
116Example usage:
117 ut_chrono_t ch("this loop");
118 for (;;) { ... }
119 ch.show();
120would print the timings of the for() loop, prefixed with "this loop:" */
122 public:
123 /** Constructor.
124 @param[in] name chrono's name, used when showing the values */
126 reset();
127 }
128
129 /** Resets the chrono (records the current time in it). */
130 void reset() {
131 gettimeofday(&m_tv, nullptr);
132
133 getrusage(RUSAGE_SELF, &m_ru);
134 }
135
136 /** Shows the time elapsed and usage statistics since the last reset. */
137 void show() {
138 struct rusage ru_now;
139 struct timeval tv_now;
140 struct timeval tv_diff;
141
142 getrusage(RUSAGE_SELF, &ru_now);
143
144 gettimeofday(&tv_now, nullptr);
145
146#ifndef timersub
147#define timersub(a, b, r) \
148 do { \
149 (r)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
150 (r)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
151 if ((r)->tv_usec < 0) { \
152 (r)->tv_sec--; \
153 (r)->tv_usec += 1000000; \
154 } \
155 } while (0)
156#endif /* timersub */
157
158#define CHRONO_PRINT(type, tvp) \
159 fprintf(stderr, "%s: %s% 5ld.%06ld sec\n", m_name, type, \
160 static_cast<long>((tvp)->tv_sec), static_cast<long>((tvp)->tv_usec))
161
162 timersub(&tv_now, &m_tv, &tv_diff);
163 CHRONO_PRINT("real", &tv_diff);
164
165 timersub(&ru_now.ru_utime, &m_ru.ru_utime, &tv_diff);
166 CHRONO_PRINT("user", &tv_diff);
167
168 timersub(&ru_now.ru_stime, &m_ru.ru_stime, &tv_diff);
169 CHRONO_PRINT("sys ", &tv_diff);
170 }
171
172 /** Cause the timings not to be printed from the destructor. */
173 void end() { m_show_from_destructor = false; }
174
175 /** Destructor. */
178 show();
179 }
180 }
181
182 private:
183 /** Name of this chronometer. */
184 const char *m_name;
185
186 /** True if the current timings should be printed by the destructor. */
188
189 /** getrusage() result as of the last reset(). */
190 struct rusage m_ru;
191
192 /** gettimeofday() result as of the last reset(). */
193 struct timeval m_tv;
194};
195
196#endif /* HAVE_SYS_TIME_H && HAVE_SYS_RESOURCE_H */
197
198#endif
A "chronometer" used to clock snippets of code.
Definition: ut0dbg.h:121
void show()
Shows the time elapsed and usage statistics since the last reset.
Definition: ut0dbg.h:137
bool m_show_from_destructor
True if the current timings should be printed by the destructor.
Definition: ut0dbg.h:187
struct rusage m_ru
getrusage() result as of the last reset().
Definition: ut0dbg.h:190
ut_chrono_t(const char *name)
Constructor.
Definition: ut0dbg.h:125
const char * m_name
Name of this chronometer.
Definition: ut0dbg.h:184
struct timeval m_tv
gettimeofday() result as of the last reset().
Definition: ut0dbg.h:193
void reset()
Resets the chrono (records the current time in it).
Definition: ut0dbg.h:130
void end()
Cause the timings not to be printed from the destructor.
Definition: ut0dbg.h:173
~ut_chrono_t()
Destructor.
Definition: ut0dbg.h:176
Header for compiler-dependent features.
Definition: os0file.h:85
case opt name
Definition: sslopt-case.h:32
Include file for Sun RPC to compile out of the box.
#define CHRONO_PRINT(type, tvp)
void ut_dbg_assertion_failed(const char *expr, const char *file, uint64_t line)
Report a failed assertion.
Definition: ut0dbg.cc:55
#define timersub(a, b, r)
void ut_set_assert_callback(std::function< void()> &callback)
Set a callback function to be called before exiting.
Definition: ut0dbg.cc:47