diff options
author | Andrew Burgess <aburgess@redhat.com> | 2022-12-06 12:49:55 +0000 |
---|---|---|
committer | Andrew Burgess <aburgess@redhat.com> | 2022-12-14 10:56:47 +0000 |
commit | 2698da268bdd0b4a6815a15b41a42bac5f928ca7 (patch) | |
tree | ec64c7c492dff05d06e21431688b0a11a6c1b2d2 /gdbsupport | |
parent | b1e678d920e4468cfd69a40560ee24834f6bdce4 (diff) | |
download | gdb-2698da268bdd0b4a6815a15b41a42bac5f928ca7.zip gdb-2698da268bdd0b4a6815a15b41a42bac5f928ca7.tar.gz gdb-2698da268bdd0b4a6815a15b41a42bac5f928ca7.tar.bz2 |
gdb: add SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT
After the previous commit converted symbol-lookup debug to use the new
debug scheme, this commit adds SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT.
The previous commit didn't add SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT
because symbol-lookup debug is controlled by an 'unsigned int' rather
than a 'bool' control variable, we use the numeric value to offer
different levels of verbosity for symbol-lookup debug.
The *_SCOPED_DEBUG_ENTER_EXIT mechanism currently relies on capturing
a reference to the bool control variable, and evaluating the variable
both on entry, and at exit, this is done in the scoped_debug_start_end
class (see gdbsupport/common-debug.h).
This commit templates scoped_debug_start_end so that the class can
accept either a 'bool &' or an invokable object, e.g. a lambda
function, or a function pointer.
The existing scoped_debug_start_end and scoped_debug_enter_exit macros
in common-debug.h are updated to support scoped_debug_enter_exit being
templated, however, nothing outside of common-debug.h needs to change.
I've then added SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT in symtab.h, and
added a couple of token uses in symtab.c. I didn't want to add too
much in this first commit, this is really about updating
common-debug.h to support this new functionality.
Within symtab.h I created a couple of global functions that can be
used to query the status of the symbol_lookup_debug control variable,
these functions are then used within the two existing macros:
symbol_lookup_debug_printf
symbol_lookup_debug_printf_v
and also in the new SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT macro.
Diffstat (limited to 'gdbsupport')
-rw-r--r-- | gdbsupport/common-debug.h | 92 |
1 files changed, 73 insertions, 19 deletions
diff --git a/gdbsupport/common-debug.h b/gdbsupport/common-debug.h index 00a1e15..904c1a1 100644 --- a/gdbsupport/common-debug.h +++ b/gdbsupport/common-debug.h @@ -88,6 +88,7 @@ extern int debug_print_depth; it on destruction, such that nested debug statements will be printed with an indent and appear "inside" this one. */ +template<typename PT> struct scoped_debug_start_end { /* DEBUG_ENABLED is a reference to a variable that indicates whether debugging @@ -95,35 +96,35 @@ struct scoped_debug_start_end separately at construction and destruction, such that the start statement could be printed but not the end statement, or vice-versa. + DEBUG_ENABLED should either be of type 'bool &' or should be a type + that can be invoked. + MODULE and FUNC are forwarded to debug_prefixed_printf. START_PREFIX and END_PREFIX are the statements to print on construction and destruction, respectively. If the FMT format string is non-nullptr, then a `: ` is appended to the - messages, followed by the rendering of that format string. The format - string is rendered during construction and is re-used as is for the - message on exit. */ + messages, followed by the rendering of that format string with ARGS. + The format string is rendered during construction and is re-used as is + for the message on exit. */ - scoped_debug_start_end (bool &debug_enabled, const char *module, + scoped_debug_start_end (PT &debug_enabled, const char *module, const char *func, const char *start_prefix, - const char *end_prefix, const char *fmt, ...) - ATTRIBUTE_NULL_PRINTF (7, 8) + const char *end_prefix, const char *fmt, + va_list args) + ATTRIBUTE_NULL_PRINTF (7, 0) : m_debug_enabled (debug_enabled), m_module (module), m_func (func), m_end_prefix (end_prefix), m_with_format (fmt != nullptr) { - if (m_debug_enabled) + if (is_debug_enabled ()) { if (fmt != nullptr) { - va_list args; - va_start (args, fmt); m_msg = string_vprintf (fmt, args); - va_end (args); - debug_prefixed_printf (m_module, m_func, "%s: %s", start_prefix, m_msg->c_str ()); } @@ -137,6 +138,8 @@ struct scoped_debug_start_end DISABLE_COPY_AND_ASSIGN (scoped_debug_start_end); + scoped_debug_start_end (scoped_debug_start_end &&other) = default; + ~scoped_debug_start_end () { if (m_must_decrement_print_depth) @@ -145,7 +148,7 @@ struct scoped_debug_start_end --debug_print_depth; } - if (m_debug_enabled) + if (is_debug_enabled ()) { if (m_with_format) { @@ -167,7 +170,16 @@ struct scoped_debug_start_end } private: - bool &m_debug_enabled; + + /* This function is specialized based on the type PT. Returns true if + M_DEBUG_ENABLED indicates this debug setting is enabled, otherwise, + return false. */ + bool is_debug_enabled () const; + + /* Reference to the debug setting, or a callback that can read the debug + setting. Access the value of this by calling IS_DEBUG_ENABLED. */ + PT &m_debug_enabled; + const char *m_module; const char *m_func; const char *m_end_prefix; @@ -184,18 +196,60 @@ private: bool m_must_decrement_print_depth = false; }; +/* Implementation of is_debug_enabled when PT is an invokable type. */ + +template<typename PT> +inline bool +scoped_debug_start_end<PT>::is_debug_enabled () const +{ + return m_debug_enabled (); +} + +/* Implementation of is_debug_enabled when PT is 'bool &'. */ + +template<> +inline bool +scoped_debug_start_end<bool &>::is_debug_enabled () const +{ + return m_debug_enabled; +} + +/* Wrapper around the scoped_debug_start_end constructor to allow the + caller to create an object using 'auto' type, the actual type will be + based on the type of the PRED argument. All arguments are forwarded to + the scoped_debug_start_end constructor. */ + +template<typename PT> +static inline scoped_debug_start_end<PT &> ATTRIBUTE_NULL_PRINTF (6, 7) +make_scoped_debug_start_end (PT &&pred, const char *module, const char *func, + const char *start_prefix, + const char *end_prefix, const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + auto res = scoped_debug_start_end<PT &> (pred, module, func, start_prefix, + end_prefix, fmt, args); + va_end (args); + + return res; +} + /* Helper to define a module-specific start/end debug macro. */ -#define scoped_debug_start_end(debug_enabled, module, fmt, ...) \ - scoped_debug_start_end CONCAT(scoped_debug_start_end, __LINE__) \ - (debug_enabled, module, __func__, "start", "end", fmt, ##__VA_ARGS__) +#define scoped_debug_start_end(debug_enabled, module, fmt, ...) \ + auto CONCAT(scoped_debug_start_end, __LINE__) \ + = make_scoped_debug_start_end (debug_enabled, module, \ + __func__, "start", "end", \ + fmt, ##__VA_ARGS__) /* Helper to define a module-specific enter/exit debug macro. This is a special case of `scoped_debug_start_end` where the start and end messages are "enter" and "exit", to denote entry and exit of a function. */ -#define scoped_debug_enter_exit(debug_enabled, module) \ - scoped_debug_start_end CONCAT(scoped_debug_start_end, __LINE__) \ - (debug_enabled, module, __func__, "enter", "exit", nullptr) +#define scoped_debug_enter_exit(debug_enabled, module) \ + auto CONCAT(scoped_debug_start_end, __LINE__) \ + = make_scoped_debug_start_end (debug_enabled, module, \ + __func__, "enter", "exit", \ + nullptr) #endif /* COMMON_COMMON_DEBUG_H */ |