MySQL 9.1.0
Source Code Documentation
ut0dbg.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 1994, 2024, 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 designed to work with certain software (including
10but not limited to OpenSSL) that is licensed under separate terms,
11as designated in a particular file or component or in included license
12documentation. The authors of MySQL hereby grant you an additional
13permission to link the program and your derivative works with the
14separately licensed software that they have either included with
15the program or referenced in the documentation.
16
17This program is distributed in the hope that it will be useful, but WITHOUT
18ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
20for more details.
21
22You should have received a copy of the GNU General Public License along with
23this program; if not, write to the Free Software Foundation, Inc.,
2451 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
26*****************************************************************************/
27
28/** @file include/ut0dbg.h
29 Debug utilities for Innobase
30
31 Created 1/30/1994 Heikki Tuuri
32 **********************************************************************/
33
34#ifndef ut0dbg_h
35#define ut0dbg_h
36
37#include "my_compiler.h"
38
39/* Do not include univ.i because univ.i includes this. */
40
41#include <cstdio>
42#include <functional>
43#include <sstream>
44
45/** Set a callback function to be called before exiting.
46@param[in] callback user callback function */
47void ut_set_assert_callback(std::function<void()> &callback);
48
49/** Report a failed assertion.
50@param[in] expr The failed assertion
51@param[in] file Source file containing the assertion
52@param[in] line Line number of the assertion */
53[[noreturn]] void ut_dbg_assertion_failed(const char *expr, const char *file,
54 uint64_t line);
55
56template <typename L, typename R>
57[[noreturn]] void inline ut_dbg_comparison_failed(
58 const char *lhs_expr, const L &lhs_value, const char *op,
59 const char *rhs_expr, const R &rhs_value, const char *file, uint64_t line) {
61 text << lhs_expr << " == " << lhs_value << ' ' << op << ' ' << rhs_value
62 << " == " << rhs_expr;
63 ut_dbg_assertion_failed(text.str().c_str(), file, line);
64}
65
66/** Assert that LHS OP RHS, where OP is an operator.
67Abort execution otherwise.
68Technical remarks: The LHS and RHS are evaluated exactly once (no short
69circuiting, even if OP is && or ||). Each value is stored in a local variable,
70so it's fine for LHS or RHS to return a temporary.
71In case of assertion failure references to const values of LHS and RHS will be
72passed to std::ostringstream::operator<<, so it must be implemented for them. */
73#define ut_a_op(LHS, OP, RHS) \
74 do { \
75 const auto lhs{LHS}; \
76 const auto rhs{RHS}; \
77 if (unlikely(!(lhs OP rhs))) { \
78 ut_dbg_comparison_failed(#LHS, lhs, #OP, #RHS, rhs, __FILE__, __LINE__); \
79 } \
80 } while (0)
81
82/** Assert that LHS < RHS. Abort execution otherwise. */
83#define ut_a_lt(LHS, RHS) ut_a_op(LHS, <, RHS)
84/** Assert that LHS <= RHS. Abort execution otherwise. */
85#define ut_a_le(LHS, RHS) ut_a_op(LHS, <=, RHS)
86/** Assert that LHS == RHS. Abort execution otherwise. */
87#define ut_a_eq(LHS, RHS) ut_a_op(LHS, ==, RHS)
88/** Assert that LHS != RHS. Abort execution otherwise. */
89#define ut_a_ne(LHS, RHS) ut_a_op(LHS, !=, RHS)
90
91/** Abort execution if EXPR does not evaluate to nonzero.
92@param EXPR assertion expression that should hold */
93#define ut_a(EXPR) \
94 do { \
95 if (unlikely(false == (bool)(EXPR))) { \
96 ut_dbg_assertion_failed(#EXPR, __FILE__, __LINE__); \
97 } \
98 } while (0)
99
100/** Abort execution. */
101#define ut_error ut_dbg_assertion_failed(nullptr, __FILE__, __LINE__)
102
103#ifdef UNIV_DEBUG
104/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
105#define ut_ad(EXPR) ut_a(EXPR)
106/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
107#define ut_d(EXPR) EXPR
108/** Opposite of ut_d(). Does nothing if UNIV_DEBUG is defined. */
109#define ut_o(EXPR)
110/** Debug-only assertion that LHS < RHS. */
111#define ut_ad_lt(LHS, RHS) ut_a_lt(LHS, RHS)
112/** Debug-only assertion that LHS <= RHS. */
113#define ut_ad_le(LHS, RHS) ut_a_le(LHS, RHS)
114/** Debug-only assertion that LHS == RHS. */
115#define ut_ad_eq(LHS, RHS) ut_a_eq(LHS, RHS)
116/** Assert that LHS != RHS. Abort execution otherwise. */
117#define ut_ad_ne(LHS, RHS) ut_a_op(LHS, !=, RHS)
118#else
119/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
120#define ut_ad(EXPR)
121/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
122#define ut_d(EXPR)
123/** Opposite of ut_d(). Does nothing if UNIV_DEBUG is defined. */
124#define ut_o(EXPR) EXPR
125/** Debug-only assertion that LHS < RHS. */
126#define ut_ad_lt(LHS, RHS)
127/** Debug-only assertion that LHS <= RHS. */
128#define ut_ad_le(LHS, RHS)
129/** Debug-only assertion that LHS == RHS. */
130#define ut_ad_eq(LHS, RHS)
131/** Assert that LHS != RHS. */
132#define ut_ad_ne(LHS, RHS)
133#endif
134
135/** Debug crash point */
136#ifdef UNIV_DEBUG
137#define DBUG_INJECT_CRASH(prefix, count) \
138 do { \
139 char buf[64]; \
140 snprintf(buf, sizeof buf, prefix "_%u", count); \
141 DBUG_EXECUTE_IF(buf, DBUG_SUICIDE();); \
142 } while (0)
143
144#define DBUG_INJECT_CRASH_WITH_LOG_FLUSH(prefix, count) \
145 do { \
146 char buf[64]; \
147 snprintf(buf, sizeof buf, prefix "_%u", count); \
148 DBUG_EXECUTE_IF(buf, log_buffer_flush_to_disk(); DBUG_SUICIDE();); \
149 } while (0)
150
151#else
152#define DBUG_INJECT_CRASH(prefix, count)
153#define DBUG_INJECT_CRASH_WITH_LOG_FLUSH(prefix, count)
154#endif
155
156/** Silence warnings about an unused variable by doing a null assignment.
157@param A the unused variable */
158#define UT_NOT_USED(A) std::ignore = A
159
160#if defined(HAVE_SYS_TIME_H) && defined(HAVE_SYS_RESOURCE_H)
161
162#define HAVE_UT_CHRONO_T
163
164#include <sys/resource.h>
165#include <sys/time.h>
166#include <sys/types.h>
167
168/** A "chronometer" used to clock snippets of code.
169Example usage:
170 ut_chrono_t ch("this loop");
171 for (;;) { ... }
172 ch.show();
173would print the timings of the for() loop, prefixed with "this loop:" */
175 public:
176 /** Constructor.
177 @param[in] name chrono's name, used when showing the values */
179 reset();
180 }
181
182 /** Resets the chrono (records the current time in it). */
183 void reset() {
184 gettimeofday(&m_tv, nullptr);
185
186 getrusage(RUSAGE_SELF, &m_ru);
187 }
188
189 /** Shows the time elapsed and usage statistics since the last reset. */
190 void show() {
191 struct rusage ru_now;
192 struct timeval tv_now;
193 struct timeval tv_diff;
194
195 getrusage(RUSAGE_SELF, &ru_now);
196
197 gettimeofday(&tv_now, nullptr);
198
199#ifndef timersub
200#define timersub(a, b, r) \
201 do { \
202 (r)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
203 (r)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
204 if ((r)->tv_usec < 0) { \
205 (r)->tv_sec--; \
206 (r)->tv_usec += 1000000; \
207 } \
208 } while (0)
209#endif /* timersub */
210
211#define CHRONO_PRINT(type, tvp) \
212 fprintf(stderr, "%s: %s% 5ld.%06ld sec\n", m_name, type, \
213 static_cast<long>((tvp)->tv_sec), static_cast<long>((tvp)->tv_usec))
214
215 timersub(&tv_now, &m_tv, &tv_diff);
216 CHRONO_PRINT("real", &tv_diff);
217
218 timersub(&ru_now.ru_utime, &m_ru.ru_utime, &tv_diff);
219 CHRONO_PRINT("user", &tv_diff);
220
221 timersub(&ru_now.ru_stime, &m_ru.ru_stime, &tv_diff);
222 CHRONO_PRINT("sys ", &tv_diff);
223 }
224
225 /** Cause the timings not to be printed from the destructor. */
226 void end() { m_show_from_destructor = false; }
227
228 /** Destructor. */
231 show();
232 }
233 }
234
235 private:
236 /** Name of this chronometer. */
237 const char *m_name;
238
239 /** True if the current timings should be printed by the destructor. */
241
242 /** getrusage() result as of the last reset(). */
243 struct rusage m_ru;
244
245 /** gettimeofday() result as of the last reset(). */
246 struct timeval m_tv;
247};
248
249#endif /* HAVE_SYS_TIME_H && HAVE_SYS_RESOURCE_H */
250
251#endif
A "chronometer" used to clock snippets of code.
Definition: ut0dbg.h:174
void show()
Shows the time elapsed and usage statistics since the last reset.
Definition: ut0dbg.h:190
bool m_show_from_destructor
True if the current timings should be printed by the destructor.
Definition: ut0dbg.h:240
struct rusage m_ru
getrusage() result as of the last reset().
Definition: ut0dbg.h:243
ut_chrono_t(const char *name)
Constructor.
Definition: ut0dbg.h:178
const char * m_name
Name of this chronometer.
Definition: ut0dbg.h:237
struct timeval m_tv
gettimeofday() result as of the last reset().
Definition: ut0dbg.h:246
void reset()
Resets the chrono (records the current time in it).
Definition: ut0dbg.h:183
void end()
Cause the timings not to be printed from the destructor.
Definition: ut0dbg.h:226
~ut_chrono_t()
Destructor.
Definition: ut0dbg.h:229
#define L
Definition: ctype-tis620.cc:75
Header for compiler-dependent features.
Definition: os0file.h:89
std::basic_ostringstream< char, std::char_traits< char >, ut::allocator< char > > ostringstream
Specialization of basic_ostringstream which uses ut::allocator.
Definition: ut0new.h:2872
case opt name
Definition: sslopt-case.h:29
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:56
#define timersub(a, b, r)
void ut_dbg_comparison_failed(const char *lhs_expr, const L &lhs_value, const char *op, const char *rhs_expr, const R &rhs_value, const char *file, uint64_t line)
Definition: ut0dbg.h:57
void ut_set_assert_callback(std::function< void()> &callback)
Set a callback function to be called before exiting.
Definition: ut0dbg.cc:48