1287516Sdim/* Declarations for debug printing functions. 2287516Sdim 3287516Sdim Copyright (C) 2014-2023 Free Software Foundation, Inc. 4287516Sdim 5287516Sdim This file is part of GDB. 6287516Sdim 7287516Sdim This program is free software; you can redistribute it and/or modify 8287516Sdim it under the terms of the GNU General Public License as published by 9287516Sdim the Free Software Foundation; either version 3 of the License, or 10287516Sdim (at your option) any later version. 11287516Sdim 12287516Sdim This program is distributed in the hope that it will be useful, 13287516Sdim but WITHOUT ANY WARRANTY; without even the implied warranty of 14287516Sdim MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15287516Sdim GNU General Public License for more details. 16287516Sdim 17287516Sdim You should have received a copy of the GNU General Public License 18287516Sdim along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19287516Sdim 20287516Sdim#ifndef COMMON_COMMON_DEBUG_H 21287516Sdim#define COMMON_COMMON_DEBUG_H 22287516Sdim 23287516Sdim#include "gdbsupport/gdb_optional.h" 24#include "gdbsupport/preprocessor.h" 25 26#include <stdarg.h> 27 28/* Set to true to enable debugging of hardware breakpoint/ 29 watchpoint support code. */ 30 31extern bool show_debug_regs; 32 33/* Print a formatted message to the appropriate channel for 34 debugging output for the client. */ 35 36extern void debug_printf (const char *format, ...) 37 ATTRIBUTE_PRINTF (1, 2); 38 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. */ 42 43extern void debug_vprintf (const char *format, va_list ap) 44 ATTRIBUTE_PRINTF (1, 0); 45 46/* Print a debug statement prefixed with the module and function name, and 47 with a newline at the end. */ 48 49extern void ATTRIBUTE_PRINTF (3, 4) debug_prefixed_printf 50 (const char *module, const char *func, const char *format, ...); 51 52/* Print a debug statement prefixed with the module and function name, and 53 with a newline at the end. */ 54 55extern void ATTRIBUTE_PRINTF (3, 0) debug_prefixed_vprintf 56 (const char *module, const char *func, const char *format, va_list args); 57 58/* Helper to define "_debug_print" macros. 59 60 DEBUG_ENABLED_COND is an expression that evaluates to true if the debugging 61 statement is enabled and should be printed. 62 63 The other arguments, as well as the name of the current function, are 64 forwarded to debug_prefixed_printf. */ 65 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) 73 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) 81 82/* Nesting depth of scoped_debug_start_end objects. */ 83 84extern int debug_print_depth; 85 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. */ 90 91template<typename PT> 92struct scoped_debug_start_end 93{ 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. 98 99 DEBUG_ENABLED should either be of type 'bool &' or should be a type 100 that can be invoked. 101 102 MODULE and FUNC are forwarded to debug_prefixed_printf. 103 104 START_PREFIX and END_PREFIX are the statements to print on construction and 105 destruction, respectively. 106 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. */ 111 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) 122 { 123 if (is_debug_enabled ()) 124 { 125 if (fmt != nullptr) 126 { 127 m_msg = string_vprintf (fmt, args); 128 debug_prefixed_printf (m_module, m_func, "%s: %s", 129 start_prefix, m_msg->c_str ()); 130 } 131 else 132 debug_prefixed_printf (m_module, m_func, "%s", start_prefix); 133 134 ++debug_print_depth; 135 m_must_decrement_print_depth = true; 136 } 137 } 138 139 DISABLE_COPY_AND_ASSIGN (scoped_debug_start_end); 140 141 scoped_debug_start_end (scoped_debug_start_end &&other) = default; 142 143 ~scoped_debug_start_end () 144 { 145 if (m_must_decrement_print_depth) 146 { 147 gdb_assert (debug_print_depth > 0); 148 --debug_print_depth; 149 } 150 151 if (is_debug_enabled ()) 152 { 153 if (m_with_format) 154 { 155 if (m_msg.has_value ()) 156 debug_prefixed_printf (m_module, m_func, "%s: %s", 157 m_end_prefix, m_msg->c_str ()); 158 else 159 { 160 /* A format string was passed to the constructor, but debug 161 control variable wasn't set at the time, so we don't have the 162 rendering of the format string. */ 163 debug_prefixed_printf (m_module, m_func, "%s: <%s debugging was not enabled on entry>", 164 m_end_prefix, m_module); 165 } 166 } 167 else 168 debug_prefixed_printf (m_module, m_func, "%s", m_end_prefix); 169 } 170 } 171 172private: 173 174 /* This function is specialized based on the type PT. Returns true if 175 M_DEBUG_ENABLED indicates this debug setting is enabled, otherwise, 176 return false. */ 177 bool is_debug_enabled () const; 178 179 /* Reference to the debug setting, or a callback that can read the debug 180 setting. Access the value of this by calling IS_DEBUG_ENABLED. */ 181 PT &m_debug_enabled; 182 183 const char *m_module; 184 const char *m_func; 185 const char *m_end_prefix; 186 187 /* The result of formatting the format string in the constructor. */ 188 gdb::optional<std::string> m_msg; 189 190 /* True is a non-nullptr format was passed to the constructor. */ 191 bool m_with_format; 192 193 /* This is used to handle the case where debugging is enabled during 194 construction but not during destruction, or vice-versa. We want to make 195 sure there are as many increments are there are decrements. */ 196 bool m_must_decrement_print_depth = false; 197}; 198 199/* Implementation of is_debug_enabled when PT is an invokable type. */ 200 201template<typename PT> 202inline bool 203scoped_debug_start_end<PT>::is_debug_enabled () const 204{ 205 return m_debug_enabled (); 206} 207 208/* Implementation of is_debug_enabled when PT is 'bool &'. */ 209 210template<> 211inline bool 212scoped_debug_start_end<bool &>::is_debug_enabled () const 213{ 214 return m_debug_enabled; 215} 216 217/* Wrapper around the scoped_debug_start_end constructor to allow the 218 caller to create an object using 'auto' type, the actual type will be 219 based on the type of the PRED argument. All arguments are forwarded to 220 the scoped_debug_start_end constructor. */ 221 222template<typename PT> 223static inline scoped_debug_start_end<PT &> ATTRIBUTE_NULL_PRINTF (6, 7) 224make_scoped_debug_start_end (PT &&pred, const char *module, const char *func, 225 const char *start_prefix, 226 const char *end_prefix, const char *fmt, ...) 227{ 228 va_list args; 229 va_start (args, fmt); 230 auto res = scoped_debug_start_end<PT &> (pred, module, func, start_prefix, 231 end_prefix, fmt, args); 232 va_end (args); 233 234 return res; 235} 236 237/* Helper to define a module-specific start/end debug macro. */ 238 239#define scoped_debug_start_end(debug_enabled, module, fmt, ...) \ 240 auto CONCAT(scoped_debug_start_end, __LINE__) \ 241 = make_scoped_debug_start_end (debug_enabled, module, \ 242 __func__, "start", "end", \ 243 fmt, ##__VA_ARGS__) 244 245/* Helper to define a module-specific enter/exit debug macro. This is a special 246 case of `scoped_debug_start_end` where the start and end messages are "enter" 247 and "exit", to denote entry and exit of a function. */ 248 249#define scoped_debug_enter_exit(debug_enabled, module) \ 250 auto CONCAT(scoped_debug_start_end, __LINE__) \ 251 = make_scoped_debug_start_end (debug_enabled, module, \ 252 __func__, "enter", "exit", \ 253 nullptr) 254 255#endif /* COMMON_COMMON_DEBUG_H */ 256