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