GDB (xrefs)
Loading...
Searching...
No Matches
complaints.c
Go to the documentation of this file.
1/* Support for complaint handling during symbol reading in GDB.
2
3 Copyright (C) 1990-2023 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#include "defs.h"
21#include "complaints.h"
22#include "command.h"
23#include "gdbcmd.h"
24#include "gdbsupport/selftest.h"
25#include <unordered_map>
26#include <mutex>
27
28/* Map format strings to counters. */
29
30static std::unordered_map<const char *, int> counters;
31
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
37
38#if CXX_STD_THREAD
39static std::mutex complaint_mutex;
40#endif /* CXX_STD_THREAD */
41
42/* See complaints.h. */
43
44void
45complaint_internal (const char *fmt, ...)
46{
47 va_list args;
48
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 }
56
57 va_start (args, fmt);
58
60 (*deprecated_warning_hook) (fmt, args);
61 else
62 {
63 gdb_puts (_("During symbol reading: "), gdb_stderr);
64 gdb_vprintf (gdb_stderr, fmt, args);
65 gdb_puts ("\n", gdb_stderr);
66 }
67
68 va_end (args);
69}
70
71/* See complaints.h. */
72
73void
75{
76 counters.clear ();
77}
78
79/* See complaints.h. */
80
82
83/* See complaints.h. */
84
86 : m_saved_warning_hook (deprecated_warning_hook)
87{
88 /* These cannot be stacked. */
89 gdb_assert (g_complaint_interceptor == nullptr);
92}
93
94/* A helper that wraps a warning hook. */
95
96static void
97wrap_warning_hook (void (*hook) (const char *, va_list), ...)
98{
99 va_list args;
100 va_start (args, hook);
101 hook ("%s", args);
102 va_end (args);
103}
104
105/* See complaints.h. */
106
108{
109 for (const std::string &str : m_complaints)
110 {
113 else
114 gdb_printf (gdb_stderr, _("During symbol reading: %s\n"),
115 str.c_str ());
116 }
117
118 g_complaint_interceptor = nullptr;
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
133static void
134complaints_show_value (struct ui_file *file, int from_tty,
135 struct cmd_list_element *cmd, const char *value)
136{
137 gdb_printf (file, _("Max number of complaints about incorrect"
138 " symbols is %s.\n"),
139 value);
140}
141
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; \
158 execute_fn_to_string (output, []() { complaint (STR); }, false); \
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; \
169 execute_fn_to_string (output, []() { complaint (STR); }, false); \
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);
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
190void
192{
194 &stop_whining, _("\
195Set max number of complaints about incorrect symbols."), _("\
196Show max number of complaints about incorrect symbols."), NULL,
198 &setlist, &showlist);
199
200#if GDB_SELF_TEST
201 selftests::register_test ("complaints", selftests::test_complaints);
202#endif /* GDB_SELF_TEST */
203}
void static void static complaint_interceptor * g_complaint_interceptor
Definition complaints.h:90
std::unordered_set< std::string > m_complaints
Definition complaints.h:78
void static void issue_complaint(const char *, va_list) ATTRIBUTE_PRINTF(1
Definition complaints.c:125
void(* m_saved_warning_hook)(const char *, va_list) ATTRIBUTE_FPTR_PRINTF(1
Definition complaints.h:81
struct cmd_list_element * showlist
Definition cli-cmds.c:127
struct cmd_list_element * setlist
Definition cli-cmds.c:119
set_show_commands add_setshow_zinteger_cmd(const char *name, enum command_class theclass, int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
@ class_support
Definition command.h:58
void _initialize_complaints()
Definition complaints.c:191
void complaint_internal(const char *fmt,...)
Definition complaints.c:45
int stop_whining
Definition complaints.c:36
static void complaints_show_value(struct ui_file *file, int from_tty, struct cmd_list_element *cmd, const char *value)
Definition complaints.c:134
void clear_complaints()
Definition complaints.c:74
static void wrap_warning_hook(void(*hook)(const char *, va_list),...)
Definition complaints.c:97
static std::unordered_map< const char *, int > counters
Definition complaints.c:30
int void(* deprecated_warning_hook)(const char *, va_list) ATTRIBUTE_FPTR_PRINTF(1
Definition top.c:224
Definition value.h:130
void gdb_vprintf(struct ui_file *stream, const char *format, va_list args)
Definition utils.c:1874
void gdb_printf(struct ui_file *stream, const char *format,...)
Definition utils.c:1886
void gdb_puts(const char *linebuffer, struct ui_file *stream)
Definition utils.c:1809
#define gdb_stderr
Definition utils.h:187