]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdbsupport/common-debug.h
gdb: add missing test for completion of invalid /FMT strings
[thirdparty/binutils-gdb.git] / gdbsupport / common-debug.h
1 /* Declarations for debug printing functions.
2
3 Copyright (C) 2014-2021 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
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.
11
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.
16
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/>. */
19
20 #ifndef COMMON_COMMON_DEBUG_H
21 #define COMMON_COMMON_DEBUG_H
22
23 /* Set to true to enable debugging of hardware breakpoint/
24 watchpoint support code. */
25
26 extern bool show_debug_regs;
27
28 /* Print a formatted message to the appropriate channel for
29 debugging output for the client. */
30
31 extern void debug_printf (const char *format, ...)
32 ATTRIBUTE_PRINTF (1, 2);
33
34 /* Print a formatted message to the appropriate channel for
35 debugging output for the client. This function must be
36 provided by the client. */
37
38 extern void debug_vprintf (const char *format, va_list ap)
39 ATTRIBUTE_PRINTF (1, 0);
40
41 /* Print a debug statement prefixed with the module and function name, and
42 with a newline at the end. */
43
44 extern void ATTRIBUTE_PRINTF (3, 4) debug_prefixed_printf
45 (const char *module, const char *func, const char *format, ...);
46
47 /* Print a debug statement prefixed with the module and function name, and
48 with a newline at the end. */
49
50 extern void ATTRIBUTE_PRINTF (3, 0) debug_prefixed_vprintf
51 (const char *module, const char *func, const char *format, va_list args);
52
53 /* Helper to define "_debug_print" macros.
54
55 DEBUG_ENABLED_COND is an expression that evaluates to true if the debugging
56 statement is enabled and should be printed.
57
58 The other arguments, as well as the name of the current function, are
59 forwarded to debug_prefixed_printf. */
60
61 #define debug_prefixed_printf_cond(debug_enabled_cond, module, fmt, ...) \
62 do \
63 { \
64 if (debug_enabled_cond) \
65 debug_prefixed_printf (module, __func__, fmt, ##__VA_ARGS__); \
66 } \
67 while (0)
68
69 /* Nesting depth of scoped_debug_start_end objects. */
70
71 extern int debug_print_depth;
72
73 /* Print a message on construction and destruction, to denote the start and end
74 of an operation. Increment DEBUG_PRINT_DEPTH on construction and decrement
75 it on destruction, such that nested debug statements will be printed with
76 an indent and appear "inside" this one. */
77
78 struct scoped_debug_start_end
79 {
80 /* DEBUG_ENABLED is a reference to a variable that indicates whether debugging
81 is enabled, so if the debug statements should be printed. Is is read
82 separately at construction and destruction, such that the start statement
83 could be printed but not the end statement, or vice-versa.
84
85 MODULE and FUNC are forwarded to debug_prefixed_printf.
86
87 START_MSG and END_MSG are the statements to print on construction and
88 destruction, respectively. */
89
90 scoped_debug_start_end (bool &debug_enabled, const char *module,
91 const char *func, const char *start_msg,
92 const char *end_msg)
93 : m_debug_enabled (debug_enabled),
94 m_module (module),
95 m_func (func),
96 m_end_msg (end_msg)
97 {
98 if (m_debug_enabled)
99 {
100 debug_prefixed_printf (m_module, m_func, "%s", start_msg);
101 ++debug_print_depth;
102 m_must_decrement_print_depth = true;
103 }
104 }
105
106 DISABLE_COPY_AND_ASSIGN (scoped_debug_start_end);
107
108 ~scoped_debug_start_end ()
109 {
110 if (m_must_decrement_print_depth)
111 {
112 gdb_assert (debug_print_depth > 0);
113 --debug_print_depth;
114 }
115
116 if (m_debug_enabled)
117 {
118 debug_prefixed_printf (m_module, m_func, "%s", m_end_msg);
119 }
120 }
121
122 private:
123 bool &m_debug_enabled;
124 const char *m_module;
125 const char *m_func;
126 const char *m_end_msg;
127
128 /* This is used to handle the case where debugging is enabled during
129 construction but not during destruction, or vice-versa. We want to make
130 sure there are as many increments are there are decrements. */
131
132 bool m_must_decrement_print_depth = false;
133 };
134
135 /* Helper to define a module-specific start/end debug macro. */
136
137 #define scoped_debug_start_end(debug_enabled, module, msg) \
138 scoped_debug_start_end CONCAT(scoped_debug_start_end, __LINE__) \
139 (debug_enabled, module, __func__, "start: " msg, "end: " msg)
140
141 /* Helper to define a module-specific enter/exit debug macro. This is a special
142 case of `scoped_debug_start_end` where the start and end messages are "enter"
143 and "exit", to denote entry and exit of a function. */
144
145 #define scoped_debug_enter_exit(debug_enabled, module) \
146 scoped_debug_start_end CONCAT(scoped_debug_start_end, __LINE__) \
147 (debug_enabled, module, __func__, "enter", "exit")
148
149 #endif /* COMMON_COMMON_DEBUG_H */