complaints.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /* Support for complaint handling during symbol reading in GDB.
  2. Copyright (C) 1990-2022 Free Software Foundation, Inc.
  3. This file is part of GDB.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  14. #include "defs.h"
  15. #include "complaints.h"
  16. #include "command.h"
  17. #include "gdbcmd.h"
  18. #include "gdbsupport/selftest.h"
  19. #include <unordered_map>
  20. /* Map format strings to counters. */
  21. static std::unordered_map<const char *, int> counters;
  22. /* How many complaints about a particular thing should be printed
  23. before we stop whining about it? Default is no whining at all,
  24. since so many systems have ill-constructed symbol files. */
  25. int stop_whining = 0;
  26. /* See complaints.h. */
  27. void
  28. complaint_internal (const char *fmt, ...)
  29. {
  30. va_list args;
  31. if (++counters[fmt] > stop_whining)
  32. return;
  33. va_start (args, fmt);
  34. if (deprecated_warning_hook)
  35. (*deprecated_warning_hook) (fmt, args);
  36. else
  37. {
  38. gdb_puts (_("During symbol reading: "), gdb_stderr);
  39. gdb_vprintf (gdb_stderr, fmt, args);
  40. gdb_puts ("\n", gdb_stderr);
  41. }
  42. va_end (args);
  43. }
  44. /* See complaints.h. */
  45. void
  46. clear_complaints ()
  47. {
  48. counters.clear ();
  49. }
  50. static void
  51. complaints_show_value (struct ui_file *file, int from_tty,
  52. struct cmd_list_element *cmd, const char *value)
  53. {
  54. gdb_printf (file, _("Max number of complaints about incorrect"
  55. " symbols is %s.\n"),
  56. value);
  57. }
  58. #if GDB_SELF_TEST
  59. namespace selftests {
  60. /* Entry point for complaints unit tests. */
  61. static void
  62. test_complaints ()
  63. {
  64. std::unordered_map<const char *, int> tmp;
  65. scoped_restore reset_counters = make_scoped_restore (&counters, tmp);
  66. scoped_restore reset_stop_whining = make_scoped_restore (&stop_whining, 2);
  67. #define CHECK_COMPLAINT(STR, CNT) \
  68. do \
  69. { \
  70. std::string output; \
  71. execute_fn_to_string (output, []() { complaint (STR); }, false); \
  72. std::string expected \
  73. = _("During symbol reading: ") + std::string (STR "\n"); \
  74. SELF_CHECK (output == expected); \
  75. SELF_CHECK (counters[STR] == CNT); \
  76. } while (0)
  77. #define CHECK_COMPLAINT_SILENT(STR, CNT) \
  78. do \
  79. { \
  80. std::string output; \
  81. execute_fn_to_string (output, []() { complaint (STR); }, false); \
  82. SELF_CHECK (output.empty ()); \
  83. SELF_CHECK (counters[STR] == CNT); \
  84. } while (0)
  85. CHECK_COMPLAINT ("maintenance complaint 0", 1);
  86. CHECK_COMPLAINT ("maintenance complaint 0", 2);
  87. CHECK_COMPLAINT_SILENT ("maintenance complaint 0", 3);
  88. CHECK_COMPLAINT ("maintenance complaint 1", 1);
  89. clear_complaints ();
  90. CHECK_COMPLAINT ("maintenance complaint 0", 1);
  91. #undef CHECK_COMPLAINT
  92. #undef CHECK_COMPLAINT_SILENT
  93. }
  94. } // namespace selftests
  95. #endif /* GDB_SELF_TEST */
  96. void _initialize_complaints ();
  97. void
  98. _initialize_complaints ()
  99. {
  100. add_setshow_zinteger_cmd ("complaints", class_support,
  101. &stop_whining, _("\
  102. Set max number of complaints about incorrect symbols."), _("\
  103. Show max number of complaints about incorrect symbols."), NULL,
  104. NULL, complaints_show_value,
  105. &setlist, &showlist);
  106. #if GDB_SELF_TEST
  107. selftests::register_test ("complaints", selftests::test_complaints);
  108. #endif /* GDB_SELF_TEST */
  109. }