]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/complaints.c
gdb, gdbserver, gdbsupport: remove includes of early headers
[thirdparty/binutils-gdb.git] / gdb / complaints.c
CommitLineData
c906108c 1/* Support for complaint handling during symbol reading in GDB.
b9caf505 2
1d506c26 3 Copyright (C) 1990-2024 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
c5aa993b 10 (at your option) any later version.
c906108c 11
c5aa993b
JM
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.
c906108c 16
c5aa993b 17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c 19
d55e5aa6 20#include "complaints.h"
4de283e4 21#include "command.h"
c906108c 22#include "gdbcmd.h"
54b815dd 23#include "run-on-main-thread.h"
86fe51fc 24#include "gdbsupport/selftest.h"
4de283e4 25#include <unordered_map>
da632297 26#include <mutex>
c906108c 27
ff1cf532 28/* Map format strings to counters. */
c906108c 29
ff1cf532 30static std::unordered_map<const char *, int> counters;
c906108c 31
b9caf505
AC
32/* How many complaints about a particular thing should be printed
33 before we stop whining about it? Default is no whining at all,
34 since so many systems have ill-constructed symbol files. */
35
62d7ae92 36int stop_whining = 0;
b9caf505 37
da632297
TT
38#if CXX_STD_THREAD
39static std::mutex complaint_mutex;
40#endif /* CXX_STD_THREAD */
41
de54e1a5 42/* See complaints.h. */
b9caf505 43
de54e1a5
TT
44void
45complaint_internal (const char *fmt, ...)
b9caf505 46{
de54e1a5 47 va_list args;
c5504eaf 48
da632297
TT
49 {
50#if CXX_STD_THREAD
51 std::lock_guard<std::mutex> guard (complaint_mutex);
52#endif
53 if (++counters[fmt] > stop_whining)
54 return;
55 }
b9caf505 56
de54e1a5 57 va_start (args, fmt);
b9caf505 58
49346fa7
AVK
59 warning_hook_handler handler = get_warning_hook_handler ();
60 if (handler != nullptr)
61 handler (fmt, args);
b9caf505 62 else
c906108c 63 {
0426ad51 64 gdb_puts (_("During symbol reading: "), gdb_stderr);
19a7b8ab 65 gdb_vprintf (gdb_stderr, fmt, args);
0426ad51 66 gdb_puts ("\n", gdb_stderr);
c906108c 67 }
c906108c 68
b9caf505
AC
69 va_end (args);
70}
71
5ca8c39f 72/* See complaints.h. */
c906108c
SS
73
74void
5ca8c39f 75clear_complaints ()
c906108c 76{
ff1cf532 77 counters.clear ();
c906108c
SS
78}
79
da632297
TT
80/* See complaints.h. */
81
54b815dd 82thread_local complaint_interceptor *complaint_interceptor::g_complaint_interceptor;
da632297
TT
83
84/* See complaints.h. */
85
86complaint_interceptor::complaint_interceptor ()
49346fa7
AVK
87 : m_saved_complaint_interceptor (&g_complaint_interceptor, this),
88 m_saved_warning_hook (issue_complaint)
da632297 89{
da632297
TT
90}
91
92/* A helper that wraps a warning hook. */
93
94static void
49346fa7 95wrap_warning_hook (warning_hook_handler hook, ...)
da632297
TT
96{
97 va_list args;
98 va_start (args, hook);
99 hook ("%s", args);
100 va_end (args);
101}
102
103/* See complaints.h. */
104
54b815dd
TT
105void
106re_emit_complaints (const complaint_collection &complaints)
da632297 107{
54b815dd
TT
108 gdb_assert (is_main_thread ());
109
110 for (const std::string &str : complaints)
da632297 111 {
49346fa7
AVK
112 warning_hook_handler handler = get_warning_hook_handler ();
113 if (handler != nullptr)
114 wrap_warning_hook (handler, str.c_str ());
da632297
TT
115 else
116 gdb_printf (gdb_stderr, _("During symbol reading: %s\n"),
117 str.c_str ());
118 }
da632297
TT
119}
120
121/* See complaints.h. */
122
123void
124complaint_interceptor::issue_complaint (const char *fmt, va_list args)
125{
126#if CXX_STD_THREAD
127 std::lock_guard<std::mutex> guard (complaint_mutex);
128#endif
129 g_complaint_interceptor->m_complaints.insert (string_vprintf (fmt, args));
130}
131
335cca0d 132static void
08546159
AC
133complaints_show_value (struct ui_file *file, int from_tty,
134 struct cmd_list_element *cmd, const char *value)
335cca0d 135{
6cb06a8c
TT
136 gdb_printf (file, _("Max number of complaints about incorrect"
137 " symbols is %s.\n"),
138 value);
335cca0d
AC
139}
140
86fe51fc
TV
141#if GDB_SELF_TEST
142namespace selftests {
143
144/* Entry point for complaints unit tests. */
145
146static void
147test_complaints ()
148{
149 std::unordered_map<const char *, int> tmp;
150 scoped_restore reset_counters = make_scoped_restore (&counters, tmp);
151 scoped_restore reset_stop_whining = make_scoped_restore (&stop_whining, 2);
152
153#define CHECK_COMPLAINT(STR, CNT) \
154 do \
155 { \
156 std::string output; \
84a6adfd 157 execute_fn_to_string (output, []() { complaint (STR); }, false); \
86fe51fc
TV
158 std::string expected \
159 = _("During symbol reading: ") + std::string (STR "\n"); \
160 SELF_CHECK (output == expected); \
161 SELF_CHECK (counters[STR] == CNT); \
162 } while (0)
163
164#define CHECK_COMPLAINT_SILENT(STR, CNT) \
165 do \
166 { \
167 std::string output; \
84a6adfd 168 execute_fn_to_string (output, []() { complaint (STR); }, false); \
86fe51fc
TV
169 SELF_CHECK (output.empty ()); \
170 SELF_CHECK (counters[STR] == CNT); \
171 } while (0)
172
173 CHECK_COMPLAINT ("maintenance complaint 0", 1);
174 CHECK_COMPLAINT ("maintenance complaint 0", 2);
175 CHECK_COMPLAINT_SILENT ("maintenance complaint 0", 3);
176 CHECK_COMPLAINT ("maintenance complaint 1", 1);
177 clear_complaints ();
178 CHECK_COMPLAINT ("maintenance complaint 0", 1);
179
180#undef CHECK_COMPLAINT
181#undef CHECK_COMPLAINT_SILENT
182}
183
184
185} // namespace selftests
186#endif /* GDB_SELF_TEST */
187
6c265988 188void _initialize_complaints ();
c906108c 189void
6c265988 190_initialize_complaints ()
c906108c 191{
aff410f1
MS
192 add_setshow_zinteger_cmd ("complaints", class_support,
193 &stop_whining, _("\
3d263c1d 194Set max number of complaints about incorrect symbols."), _("\
335cca0d 195Show max number of complaints about incorrect symbols."), NULL,
08546159 196 NULL, complaints_show_value,
b3f42336 197 &setlist, &showlist);
86fe51fc
TV
198
199#if GDB_SELF_TEST
200 selftests::register_test ("complaints", selftests::test_complaints);
201#endif /* GDB_SELF_TEST */
c906108c 202}