MySQL  8.0.27
Source Code Documentation
my_dbug.h
Go to the documentation of this file.
1 /* Copyright (c) 2000, 2021, Oracle and/or its affiliates.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License, version 2.0,
5  as published by the Free Software Foundation.
6 
7  This program is also distributed with certain software (including
8  but not limited to OpenSSL) that is licensed under separate terms,
9  as designated in a particular file or component or in included license
10  documentation. The authors of MySQL hereby grant you an additional
11  permission to link the program and your derivative works with the
12  separately licensed software that they have included with MySQL.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License, version 2.0, for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 #ifndef MY_DBUG_INCLUDED
24 #define MY_DBUG_INCLUDED
25 
26 /**
27  @file include/my_dbug.h
28 */
29 
30 #ifdef MY_MSCRT_DEBUG
31 #include <crtdbg.h>
32 #endif
33 #include <stdlib.h>
34 
35 #include "my_compiler.h"
36 
37 #include <string.h>
38 
39 #if !defined(NDEBUG)
40 #include <assert.h> // IWYU pragma: keep
41 #include <stdio.h>
42 #endif
43 
44 #if !defined(NDEBUG)
45 
47  const char *func; /* function name of the previous stack frame */
48  int func_len; /* how much to print from func */
49  const char *file; /* filename of the function of previous frame */
50  unsigned int level; /* this nesting level, highest bit enables tracing */
51  struct _db_stack_frame_ *prev; /* pointer to the previous frame */
52 };
53 
54 struct CODE_STATE;
55 
56 extern int _db_keyword_(struct CODE_STATE *, const char *, int);
57 extern int _db_explain_(struct CODE_STATE *cs, char *buf, size_t len);
58 extern int _db_explain_init_(char *buf, size_t len);
59 extern int _db_is_pushed_(void);
60 extern void _db_process_(const char *name);
61 extern void _db_push_(const char *control);
62 extern void _db_pop_(void);
63 extern void _db_set_(const char *control);
64 extern void _db_set_init_(const char *control);
65 extern void _db_enter_(const char *_func_, int func_len, const char *_file_,
66  unsigned int _line_,
67  struct _db_stack_frame_ *_stack_frame_);
68 extern void _db_return_(unsigned int _line_,
69  struct _db_stack_frame_ *_stack_frame_);
70 extern void _db_pargs_(unsigned int _line_, const char *keyword);
71 extern int _db_enabled_();
72 extern void _db_doprnt_(const char *format, ...)
73  MY_ATTRIBUTE((format(printf, 1, 2)));
74 extern void _db_dump_(unsigned int _line_, const char *keyword,
75  const unsigned char *memory, size_t length);
76 extern void _db_end_(void);
77 extern void _db_lock_file_(void);
78 extern void _db_unlock_file_(void);
79 extern FILE *_db_fp_(void);
80 extern void _db_flush_();
81 
82 #ifdef __cplusplus
83 
84 #if defined(__GNUC__)
85 // GCC, Clang, and compatible compilers.
86 #define DBUG_PRETTY_FUNCTION __PRETTY_FUNCTION__
87 #elif defined(__FUNCSIG__)
88 // For MSVC; skips the __cdecl. (__PRETTY_FUNCTION__ in GCC is not a
89 // preprocessor constant, but __FUNCSIG__ in MSVC is.)
90 #define DBUG_PRETTY_FUNCTION strchr(__FUNCSIG__, ' ') + 1
91 #else
92 // Standard C++; does not include the class name.
93 #define DBUG_PRETTY_FUNCTION __func__
94 #endif
95 
96 /**
97  A RAII helper to do DBUG_ENTER / DBUG_RETURN for you automatically. Use like
98  this:
99 
100  int foo() {
101  DBUG_TRACE;
102  return 42;
103  }
104  */
106  public:
107  AutoDebugTrace(const char *function, const char *filename, int line) {
108  // Remove the return type, if it's there.
109  const char *begin = strchr(function, ' ');
110  if (begin != nullptr) {
111  function = begin + 1;
112  }
113 
114  // Cut it off at the first parenthesis; the argument list is
115  // often too long to be interesting.
116  const char *end = strchr(function, '(');
117 
118  if (end == nullptr) {
119  _db_enter_(function, static_cast<int>(strlen(function)), filename, line,
120  &m_stack_frame);
121  } else {
122  _db_enter_(function, static_cast<int>(end - function), filename, line,
123  &m_stack_frame);
124  }
125  }
126 
128 
129  private:
131 };
132 
133 #define DBUG_TRACE \
134  AutoDebugTrace _db_trace(DBUG_PRETTY_FUNCTION, __FILE__, __LINE__)
135 
136 #endif
137 
138 #define DBUG_ENTER(a) \
139  struct _db_stack_frame_ _db_stack_frame_; \
140  _db_enter_(a, ::strlen(a), __FILE__, __LINE__, &_db_stack_frame_)
141 
142 #define DBUG_RETURN(a1) \
143  do { \
144  _db_return_(__LINE__, &_db_stack_frame_); \
145  return (a1); \
146  } while (0)
147 #define DBUG_VOID_RETURN \
148  do { \
149  _db_return_(__LINE__, &_db_stack_frame_); \
150  return; \
151  } while (0)
152 #define DBUG_EXECUTE(keyword, a1) \
153  do { \
154  if (_db_keyword_(0, (keyword), 0)) { \
155  a1 \
156  } \
157  } while (0)
158 #define DBUG_EXECUTE_IF(keyword, a1) \
159  do { \
160  if (_db_keyword_(0, (keyword), 1)) { \
161  a1 \
162  } \
163  } while (0)
164 #define DBUG_EVALUATE(keyword, a1, a2) \
165  (_db_keyword_(0, (keyword), 0) ? (a1) : (a2))
166 #define DBUG_EVALUATE_IF(keyword, a1, a2) \
167  (_db_keyword_(0, (keyword), 1) ? (a1) : (a2))
168 #define DBUG_PRINT(keyword, arglist) \
169  do { \
170  _db_pargs_(__LINE__, keyword); \
171  if (_db_enabled_()) { \
172  _db_doprnt_ arglist; \
173  } \
174  } while (0)
175 
176 #define DBUG_PUSH(a1) _db_push_(a1)
177 #define DBUG_POP() _db_pop_()
178 #define DBUG_SET(a1) _db_set_(a1)
179 #define DBUG_SET_INITIAL(a1) _db_set_init_(a1)
180 #define DBUG_PROCESS(a1) _db_process_(a1)
181 #define DBUG_FILE _db_fp_()
182 #define DBUG_DUMP(keyword, a1, a2) _db_dump_(__LINE__, keyword, a1, a2)
183 #define DBUG_END() _db_end_()
184 #define DBUG_LOCK_FILE _db_lock_file_()
185 #define DBUG_UNLOCK_FILE _db_unlock_file_()
186 #define DBUG_EXPLAIN(buf, len) _db_explain_(0, (buf), (len))
187 #define DBUG_EXPLAIN_INITIAL(buf, len) _db_explain_init_((buf), (len))
188 #ifndef _WIN32
189 #define DBUG_ABORT() (_db_flush_(), abort())
190 #define DBUG_EXIT() (_db_flush_(), exit(2))
191 #else
192 #include <crtdbg.h>
193 
194 #define DBUG_ABORT() \
195  (_db_flush_(), (void)_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE), \
196  (void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR), abort())
197 #define DBUG_EXIT() \
198  (_db_flush_(), (void)_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE), \
199  (void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR), _exit(2))
200 #endif
201 
202 /*
203  Make the program fail, without creating a core file.
204  abort() will send SIGABRT which (most likely) generates core.
205  Use SIGKILL instead, which cannot be caught.
206  We also pause the current thread, until the signal is actually delivered.
207  An alternative would be to use _exit(EXIT_FAILURE),
208  but then valgrind would report lots of memory leaks.
209  */
210 #ifdef _WIN32
211 #define DBUG_SUICIDE() DBUG_EXIT()
212 #else
213 extern void _db_suicide_() MY_ATTRIBUTE((noreturn));
214 extern void _db_flush_gcov_();
215 #define DBUG_SUICIDE() (_db_flush_(), _db_suicide_())
216 #endif
217 
218 #else /* No debugger */
219 
220 #ifdef __cplusplus
221 #define DBUG_TRACE \
222  do { \
223  } while (false)
224 #endif
225 #define DBUG_ENTER(a1)
226 #define DBUG_RETURN(a1) \
227  do { \
228  return (a1); \
229  } while (0)
230 #define DBUG_VOID_RETURN \
231  do { \
232  return; \
233  } while (0)
234 #define DBUG_EXECUTE(keyword, a1) \
235  do { \
236  } while (0)
237 #define DBUG_EXECUTE_IF(keyword, a1) \
238  do { \
239  } while (0)
240 #define DBUG_EVALUATE(keyword, a1, a2) (a2)
241 #define DBUG_EVALUATE_IF(keyword, a1, a2) (a2)
242 #define DBUG_PRINT(keyword, arglist) \
243  do { \
244  } while (0)
245 #define DBUG_PUSH(a1) \
246  do { \
247  } while (0)
248 #define DBUG_SET(a1) \
249  do { \
250  } while (0)
251 #define DBUG_SET_INITIAL(a1) \
252  do { \
253  } while (0)
254 #define DBUG_POP() \
255  do { \
256  } while (0)
257 #define DBUG_PROCESS(a1) \
258  do { \
259  } while (0)
260 #define DBUG_DUMP(keyword, a1, a2) \
261  do { \
262  } while (0)
263 #define DBUG_END() \
264  do { \
265  } while (0)
266 #define DBUG_LOCK_FILE \
267  do { \
268  } while (0)
269 #define DBUG_FILE (stderr)
270 #define DBUG_UNLOCK_FILE \
271  do { \
272  } while (0)
273 #define DBUG_EXPLAIN(buf, len)
274 #define DBUG_EXPLAIN_INITIAL(buf, len)
275 #define DBUG_ABORT() \
276  do { \
277  } while (0)
278 #define DBUG_SUICIDE() \
279  do { \
280  } while (0)
281 
282 #endif
283 
284 #ifdef __cplusplus
285 #if !defined(NDEBUG)
286 #include <sstream>
287 #include <string>
288 
289 /*
290  A C++ interface to the DBUG_PRINT macro. The DBUG_LOG macro takes two
291  arguments. The first argument is the keyword, as that of the
292  DBUG_PRINT. The 2nd argument 'v' will be passed to a C++ output stream.
293  This enables the use of C++ style output stream operator. In the code, it
294  will be used as follows:
295 
296  DBUG_LOG("blob", "space: " << space_id);
297 
298  Note: DBUG_PRINT() has a limitation of 1024 bytes for a single
299  print out. So, this limitation is there for DBUG_LOG macro also.
300 */
301 
302 #define DBUG_LOG(keyword, v) \
303  do { \
304  if (_db_enabled_()) { \
305  std::ostringstream sout; \
306  sout << v; \
307  DBUG_PRINT(keyword, ("%s", sout.str().c_str())); \
308  } \
309  } while (0)
310 
311 #else /* NDEBUG */
312 #define DBUG_LOG(keyword, v) \
313  do { \
314  } while (0)
315 #endif /* NDEBUG */
316 
317 /**
318  A type-safe interface to DBUG_EXECUTE_IF, where the debug action to
319  activate when the keyword is provided is given as a callable object
320  (typically a lambda).
321 
322  @note The body of the callable will be checked by the compiler even
323  in optimized mode.
324 
325  @param keyword String literal which will enable this debug action.
326  @param clos Callable object taking no arguments which will be
327  called in debug mode if the keyword is enabled.
328  */
329 template <class DBGCLOS>
330 inline void dbug(const char *keyword [[maybe_unused]],
331  DBGCLOS &&clos [[maybe_unused]]) {
332  DBUG_EXECUTE_IF(keyword, clos(););
333 }
334 
335 #endif /* __cplusplus */
336 #endif /* MY_DBUG_INCLUDED */
A RAII helper to do DBUG_ENTER / DBUG_RETURN for you automatically.
Definition: my_dbug.h:105
AutoDebugTrace(const char *function, const char *filename, int line)
Definition: my_dbug.h:107
~AutoDebugTrace()
Definition: my_dbug.h:127
_db_stack_frame_ m_stack_frame
Definition: my_dbug.h:130
Header for compiler-dependent features.
FILE * _db_fp_(void)
Definition: dbug.cc:1732
void _db_dump_(unsigned int _line_, const char *keyword, const unsigned char *memory, size_t length)
Definition: dbug.cc:1369
int _db_keyword_(struct CODE_STATE *, const char *, int)
Definition: dbug.cc:1758
void dbug(const char *keyword[[maybe_unused]], DBGCLOS &&clos[[maybe_unused]])
A type-safe interface to DBUG_EXECUTE_IF, where the debug action to activate when the keyword is prov...
Definition: my_dbug.h:330
void _db_lock_file_(void)
Definition: dbug.cc:2167
void _db_return_(unsigned int _line_, struct _db_stack_frame_ *_stack_frame_)
Definition: dbug.cc:1189
void _db_flush_()
Definition: dbug.cc:2123
#define DBUG_EXECUTE_IF(keyword, a1)
Definition: my_dbug.h:158
void _db_unlock_file_(void)
Definition: dbug.cc:2174
void _db_set_(const char *control)
Definition: dbug.cc:800
void _db_pop_(void)
Definition: dbug.cc:904
void _db_end_(void)
Definition: dbug.cc:1660
void _db_set_init_(const char *control)
Definition: dbug.cc:879
void _db_suicide_()
Definition: dbug.cc:2144
void _db_doprnt_(const char *format,...)
Definition: dbug.cc:1311
void _db_flush_gcov_()
Definition: dbug.cc:2135
void _db_enter_(const char *_func_, int func_len, const char *_file_, unsigned int _line_, struct _db_stack_frame_ *_stack_frame_)
Definition: dbug.cc:1120
void _db_process_(const char *name)
Definition: dbug.cc:397
int _db_explain_init_(char *buf, size_t len)
Definition: dbug.cc:1078
void _db_push_(const char *control)
Definition: dbug.cc:836
int _db_explain_(struct CODE_STATE *cs, char *buf, size_t len)
Definition: dbug.cc:1018
void _db_pargs_(unsigned int _line_, const char *keyword)
Definition: dbug.cc:1251
int _db_enabled_()
Definition: dbug.cc:1275
int _db_is_pushed_(void)
Returns true if session-local settings have been set.
Definition: dbug.cc:858
Definition: buf0block_hint.cc:29
const std::string FILE("FILE")
Definition: commit_order_queue.h:33
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:75
Definition: aligned_atomic.h:40
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:191
const char * filename
Definition: pfs_example_component_population.cc:64
case opt name
Definition: sslopt-case.h:32
Definition: dbug.cc:217
int func_len
Definition: dbug.cc:220
Definition: my_dbug.h:46
struct _db_stack_frame_ * prev
Definition: my_dbug.h:51
const char * func
Definition: my_dbug.h:47
int func_len
Definition: my_dbug.h:48
unsigned int level
Definition: my_dbug.h:50
const char * file
Definition: my_dbug.h:49