Automatic date update in version.in
[binutils-gdb.git] / gdbsupport / common-debug.h
blobb41d6a401cc8a4cf7c6020ff70ea1a88680a2543
1 /* Declarations for debug printing functions.
3 Copyright (C) 2014-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #ifndef COMMON_COMMON_DEBUG_H
21 #define COMMON_COMMON_DEBUG_H
23 #include <optional>
24 #include "gdbsupport/preprocessor.h"
26 #include <stdarg.h>
28 /* Set to true to enable debugging of hardware breakpoint/
29 watchpoint support code. */
31 extern bool show_debug_regs;
33 /* Print a formatted message to the appropriate channel for
34 debugging output for the client. */
36 extern void debug_printf (const char *format, ...)
37 ATTRIBUTE_PRINTF (1, 2);
39 /* Print a formatted message to the appropriate channel for
40 debugging output for the client. This function must be
41 provided by the client. */
43 extern void debug_vprintf (const char *format, va_list ap)
44 ATTRIBUTE_PRINTF (1, 0);
46 /* Print a debug statement prefixed with the module and function name, and
47 with a newline at the end. */
49 extern void ATTRIBUTE_PRINTF (3, 4) debug_prefixed_printf
50 (const char *module, const char *func, const char *format, ...);
52 /* Print a debug statement prefixed with the module and function name, and
53 with a newline at the end. */
55 extern void ATTRIBUTE_PRINTF (3, 0) debug_prefixed_vprintf
56 (const char *module, const char *func, const char *format, va_list args);
58 /* Helper to define "_debug_print" macros.
60 DEBUG_ENABLED_COND is an expression that evaluates to true if the debugging
61 statement is enabled and should be printed.
63 The other arguments, as well as the name of the current function, are
64 forwarded to debug_prefixed_printf. */
66 #define debug_prefixed_printf_cond(debug_enabled_cond, module, fmt, ...) \
67 do \
68 { \
69 if (debug_enabled_cond) \
70 debug_prefixed_printf (module, __func__, fmt, ##__VA_ARGS__); \
71 } \
72 while (0)
74 #define debug_prefixed_printf_cond_nofunc(debug_enabled_cond, module, fmt, ...) \
75 do \
76 { \
77 if (debug_enabled_cond) \
78 debug_prefixed_printf (module, nullptr, fmt, ##__VA_ARGS__); \
79 } \
80 while (0)
82 /* Nesting depth of scoped_debug_start_end objects. */
84 extern int debug_print_depth;
86 /* Print a message on construction and destruction, to denote the start and end
87 of an operation. Increment DEBUG_PRINT_DEPTH on construction and decrement
88 it on destruction, such that nested debug statements will be printed with
89 an indent and appear "inside" this one. */
91 template<typename PT>
92 struct scoped_debug_start_end
94 /* DEBUG_ENABLED is a reference to a variable that indicates whether debugging
95 is enabled, so if the debug statements should be printed. Is is read
96 separately at construction and destruction, such that the start statement
97 could be printed but not the end statement, or vice-versa.
99 DEBUG_ENABLED should either be of type 'bool &' or should be a type
100 that can be invoked.
102 MODULE and FUNC are forwarded to debug_prefixed_printf.
104 START_PREFIX and END_PREFIX are the statements to print on construction and
105 destruction, respectively.
107 If the FMT format string is non-nullptr, then a `: ` is appended to the
108 messages, followed by the rendering of that format string with ARGS.
109 The format string is rendered during construction and is re-used as is
110 for the message on exit. */
112 scoped_debug_start_end (PT &debug_enabled, const char *module,
113 const char *func, const char *start_prefix,
114 const char *end_prefix, const char *fmt,
115 va_list args)
116 ATTRIBUTE_NULL_PRINTF (7, 0)
117 : m_debug_enabled (debug_enabled),
118 m_module (module),
119 m_func (func),
120 m_end_prefix (end_prefix),
121 m_with_format (fmt != nullptr)
123 if (is_debug_enabled ())
125 if (fmt != nullptr)
127 m_msg = string_vprintf (fmt, args);
128 debug_prefixed_printf (m_module, m_func, "%s: %s",
129 start_prefix, m_msg->c_str ());
131 else
132 debug_prefixed_printf (m_module, m_func, "%s", start_prefix);
134 ++debug_print_depth;
135 m_must_decrement_print_depth = true;
139 DISABLE_COPY_AND_ASSIGN (scoped_debug_start_end);
141 scoped_debug_start_end (scoped_debug_start_end &&other)
142 : m_debug_enabled (other.m_debug_enabled),
143 m_module (other.m_module),
144 m_func (other.m_func),
145 m_end_prefix (other.m_end_prefix),
146 m_msg (other.m_msg),
147 m_with_format (other.m_with_format),
148 m_must_decrement_print_depth (other.m_must_decrement_print_depth),
149 m_disabled (other.m_disabled)
151 /* Avoid the moved-from object doing the side-effects in its destructor. */
152 other.m_disabled = true;
155 ~scoped_debug_start_end ()
157 if (m_disabled)
158 return;
160 if (m_must_decrement_print_depth)
162 gdb_assert (debug_print_depth > 0);
163 --debug_print_depth;
166 if (is_debug_enabled ())
168 if (m_with_format)
170 if (m_msg.has_value ())
171 debug_prefixed_printf (m_module, m_func, "%s: %s",
172 m_end_prefix, m_msg->c_str ());
173 else
175 /* A format string was passed to the constructor, but debug
176 control variable wasn't set at the time, so we don't have the
177 rendering of the format string. */
178 debug_prefixed_printf (m_module, m_func, "%s: <%s debugging was not enabled on entry>",
179 m_end_prefix, m_module);
182 else
183 debug_prefixed_printf (m_module, m_func, "%s", m_end_prefix);
187 private:
189 /* This function is specialized based on the type PT. Returns true if
190 M_DEBUG_ENABLED indicates this debug setting is enabled, otherwise,
191 return false. */
192 bool is_debug_enabled () const;
194 /* Reference to the debug setting, or a callback that can read the debug
195 setting. Access the value of this by calling IS_DEBUG_ENABLED. */
196 PT &m_debug_enabled;
198 const char *m_module;
199 const char *m_func;
200 const char *m_end_prefix;
202 /* The result of formatting the format string in the constructor. */
203 std::optional<std::string> m_msg;
205 /* True is a non-nullptr format was passed to the constructor. */
206 bool m_with_format;
208 /* This is used to handle the case where debugging is enabled during
209 construction but not during destruction, or vice-versa. We want to make
210 sure there are as many increments are there are decrements. */
211 bool m_must_decrement_print_depth = false;
213 /* True if this object was moved from, and the destructor behavior must be
214 inhibited. */
215 bool m_disabled = false;
218 /* Implementation of is_debug_enabled when PT is an invokable type. */
220 template<typename PT>
221 inline bool
222 scoped_debug_start_end<PT>::is_debug_enabled () const
224 return m_debug_enabled ();
227 /* Implementation of is_debug_enabled when PT is 'bool &'. */
229 template<>
230 inline bool
231 scoped_debug_start_end<bool &>::is_debug_enabled () const
233 return m_debug_enabled;
236 /* Wrapper around the scoped_debug_start_end constructor to allow the
237 caller to create an object using 'auto' type, the actual type will be
238 based on the type of the PRED argument. All arguments are forwarded to
239 the scoped_debug_start_end constructor. */
241 template<typename PT>
242 static inline scoped_debug_start_end<PT &> ATTRIBUTE_NULL_PRINTF (6, 7)
243 make_scoped_debug_start_end (PT &&pred, const char *module, const char *func,
244 const char *start_prefix,
245 const char *end_prefix, const char *fmt, ...)
247 va_list args;
248 va_start (args, fmt);
249 auto res = scoped_debug_start_end<PT &> (pred, module, func, start_prefix,
250 end_prefix, fmt, args);
251 va_end (args);
253 return res;
256 /* Helper to define a module-specific start/end debug macro. */
258 #define scoped_debug_start_end(debug_enabled, module, fmt, ...) \
259 auto CONCAT(scoped_debug_start_end, __LINE__) \
260 = make_scoped_debug_start_end (debug_enabled, module, \
261 __func__, "start", "end", \
262 fmt, ##__VA_ARGS__)
264 /* Helper to define a module-specific enter/exit debug macro. This is a special
265 case of `scoped_debug_start_end` where the start and end messages are "enter"
266 and "exit", to denote entry and exit of a function. */
268 #define scoped_debug_enter_exit(debug_enabled, module) \
269 auto CONCAT(scoped_debug_start_end, __LINE__) \
270 = make_scoped_debug_start_end (debug_enabled, module, \
271 __func__, "enter", "exit", \
272 nullptr)
274 #endif /* COMMON_COMMON_DEBUG_H */