Skip to content

Commit 0df0cce

Browse files
committed
gdbsupport: allow passing format string to scoped_debug_start_end
A little thing that bothers me with scoped_debug_start_end is that it's not possible to pass a format string to add context to the messages: the start and end messages are fixed. It was done like this at the time because there's the risk that debug output is not enabled on entry (when the constructor runs) but is enabled on exit (when the destructor runs). For example, a user debugging from a top-gdb may manually enable a debug_foo variable. If debug output is disabled while the constructor runs, we won't render the format string (to minimize overhead) so it won't be available in the destructor. I think it would be nice to be able to use a format string along with scoped_debug_start_end, and I think it's unfortunate that such a narrow use case prevents it. So with this patch, I propose that we allow passing a format string to scoped_debug_start_end, and if the rare situation described above happens, then we just show a "sorry, message not available" kind of message. The following patch makes use of this. gdbsupport/ChangeLog: * common-debug.h (struct scoped_debug_start_end) <scoped_debug_start_end>: Change start_msg/end_msg for start_prefix/end_prefix. Add format string parameter and make variadic. <~scoped_debug_start_end>: Adjust. <m_end_msg>: Rename to... <m_end_prefix>: ... this. <m_with_format>: New. <m_msg>: New. (scoped_debug_start_end): Make variadic. (scoped_debug_enter_exit): Adjust. Change-Id: I9427ce8877a246a46694b3a1fec3837dc6954d6e
1 parent c90e7d6 commit 0df0cce

File tree

2 files changed

+68
-12
lines changed

2 files changed

+68
-12
lines changed

gdbsupport/ChangeLog

+14
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
2021-04-24 Simon Marchi <[email protected]>
2+
3+
* common-debug.h (struct scoped_debug_start_end)
4+
<scoped_debug_start_end>: Change start_msg/end_msg for
5+
start_prefix/end_prefix. Add format string parameter and make
6+
variadic.
7+
<~scoped_debug_start_end>: Adjust.
8+
<m_end_msg>: Rename to...
9+
<m_end_prefix>: ... this.
10+
<m_with_format>: New.
11+
<m_msg>: New.
12+
(scoped_debug_start_end): Make variadic.
13+
(scoped_debug_enter_exit): Adjust.
14+
115
2021-04-24 Simon Marchi <[email protected]>
216

317
* observable.h (class observable) <struct observer> <observer>:

gdbsupport/common-debug.h

+54-12
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020
#ifndef COMMON_COMMON_DEBUG_H
2121
#define COMMON_COMMON_DEBUG_H
2222

23+
#include "gdbsupport/gdb_optional.h"
2324
#include "gdbsupport/preprocessor.h"
2425

26+
#include <stdarg.h>
27+
2528
/* Set to true to enable debugging of hardware breakpoint/
2629
watchpoint support code. */
2730

@@ -94,20 +97,39 @@ struct scoped_debug_start_end
9497
9598
MODULE and FUNC are forwarded to debug_prefixed_printf.
9699
97-
START_MSG and END_MSG are the statements to print on construction and
98-
destruction, respectively. */
100+
START_PREFIX and END_PREFIX are the statements to print on construction and
101+
destruction, respectively.
102+
103+
If the FMT format string is non-nullptr, then a `: ` is appended to the
104+
messages, followed by the rendering of that format string. The format
105+
string is rendered during construction and is re-used as is for the
106+
message on exit. */
99107

100108
scoped_debug_start_end (bool &debug_enabled, const char *module,
101-
const char *func, const char *start_msg,
102-
const char *end_msg)
109+
const char *func, const char *start_prefix,
110+
const char *end_prefix, const char *fmt, ...)
111+
ATTRIBUTE_NULL_PRINTF (7, 8)
103112
: m_debug_enabled (debug_enabled),
104113
m_module (module),
105114
m_func (func),
106-
m_end_msg (end_msg)
115+
m_end_prefix (end_prefix),
116+
m_with_format (fmt != nullptr)
107117
{
108118
if (m_debug_enabled)
109119
{
110-
debug_prefixed_printf (m_module, m_func, "%s", start_msg);
120+
if (fmt != nullptr)
121+
{
122+
va_list args;
123+
va_start (args, fmt);
124+
m_msg = string_vprintf (fmt, args);
125+
va_end (args);
126+
127+
debug_prefixed_printf (m_module, m_func, "%s: %s",
128+
start_prefix, m_msg->c_str ());
129+
}
130+
else
131+
debug_prefixed_printf (m_module, m_func, "%s", start_prefix);
132+
111133
++debug_print_depth;
112134
m_must_decrement_print_depth = true;
113135
}
@@ -125,35 +147,55 @@ struct scoped_debug_start_end
125147

126148
if (m_debug_enabled)
127149
{
128-
debug_prefixed_printf (m_module, m_func, "%s", m_end_msg);
150+
if (m_with_format)
151+
{
152+
if (m_msg.has_value ())
153+
debug_prefixed_printf (m_module, m_func, "%s: %s",
154+
m_end_prefix, m_msg->c_str ());
155+
else
156+
{
157+
/* A format string was passed to the constructor, but debug
158+
control variable wasn't set at the time, so we don't have the
159+
rendering of the format string. */
160+
debug_prefixed_printf (m_module, m_func, "%s: <%s debugging was not enabled on entry>",
161+
m_end_prefix, m_module);
162+
}
163+
}
164+
else
165+
debug_prefixed_printf (m_module, m_func, "%s", m_end_prefix);
129166
}
130167
}
131168

132169
private:
133170
bool &m_debug_enabled;
134171
const char *m_module;
135172
const char *m_func;
136-
const char *m_end_msg;
173+
const char *m_end_prefix;
174+
175+
/* The result of formatting the format string in the constructor. */
176+
gdb::optional<std::string> m_msg;
177+
178+
/* True is a non-nullptr format was passed to the constructor. */
179+
bool m_with_format;
137180

138181
/* This is used to handle the case where debugging is enabled during
139182
construction but not during destruction, or vice-versa. We want to make
140183
sure there are as many increments are there are decrements. */
141-
142184
bool m_must_decrement_print_depth = false;
143185
};
144186

145187
/* Helper to define a module-specific start/end debug macro. */
146188

147-
#define scoped_debug_start_end(debug_enabled, module, msg) \
189+
#define scoped_debug_start_end(debug_enabled, module, fmt, ...) \
148190
scoped_debug_start_end CONCAT(scoped_debug_start_end, __LINE__) \
149-
(debug_enabled, module, __func__, "start: " msg, "end: " msg)
191+
(debug_enabled, module, __func__, "start", "end", fmt, ##__VA_ARGS__)
150192

151193
/* Helper to define a module-specific enter/exit debug macro. This is a special
152194
case of `scoped_debug_start_end` where the start and end messages are "enter"
153195
and "exit", to denote entry and exit of a function. */
154196

155197
#define scoped_debug_enter_exit(debug_enabled, module) \
156198
scoped_debug_start_end CONCAT(scoped_debug_start_end, __LINE__) \
157-
(debug_enabled, module, __func__, "enter", "exit")
199+
(debug_enabled, module, __func__, "enter", "exit", nullptr)
158200

159201
#endif /* COMMON_COMMON_DEBUG_H */

0 commit comments

Comments
 (0)