Allow thread-pool.h to work without threads
[binutils-gdb.git] / gdb / maint.c
1 /* Support for GDB maintenance commands.
2
3 Copyright (C) 1992-2022 Free Software Foundation, Inc.
4
5 Written by Fred Fish at Cygnus Support.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22
23 #include "defs.h"
24 #include "arch-utils.h"
25 #include <ctype.h>
26 #include <cmath>
27 #include <signal.h>
28 #include "command.h"
29 #include "gdbcmd.h"
30 #include "symtab.h"
31 #include "block.h"
32 #include "gdbtypes.h"
33 #include "demangle.h"
34 #include "gdbcore.h"
35 #include "expression.h" /* For language.h */
36 #include "language.h"
37 #include "symfile.h"
38 #include "objfiles.h"
39 #include "value.h"
40 #include "top.h"
41 #include "maint.h"
42 #include "gdbsupport/selftest.h"
43 #include "inferior.h"
44 #include "gdbsupport/thread-pool.h"
45
46 #include "cli/cli-decode.h"
47 #include "cli/cli-utils.h"
48 #include "cli/cli-setshow.h"
49 #include "cli/cli-cmds.h"
50
51 static void maintenance_do_deprecate (const char *, int);
52
53 #ifndef _WIN32
54 static void
55 maintenance_dump_me (const char *args, int from_tty)
56 {
57 if (query (_("Should GDB dump core? ")))
58 {
59 #ifdef __DJGPP__
60 /* SIGQUIT by default is ignored, so use SIGABRT instead. */
61 signal (SIGABRT, SIG_DFL);
62 kill (getpid (), SIGABRT);
63 #else
64 signal (SIGQUIT, SIG_DFL);
65 kill (getpid (), SIGQUIT);
66 #endif
67 }
68 }
69 #endif
70
71 /* Stimulate the internal error mechanism that GDB uses when an
72 internal problem is detected. Allows testing of the mechanism.
73 Also useful when the user wants to drop a core file but not exit
74 GDB. */
75
76 static void
77 maintenance_internal_error (const char *args, int from_tty)
78 {
79 internal_error (__FILE__, __LINE__, "%s", (args == NULL ? "" : args));
80 }
81
82 /* Stimulate the internal error mechanism that GDB uses when an
83 internal problem is detected. Allows testing of the mechanism.
84 Also useful when the user wants to drop a core file but not exit
85 GDB. */
86
87 static void
88 maintenance_internal_warning (const char *args, int from_tty)
89 {
90 internal_warning (__FILE__, __LINE__, "%s", (args == NULL ? "" : args));
91 }
92
93 /* Stimulate the internal error mechanism that GDB uses when an
94 demangler problem is detected. Allows testing of the mechanism. */
95
96 static void
97 maintenance_demangler_warning (const char *args, int from_tty)
98 {
99 demangler_warning (__FILE__, __LINE__, "%s", (args == NULL ? "" : args));
100 }
101
102 /* Old command to demangle a string. The command has been moved to "demangle".
103 It is kept for now because otherwise "mt demangle" gets interpreted as
104 "mt demangler-warning" which artificially creates an internal gdb error. */
105
106 static void
107 maintenance_demangle (const char *args, int from_tty)
108 {
109 gdb_printf (_("This command has been moved to \"demangle\".\n"));
110 }
111
112 static void
113 maintenance_time_display (const char *args, int from_tty)
114 {
115 if (args == NULL || *args == '\0')
116 gdb_printf (_("\"maintenance time\" takes a numeric argument.\n"));
117 else
118 set_per_command_time (strtol (args, NULL, 10));
119 }
120
121 static void
122 maintenance_space_display (const char *args, int from_tty)
123 {
124 if (args == NULL || *args == '\0')
125 gdb_printf ("\"maintenance space\" takes a numeric argument.\n");
126 else
127 set_per_command_space (strtol (args, NULL, 10));
128 }
129
130 /* Mini tokenizing lexer for 'maint info sections' command. */
131
132 static bool
133 match_substring (const char *string, const char *substr)
134 {
135 int substr_len = strlen (substr);
136 const char *tok;
137
138 while ((tok = strstr (string, substr)) != NULL)
139 {
140 /* Got a partial match. Is it a whole word? */
141 if (tok == string
142 || tok[-1] == ' '
143 || tok[-1] == '\t')
144 {
145 /* Token is delimited at the front... */
146 if (tok[substr_len] == ' '
147 || tok[substr_len] == '\t'
148 || tok[substr_len] == '\0')
149 {
150 /* Token is delimited at the rear. Got a whole-word match. */
151 return true;
152 }
153 }
154 /* Token didn't match as a whole word. Advance and try again. */
155 string = tok + 1;
156 }
157 return false;
158 }
159
160 /* Structure holding information about a single bfd section flag. This is
161 used by the "maintenance info sections" command to print the sections,
162 and for filtering which sections are printed. */
163
164 struct single_bfd_flag_info
165 {
166 /* The name of the section. This is what is printed for the flag, and
167 what the user enter in order to filter by flag. */
168 const char *name;
169
170 /* The bfd defined SEC_* flagword value for this flag. */
171 flagword value;
172 };
173
174 /* Vector of all the known bfd flags. */
175
176 static const single_bfd_flag_info bfd_flag_info[] =
177 {
178 { "ALLOC", SEC_ALLOC },
179 { "LOAD", SEC_LOAD },
180 { "RELOC", SEC_RELOC },
181 { "READONLY", SEC_READONLY },
182 { "CODE", SEC_CODE },
183 { "DATA", SEC_DATA },
184 { "ROM", SEC_ROM },
185 { "CONSTRUCTOR", SEC_CONSTRUCTOR },
186 { "HAS_CONTENTS", SEC_HAS_CONTENTS },
187 { "NEVER_LOAD", SEC_NEVER_LOAD },
188 { "COFF_SHARED_LIBRARY", SEC_COFF_SHARED_LIBRARY },
189 { "IS_COMMON", SEC_IS_COMMON }
190 };
191
192 /* For each flag in the global BFD_FLAG_INFO list, if FLAGS has a flag's
193 flagword value set, and STRING contains the flag's name then return
194 true, otherwise return false. STRING is never nullptr. */
195
196 static bool
197 match_bfd_flags (const char *string, flagword flags)
198 {
199 gdb_assert (string != nullptr);
200
201 for (const auto &f : bfd_flag_info)
202 {
203 if (flags & f.value
204 && match_substring (string, f.name))
205 return true;
206 }
207
208 return false;
209 }
210
211 /* Print the names of all flags set in FLAGS. The names are taken from the
212 BFD_FLAG_INFO global. */
213
214 static void
215 print_bfd_flags (flagword flags)
216 {
217 for (const auto &f : bfd_flag_info)
218 {
219 if (flags & f.value)
220 gdb_printf (" %s", f.name);
221 }
222 }
223
224 static void
225 maint_print_section_info (const char *name, flagword flags,
226 CORE_ADDR addr, CORE_ADDR endaddr,
227 unsigned long filepos, int addr_size)
228 {
229 gdb_printf (" %s", hex_string_custom (addr, addr_size));
230 gdb_printf ("->%s", hex_string_custom (endaddr, addr_size));
231 gdb_printf (" at %s",
232 hex_string_custom ((unsigned long) filepos, 8));
233 gdb_printf (": %s", name);
234 print_bfd_flags (flags);
235 gdb_printf ("\n");
236 }
237
238 /* Return the number of digits required to display COUNT in decimal.
239
240 Used when pretty printing index numbers to ensure all of the indexes line
241 up.*/
242
243 static int
244 index_digits (int count)
245 {
246 return ((int) log10 ((float) count)) + 1;
247 }
248
249 /* Helper function to pretty-print the section index of ASECT from ABFD.
250 The INDEX_DIGITS is the number of digits in the largest index that will
251 be printed, and is used to pretty-print the resulting string. */
252
253 static void
254 print_section_index (bfd *abfd,
255 asection *asect,
256 int index_digits)
257 {
258 std::string result
259 = string_printf (" [%d] ", gdb_bfd_section_index (abfd, asect));
260 /* The '+ 4' for the leading and trailing characters. */
261 gdb_printf ("%-*s", (index_digits + 4), result.c_str ());
262 }
263
264 /* Print information about ASECT from ABFD. The section will be printed using
265 the VMA's from the bfd, which will not be the relocated addresses for bfds
266 that should be relocated. The information must be printed with the same
267 layout as PRINT_OBJFILE_SECTION_INFO below.
268
269 ARG is the argument string passed by the user to the top level maintenance
270 info sections command. Used for filtering which sections are printed. */
271
272 static void
273 print_bfd_section_info (bfd *abfd, asection *asect, const char *arg,
274 int index_digits)
275 {
276 flagword flags = bfd_section_flags (asect);
277 const char *name = bfd_section_name (asect);
278
279 if (arg == NULL || *arg == '\0'
280 || match_substring (arg, name)
281 || match_bfd_flags (arg, flags))
282 {
283 struct gdbarch *gdbarch = gdbarch_from_bfd (abfd);
284 int addr_size = gdbarch_addr_bit (gdbarch) / 8;
285 CORE_ADDR addr, endaddr;
286
287 addr = bfd_section_vma (asect);
288 endaddr = addr + bfd_section_size (asect);
289 print_section_index (abfd, asect, index_digits);
290 maint_print_section_info (name, flags, addr, endaddr,
291 asect->filepos, addr_size);
292 }
293 }
294
295 /* Print information about ASECT which is GDB's wrapper around a section
296 from ABFD. The information must be printed with the same layout as
297 PRINT_BFD_SECTION_INFO above. PRINT_DATA holds information used to
298 filter which sections are printed, and for formatting the output.
299
300 ARG is the argument string passed by the user to the top level maintenance
301 info sections command. Used for filtering which sections are printed. */
302
303 static void
304 print_objfile_section_info (bfd *abfd, struct obj_section *asect,
305 const char *arg, int index_digits)
306 {
307 flagword flags = bfd_section_flags (asect->the_bfd_section);
308 const char *name = bfd_section_name (asect->the_bfd_section);
309
310 if (arg == NULL || *arg == '\0'
311 || match_substring (arg, name)
312 || match_bfd_flags (arg, flags))
313 {
314 struct gdbarch *gdbarch = gdbarch_from_bfd (abfd);
315 int addr_size = gdbarch_addr_bit (gdbarch) / 8;
316
317 print_section_index (abfd, asect->the_bfd_section, index_digits);
318 maint_print_section_info (name, flags,
319 asect->addr (), asect->endaddr (),
320 asect->the_bfd_section->filepos,
321 addr_size);
322 }
323 }
324
325 /* Find an obj_section, GDB's wrapper around a bfd section for ASECTION
326 from ABFD. It might be that no such wrapper exists (for example debug
327 sections don't have such wrappers) in which case nullptr is returned. */
328
329 obj_section *
330 maint_obj_section_from_bfd_section (bfd *abfd,
331 asection *asection,
332 objfile *ofile)
333 {
334 if (ofile->sections == nullptr)
335 return nullptr;
336
337 obj_section *osect
338 = &ofile->sections[gdb_bfd_section_index (abfd, asection)];
339
340 if (osect >= ofile->sections_end)
341 return nullptr;
342
343 return osect;
344 }
345
346 /* Print information about all sections from ABFD, which is the bfd
347 corresponding to OBJFILE. It is fine for OBJFILE to be nullptr, but
348 ABFD must never be nullptr. If OBJFILE is provided then the sections of
349 ABFD will (potentially) be displayed relocated (i.e. the object file was
350 loaded with add-symbol-file and custom offsets were provided).
351
352 HEADER is a string that describes this file, e.g. 'Exec file: ', or
353 'Core file: '.
354
355 ARG is a string used for filtering which sections are printed, this can
356 be nullptr for no filtering. See the top level 'maint info sections'
357 for a fuller description of the possible filtering strings. */
358
359 static void
360 maint_print_all_sections (const char *header, bfd *abfd, objfile *objfile,
361 const char *arg)
362 {
363 gdb_puts (header);
364 gdb_stdout->wrap_here (8);
365 gdb_printf ("`%s', ", bfd_get_filename (abfd));
366 gdb_stdout->wrap_here (8);
367 gdb_printf (_("file type %s.\n"), bfd_get_target (abfd));
368
369 int section_count = gdb_bfd_count_sections (abfd);
370 int digits = index_digits (section_count);
371
372 for (asection *sect : gdb_bfd_sections (abfd))
373 {
374 obj_section *osect = nullptr;
375
376 if (objfile != nullptr)
377 {
378 gdb_assert (objfile->sections != nullptr);
379 osect
380 = maint_obj_section_from_bfd_section (abfd, sect, objfile);
381 if (osect->the_bfd_section == nullptr)
382 osect = nullptr;
383 }
384
385 if (osect == nullptr)
386 print_bfd_section_info (abfd, sect, arg, digits);
387 else
388 print_objfile_section_info (abfd, osect, arg, digits);
389 }
390 }
391
392 /* The options for the "maintenance info sections" command. */
393
394 struct maint_info_sections_opts
395 {
396 /* For "-all-objects". */
397 bool all_objects = false;
398 };
399
400 static const gdb::option::option_def maint_info_sections_option_defs[] = {
401
402 gdb::option::flag_option_def<maint_info_sections_opts> {
403 "all-objects",
404 [] (maint_info_sections_opts *opts) { return &opts->all_objects; },
405 N_("Display information from all loaded object files."),
406 },
407 };
408
409 /* Create an option_def_group for the "maintenance info sections" options,
410 with CC_OPTS as context. */
411
412 static inline gdb::option::option_def_group
413 make_maint_info_sections_options_def_group (maint_info_sections_opts *cc_opts)
414 {
415 return {{maint_info_sections_option_defs}, cc_opts};
416 }
417
418 /* Completion for the "maintenance info sections" command. */
419
420 static void
421 maint_info_sections_completer (struct cmd_list_element *cmd,
422 completion_tracker &tracker,
423 const char *text, const char * /* word */)
424 {
425 /* Complete command options. */
426 const auto group = make_maint_info_sections_options_def_group (nullptr);
427 if (gdb::option::complete_options
428 (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group))
429 return;
430 const char *word = advance_to_expression_complete_word_point (tracker, text);
431
432 /* Offer completion for section flags, but not section names. This is
433 only a maintenance command after all, no point going over the top. */
434 std::vector<const char *> flags;
435 for (const auto &f : bfd_flag_info)
436 flags.push_back (f.name);
437 flags.push_back (nullptr);
438 complete_on_enum (tracker, flags.data (), text, word);
439 }
440
441 /* Implement the "maintenance info sections" command. */
442
443 static void
444 maintenance_info_sections (const char *arg, int from_tty)
445 {
446 /* Check if the "-all-objects" flag was passed. */
447 maint_info_sections_opts opts;
448 const auto group = make_maint_info_sections_options_def_group (&opts);
449 gdb::option::process_options
450 (&arg, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group);
451
452 for (objfile *ofile : current_program_space->objfiles ())
453 {
454 if (ofile->obfd == current_program_space->exec_bfd ())
455 maint_print_all_sections (_("Exec file: "), ofile->obfd, ofile, arg);
456 else if (opts.all_objects)
457 maint_print_all_sections (_("Object file: "), ofile->obfd, ofile, arg);
458 }
459
460 if (core_bfd)
461 maint_print_all_sections (_("Core file: "), core_bfd, nullptr, arg);
462 }
463
464 /* Implement the "maintenance info target-sections" command. */
465
466 static void
467 maintenance_info_target_sections (const char *arg, int from_tty)
468 {
469 bfd *abfd = nullptr;
470 int digits = 0;
471 const target_section_table *table
472 = target_get_section_table (current_inferior ()->top_target ());
473 if (table == nullptr)
474 return;
475
476 for (const target_section &sec : *table)
477 {
478 if (abfd == nullptr || sec.the_bfd_section->owner != abfd)
479 {
480 abfd = sec.the_bfd_section->owner;
481 digits = std::max (index_digits (gdb_bfd_count_sections (abfd)),
482 digits);
483 }
484 }
485
486 struct gdbarch *gdbarch = nullptr;
487 int addr_size = 0;
488 abfd = nullptr;
489 for (const target_section &sec : *table)
490 {
491 if (sec.the_bfd_section->owner != abfd)
492 {
493 abfd = sec.the_bfd_section->owner;
494 gdbarch = gdbarch_from_bfd (abfd);
495 addr_size = gdbarch_addr_bit (gdbarch) / 8;
496
497 gdb_printf (_("From '%s', file type %s:\n"),
498 bfd_get_filename (abfd), bfd_get_target (abfd));
499 }
500 print_bfd_section_info (abfd,
501 sec.the_bfd_section,
502 nullptr,
503 digits);
504 /* The magic '8 + digits' here ensures that the 'Start' is aligned
505 with the output of print_bfd_section_info. */
506 gdb_printf ("%*sStart: %s, End: %s, Owner token: %p\n",
507 (8 + digits), "",
508 hex_string_custom (sec.addr, addr_size),
509 hex_string_custom (sec.endaddr, addr_size),
510 sec.owner);
511 }
512 }
513
514 static void
515 maintenance_print_statistics (const char *args, int from_tty)
516 {
517 print_objfile_statistics ();
518 }
519
520 static void
521 maintenance_print_architecture (const char *args, int from_tty)
522 {
523 struct gdbarch *gdbarch = get_current_arch ();
524
525 if (args == NULL)
526 gdbarch_dump (gdbarch, gdb_stdout);
527 else
528 {
529 stdio_file file;
530
531 if (!file.open (args, "w"))
532 perror_with_name (_("maintenance print architecture"));
533 gdbarch_dump (gdbarch, &file);
534 }
535 }
536
537 /* The "maintenance translate-address" command converts a section and address
538 to a symbol. This can be called in two ways:
539 maintenance translate-address <secname> <addr>
540 or maintenance translate-address <addr>. */
541
542 static void
543 maintenance_translate_address (const char *arg, int from_tty)
544 {
545 CORE_ADDR address;
546 struct obj_section *sect;
547 const char *p;
548 struct bound_minimal_symbol sym;
549
550 if (arg == NULL || *arg == 0)
551 error (_("requires argument (address or section + address)"));
552
553 sect = NULL;
554 p = arg;
555
556 if (!isdigit (*p))
557 { /* See if we have a valid section name. */
558 while (*p && !isspace (*p)) /* Find end of section name. */
559 p++;
560 if (*p == '\000') /* End of command? */
561 error (_("Need to specify section name and address"));
562
563 int arg_len = p - arg;
564 p = skip_spaces (p + 1);
565
566 for (objfile *objfile : current_program_space->objfiles ())
567 ALL_OBJFILE_OSECTIONS (objfile, sect)
568 {
569 if (strncmp (sect->the_bfd_section->name, arg, arg_len) == 0)
570 goto found;
571 }
572
573 error (_("Unknown section %s."), arg);
574 found: ;
575 }
576
577 address = parse_and_eval_address (p);
578
579 if (sect)
580 sym = lookup_minimal_symbol_by_pc_section (address, sect);
581 else
582 sym = lookup_minimal_symbol_by_pc (address);
583
584 if (sym.minsym)
585 {
586 const char *symbol_name = sym.minsym->print_name ();
587 const char *symbol_offset
588 = pulongest (address - sym.value_address ());
589
590 sect = sym.obj_section ();
591 if (sect != NULL)
592 {
593 const char *section_name;
594 const char *obj_name;
595
596 gdb_assert (sect->the_bfd_section && sect->the_bfd_section->name);
597 section_name = sect->the_bfd_section->name;
598
599 gdb_assert (sect->objfile && objfile_name (sect->objfile));
600 obj_name = objfile_name (sect->objfile);
601
602 if (current_program_space->multi_objfile_p ())
603 gdb_printf (_("%s + %s in section %s of %s\n"),
604 symbol_name, symbol_offset,
605 section_name, obj_name);
606 else
607 gdb_printf (_("%s + %s in section %s\n"),
608 symbol_name, symbol_offset, section_name);
609 }
610 else
611 gdb_printf (_("%s + %s\n"), symbol_name, symbol_offset);
612 }
613 else if (sect)
614 gdb_printf (_("no symbol at %s:%s\n"),
615 sect->the_bfd_section->name, hex_string (address));
616 else
617 gdb_printf (_("no symbol at %s\n"), hex_string (address));
618
619 return;
620 }
621
622
623 /* When a command is deprecated the user will be warned the first time
624 the command is used. If possible, a replacement will be
625 offered. */
626
627 static void
628 maintenance_deprecate (const char *args, int from_tty)
629 {
630 if (args == NULL || *args == '\0')
631 {
632 gdb_printf (_("\"maintenance deprecate\" takes an argument,\n\
633 the command you want to deprecate, and optionally the replacement command\n\
634 enclosed in quotes.\n"));
635 }
636
637 maintenance_do_deprecate (args, 1);
638 }
639
640
641 static void
642 maintenance_undeprecate (const char *args, int from_tty)
643 {
644 if (args == NULL || *args == '\0')
645 {
646 gdb_printf (_("\"maintenance undeprecate\" takes an argument, \n\
647 the command you want to undeprecate.\n"));
648 }
649
650 maintenance_do_deprecate (args, 0);
651 }
652
653 /* You really shouldn't be using this. It is just for the testsuite.
654 Rather, you should use deprecate_cmd() when the command is created
655 in _initialize_blah().
656
657 This function deprecates a command and optionally assigns it a
658 replacement. */
659
660 static void
661 maintenance_do_deprecate (const char *text, int deprecate)
662 {
663 struct cmd_list_element *alias = NULL;
664 struct cmd_list_element *prefix_cmd = NULL;
665 struct cmd_list_element *cmd = NULL;
666
667 const char *start_ptr = NULL;
668 const char *end_ptr = NULL;
669 int len;
670 char *replacement = NULL;
671
672 if (text == NULL)
673 return;
674
675 if (!lookup_cmd_composition (text, &alias, &prefix_cmd, &cmd))
676 {
677 gdb_printf (_("Can't find command '%s' to deprecate.\n"), text);
678 return;
679 }
680
681 if (deprecate)
682 {
683 /* Look for a replacement command. */
684 start_ptr = strchr (text, '\"');
685 if (start_ptr != NULL)
686 {
687 start_ptr++;
688 end_ptr = strrchr (start_ptr, '\"');
689 if (end_ptr != NULL)
690 {
691 len = end_ptr - start_ptr;
692 replacement = savestring (start_ptr, len);
693 }
694 }
695 }
696
697 if (!start_ptr || !end_ptr)
698 replacement = NULL;
699
700
701 /* If they used an alias, we only want to deprecate the alias.
702
703 Note the MALLOCED_REPLACEMENT test. If the command's replacement
704 string was allocated at compile time we don't want to free the
705 memory. */
706 if (alias)
707 {
708 if (alias->malloced_replacement)
709 xfree ((char *) alias->replacement);
710
711 if (deprecate)
712 {
713 alias->deprecated_warn_user = 1;
714 alias->cmd_deprecated = 1;
715 }
716 else
717 {
718 alias->deprecated_warn_user = 0;
719 alias->cmd_deprecated = 0;
720 }
721 alias->replacement = replacement;
722 alias->malloced_replacement = 1;
723 return;
724 }
725 else if (cmd)
726 {
727 if (cmd->malloced_replacement)
728 xfree ((char *) cmd->replacement);
729
730 if (deprecate)
731 {
732 cmd->deprecated_warn_user = 1;
733 cmd->cmd_deprecated = 1;
734 }
735 else
736 {
737 cmd->deprecated_warn_user = 0;
738 cmd->cmd_deprecated = 0;
739 }
740 cmd->replacement = replacement;
741 cmd->malloced_replacement = 1;
742 return;
743 }
744 xfree (replacement);
745 }
746
747 /* Maintenance set/show framework. */
748
749 struct cmd_list_element *maintenance_set_cmdlist;
750 struct cmd_list_element *maintenance_show_cmdlist;
751
752 /* "maintenance with" command. */
753
754 static void
755 maintenance_with_cmd (const char *args, int from_tty)
756 {
757 with_command_1 ("maintenance set ", maintenance_set_cmdlist, args, from_tty);
758 }
759
760 /* "maintenance with" command completer. */
761
762 static void
763 maintenance_with_cmd_completer (struct cmd_list_element *ignore,
764 completion_tracker &tracker,
765 const char *text, const char * /*word*/)
766 {
767 with_command_completer_1 ("maintenance set ", tracker, text);
768 }
769
770 /* Profiling support. */
771
772 static bool maintenance_profile_p;
773 static void
774 show_maintenance_profile_p (struct ui_file *file, int from_tty,
775 struct cmd_list_element *c, const char *value)
776 {
777 gdb_printf (file, _("Internal profiling is %s.\n"), value);
778 }
779
780 #ifdef HAVE__ETEXT
781 extern char _etext;
782 #define TEXTEND &_etext
783 #elif defined (HAVE_ETEXT)
784 extern char etext;
785 #define TEXTEND &etext
786 #endif
787
788 #if defined (HAVE_MONSTARTUP) && defined (HAVE__MCLEANUP) && defined (TEXTEND)
789
790 static int profiling_state;
791
792 EXTERN_C void _mcleanup (void);
793
794 static void
795 mcleanup_wrapper (void)
796 {
797 if (profiling_state)
798 _mcleanup ();
799 }
800
801 EXTERN_C void monstartup (unsigned long, unsigned long);
802 extern int main ();
803
804 static void
805 maintenance_set_profile_cmd (const char *args, int from_tty,
806 struct cmd_list_element *c)
807 {
808 if (maintenance_profile_p == profiling_state)
809 return;
810
811 profiling_state = maintenance_profile_p;
812
813 if (maintenance_profile_p)
814 {
815 static int profiling_initialized;
816
817 if (!profiling_initialized)
818 {
819 atexit (mcleanup_wrapper);
820 profiling_initialized = 1;
821 }
822
823 /* "main" is now always the first function in the text segment, so use
824 its address for monstartup. */
825 monstartup ((unsigned long) &main, (unsigned long) TEXTEND);
826 }
827 else
828 {
829 extern void _mcleanup (void);
830
831 _mcleanup ();
832 }
833 }
834 #else
835 static void
836 maintenance_set_profile_cmd (const char *args, int from_tty,
837 struct cmd_list_element *c)
838 {
839 error (_("Profiling support is not available on this system."));
840 }
841 #endif
842
843 static int n_worker_threads = -1;
844
845 /* Update the thread pool for the desired number of threads. */
846 static void
847 update_thread_pool_size ()
848 {
849 #if CXX_STD_THREAD
850 int n_threads = n_worker_threads;
851
852 if (n_threads < 0)
853 n_threads = std::thread::hardware_concurrency ();
854
855 gdb::thread_pool::g_thread_pool->set_thread_count (n_threads);
856 #endif
857 }
858
859 static void
860 maintenance_set_worker_threads (const char *args, int from_tty,
861 struct cmd_list_element *c)
862 {
863 update_thread_pool_size ();
864 }
865
866 static void
867 maintenance_show_worker_threads (struct ui_file *file, int from_tty,
868 struct cmd_list_element *c,
869 const char *value)
870 {
871 #if CXX_STD_THREAD
872 if (n_worker_threads == -1)
873 {
874 gdb_printf (file, _("The number of worker threads GDB "
875 "can use is unlimited (currently %zu).\n"),
876 gdb::thread_pool::g_thread_pool->thread_count ());
877 return;
878 }
879 #endif
880
881 int report_threads = 0;
882 #if CXX_STD_THREAD
883 report_threads = n_worker_threads;
884 #endif
885 gdb_printf (file, _("The number of worker threads GDB "
886 "can use is %d.\n"),
887 report_threads);
888 }
889
890 \f
891 /* If true, display time usage both at startup and for each command. */
892
893 static bool per_command_time;
894
895 /* If true, display space usage both at startup and for each command. */
896
897 static bool per_command_space;
898
899 /* If true, display basic symtab stats for each command. */
900
901 static bool per_command_symtab;
902
903 /* mt per-command commands. */
904
905 static struct cmd_list_element *per_command_setlist;
906 static struct cmd_list_element *per_command_showlist;
907
908 /* Set whether to display time statistics to NEW_VALUE
909 (non-zero means true). */
910
911 void
912 set_per_command_time (int new_value)
913 {
914 per_command_time = new_value;
915 }
916
917 /* Set whether to display space statistics to NEW_VALUE
918 (non-zero means true). */
919
920 void
921 set_per_command_space (int new_value)
922 {
923 per_command_space = new_value;
924 }
925
926 /* Count the number of symtabs and blocks. */
927
928 static void
929 count_symtabs_and_blocks (int *nr_symtabs_ptr, int *nr_compunit_symtabs_ptr,
930 int *nr_blocks_ptr)
931 {
932 int nr_symtabs = 0;
933 int nr_compunit_symtabs = 0;
934 int nr_blocks = 0;
935
936 /* When collecting statistics during startup, this is called before
937 pretty much anything in gdb has been initialized, and thus
938 current_program_space may be NULL. */
939 if (current_program_space != NULL)
940 {
941 for (objfile *o : current_program_space->objfiles ())
942 {
943 for (compunit_symtab *cu : o->compunits ())
944 {
945 ++nr_compunit_symtabs;
946 nr_blocks += BLOCKVECTOR_NBLOCKS (cu->blockvector ());
947 nr_symtabs += std::distance (cu->filetabs ().begin (),
948 cu->filetabs ().end ());
949 }
950 }
951 }
952
953 *nr_symtabs_ptr = nr_symtabs;
954 *nr_compunit_symtabs_ptr = nr_compunit_symtabs;
955 *nr_blocks_ptr = nr_blocks;
956 }
957
958 /* As indicated by display_time and display_space, report GDB's
959 elapsed time and space usage from the base time and space recorded
960 in this object. */
961
962 scoped_command_stats::~scoped_command_stats ()
963 {
964 /* Early exit if we're not reporting any stats. It can be expensive to
965 compute the pre-command values so don't collect them at all if we're
966 not reporting stats. Alas this doesn't work in the startup case because
967 we don't know yet whether we will be reporting the stats. For the
968 startup case collect the data anyway (it should be cheap at this point),
969 and leave it to the reporter to decide whether to print them. */
970 if (m_msg_type
971 && !per_command_time
972 && !per_command_space
973 && !per_command_symtab)
974 return;
975
976 if (m_time_enabled && per_command_time)
977 {
978 print_time (_("command finished"));
979
980 using namespace std::chrono;
981
982 run_time_clock::duration cmd_time
983 = run_time_clock::now () - m_start_cpu_time;
984
985 steady_clock::duration wall_time
986 = steady_clock::now () - m_start_wall_time;
987 /* Subtract time spend in prompt_for_continue from walltime. */
988 wall_time -= get_prompt_for_continue_wait_time ();
989
990 gdb_printf (gdb_stdlog,
991 !m_msg_type
992 ? _("Startup time: %.6f (cpu), %.6f (wall)\n")
993 : _("Command execution time: %.6f (cpu), %.6f (wall)\n"),
994 duration<double> (cmd_time).count (),
995 duration<double> (wall_time).count ());
996 }
997
998 if (m_space_enabled && per_command_space)
999 {
1000 #ifdef HAVE_USEFUL_SBRK
1001 char *lim = (char *) sbrk (0);
1002
1003 long space_now = lim - lim_at_start;
1004 long space_diff = space_now - m_start_space;
1005
1006 gdb_printf (gdb_stdlog,
1007 !m_msg_type
1008 ? _("Space used: %ld (%s%ld during startup)\n")
1009 : _("Space used: %ld (%s%ld for this command)\n"),
1010 space_now,
1011 (space_diff >= 0 ? "+" : ""),
1012 space_diff);
1013 #endif
1014 }
1015
1016 if (m_symtab_enabled && per_command_symtab)
1017 {
1018 int nr_symtabs, nr_compunit_symtabs, nr_blocks;
1019
1020 count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
1021 gdb_printf (gdb_stdlog,
1022 _("#symtabs: %d (+%d),"
1023 " #compunits: %d (+%d),"
1024 " #blocks: %d (+%d)\n"),
1025 nr_symtabs,
1026 nr_symtabs - m_start_nr_symtabs,
1027 nr_compunit_symtabs,
1028 (nr_compunit_symtabs
1029 - m_start_nr_compunit_symtabs),
1030 nr_blocks,
1031 nr_blocks - m_start_nr_blocks);
1032 }
1033 }
1034
1035 scoped_command_stats::scoped_command_stats (bool msg_type)
1036 : m_msg_type (msg_type)
1037 {
1038 if (!m_msg_type || per_command_space)
1039 {
1040 #ifdef HAVE_USEFUL_SBRK
1041 char *lim = (char *) sbrk (0);
1042 m_start_space = lim - lim_at_start;
1043 m_space_enabled = 1;
1044 #endif
1045 }
1046 else
1047 m_space_enabled = 0;
1048
1049 if (msg_type == 0 || per_command_time)
1050 {
1051 using namespace std::chrono;
1052
1053 m_start_cpu_time = run_time_clock::now ();
1054 m_start_wall_time = steady_clock::now ();
1055 m_time_enabled = 1;
1056
1057 if (per_command_time)
1058 print_time (_("command started"));
1059 }
1060 else
1061 m_time_enabled = 0;
1062
1063 if (msg_type == 0 || per_command_symtab)
1064 {
1065 int nr_symtabs, nr_compunit_symtabs, nr_blocks;
1066
1067 count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
1068 m_start_nr_symtabs = nr_symtabs;
1069 m_start_nr_compunit_symtabs = nr_compunit_symtabs;
1070 m_start_nr_blocks = nr_blocks;
1071 m_symtab_enabled = 1;
1072 }
1073 else
1074 m_symtab_enabled = 0;
1075
1076 /* Initialize timer to keep track of how long we waited for the user. */
1077 reset_prompt_for_continue_wait_time ();
1078 }
1079
1080 /* See maint.h. */
1081
1082 void
1083 scoped_command_stats::print_time (const char *msg)
1084 {
1085 using namespace std::chrono;
1086
1087 auto now = system_clock::now ();
1088 auto ticks = now.time_since_epoch ().count () / (1000 * 1000);
1089 auto millis = ticks % 1000;
1090
1091 std::time_t as_time = system_clock::to_time_t (now);
1092 struct tm tm;
1093 localtime_r (&as_time, &tm);
1094
1095 char out[100];
1096 strftime (out, sizeof (out), "%F %H:%M:%S", &tm);
1097
1098 gdb_printf (gdb_stdlog, "%s.%03d - %s\n", out, (int) millis, msg);
1099 }
1100
1101 /* Handle unknown "mt set per-command" arguments.
1102 In this case have "mt set per-command on|off" affect every setting. */
1103
1104 static void
1105 set_per_command_cmd (const char *args, int from_tty)
1106 {
1107 struct cmd_list_element *list;
1108 int val;
1109
1110 val = parse_cli_boolean_value (args);
1111 if (val < 0)
1112 error (_("Bad value for 'mt set per-command no'."));
1113
1114 for (list = per_command_setlist; list != NULL; list = list->next)
1115 if (list->var->type () == var_boolean)
1116 {
1117 gdb_assert (list->type == set_cmd);
1118 do_set_command (args, from_tty, list);
1119 }
1120 }
1121
1122 /* Options affecting the "maintenance selftest" command. */
1123
1124 struct maintenance_selftest_options
1125 {
1126 bool verbose = false;
1127 } user_maintenance_selftest_options;
1128
1129 static const gdb::option::option_def maintenance_selftest_option_defs[] = {
1130 gdb::option::boolean_option_def<maintenance_selftest_options> {
1131 "verbose",
1132 [] (maintenance_selftest_options *opt) { return &opt->verbose; },
1133 nullptr,
1134 N_("Set whether selftests run in verbose mode."),
1135 N_("Show whether selftests run in verbose mode."),
1136 N_("\
1137 When on, selftests may print verbose information."),
1138 },
1139 };
1140
1141 /* Make option groups for the "maintenance selftest" command. */
1142
1143 static std::array<gdb::option::option_def_group, 1>
1144 make_maintenance_selftest_option_group (maintenance_selftest_options *opts)
1145 {
1146 return {{
1147 {{maintenance_selftest_option_defs}, opts},
1148 }};
1149 }
1150
1151 /* The "maintenance selftest" command. */
1152
1153 static void
1154 maintenance_selftest (const char *args, int from_tty)
1155 {
1156 #if GDB_SELF_TEST
1157 maintenance_selftest_options opts = user_maintenance_selftest_options;
1158 auto grp = make_maintenance_selftest_option_group (&opts);
1159 gdb::option::process_options
1160 (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp);
1161 const gdb_argv argv (args);
1162 selftests::run_tests (argv.as_array_view (), opts.verbose);
1163 #else
1164 gdb_printf (_("\
1165 Selftests have been disabled for this build.\n"));
1166 #endif
1167 }
1168
1169 /* Completer for the "maintenance selftest" command. */
1170
1171 static void
1172 maintenance_selftest_completer (cmd_list_element *cmd,
1173 completion_tracker &tracker,
1174 const char *text,
1175 const char *word)
1176 {
1177 auto grp = make_maintenance_selftest_option_group (nullptr);
1178
1179 if (gdb::option::complete_options
1180 (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp))
1181 return;
1182
1183 #if GDB_SELF_TEST
1184 selftests::for_each_selftest ([&tracker, text] (const std::string &name)
1185 {
1186 if (startswith (name.c_str (), text))
1187 tracker.add_completion (make_unique_xstrdup (name.c_str ()));
1188 });
1189 #endif
1190 }
1191
1192 static void
1193 maintenance_info_selftests (const char *arg, int from_tty)
1194 {
1195 #if GDB_SELF_TEST
1196 gdb_printf ("Registered selftests:\n");
1197 selftests::for_each_selftest ([] (const std::string &name) {
1198 gdb_printf (" - %s\n", name.c_str ());
1199 });
1200 #else
1201 gdb_printf (_("\
1202 Selftests have been disabled for this build.\n"));
1203 #endif
1204 }
1205
1206 \f
1207 void _initialize_maint_cmds ();
1208 void
1209 _initialize_maint_cmds ()
1210 {
1211 struct cmd_list_element *cmd;
1212
1213 cmd_list_element *maintenance_cmd
1214 = add_basic_prefix_cmd ("maintenance", class_maintenance, _("\
1215 Commands for use by GDB maintainers.\n\
1216 Includes commands to dump specific internal GDB structures in\n\
1217 a human readable form, to cause GDB to deliberately dump core, etc."),
1218 &maintenancelist, 0,
1219 &cmdlist);
1220
1221 add_com_alias ("mt", maintenance_cmd, class_maintenance, 1);
1222
1223 cmd_list_element *maintenance_info_cmd
1224 = add_basic_prefix_cmd ("info", class_maintenance, _("\
1225 Commands for showing internal info about the program being debugged."),
1226 &maintenanceinfolist, 0,
1227 &maintenancelist);
1228 add_alias_cmd ("i", maintenance_info_cmd, class_maintenance, 1,
1229 &maintenancelist);
1230
1231 const auto opts = make_maint_info_sections_options_def_group (nullptr);
1232 static std::string maint_info_sections_command_help
1233 = gdb::option::build_help (_("\
1234 List the BFD sections of the exec and core files.\n\
1235 \n\
1236 Usage: maintenance info sections [-all-objects] [FILTERS]\n\
1237 \n\
1238 FILTERS is a list of words, each word is either:\n\
1239 + A section name - any section with this name will be printed, or\n\
1240 + A section flag - any section with this flag will be printed. The\n\
1241 known flags are:\n\
1242 ALLOC LOAD RELOC READONLY CODE DATA ROM CONSTRUCTOR\n\
1243 HAS_CONTENTS NEVER_LOAD COFF_SHARED_LIBRARY IS_COMMON\n\
1244 \n\
1245 Sections matching any of the FILTERS will be listed (no FILTERS implies\n\
1246 all sections should be printed).\n\
1247 \n\
1248 Options:\n\
1249 %OPTIONS%"), opts);
1250 cmd = add_cmd ("sections", class_maintenance, maintenance_info_sections,
1251 maint_info_sections_command_help.c_str (),
1252 &maintenanceinfolist);
1253 set_cmd_completer_handle_brkchars (cmd, maint_info_sections_completer);
1254
1255 add_cmd ("target-sections", class_maintenance,
1256 maintenance_info_target_sections, _("\
1257 List GDB's internal section table.\n\
1258 \n\
1259 Print the current targets section list. This is a sub-set of all\n\
1260 sections, from all objects currently loaded. Usually the ALLOC\n\
1261 sectoins."),
1262 &maintenanceinfolist);
1263
1264 add_basic_prefix_cmd ("print", class_maintenance,
1265 _("Maintenance command for printing GDB internal state."),
1266 &maintenanceprintlist, 0,
1267 &maintenancelist);
1268
1269 add_basic_prefix_cmd ("flush", class_maintenance,
1270 _("Maintenance command for flushing GDB internal caches."),
1271 &maintenanceflushlist, 0,
1272 &maintenancelist);
1273
1274 add_basic_prefix_cmd ("set", class_maintenance, _("\
1275 Set GDB internal variables used by the GDB maintainer.\n\
1276 Configure variables internal to GDB that aid in GDB's maintenance"),
1277 &maintenance_set_cmdlist,
1278 0/*allow-unknown*/,
1279 &maintenancelist);
1280
1281 add_show_prefix_cmd ("show", class_maintenance, _("\
1282 Show GDB internal variables used by the GDB maintainer.\n\
1283 Configure variables internal to GDB that aid in GDB's maintenance"),
1284 &maintenance_show_cmdlist,
1285 0/*allow-unknown*/,
1286 &maintenancelist);
1287
1288 cmd = add_cmd ("with", class_maintenance, maintenance_with_cmd, _("\
1289 Like \"with\", but works with \"maintenance set\" variables.\n\
1290 Usage: maintenance with SETTING [VALUE] [-- COMMAND]\n\
1291 With no COMMAND, repeats the last executed command.\n\
1292 SETTING is any setting you can change with the \"maintenance set\"\n\
1293 subcommands."),
1294 &maintenancelist);
1295 set_cmd_completer_handle_brkchars (cmd, maintenance_with_cmd_completer);
1296
1297 #ifndef _WIN32
1298 add_cmd ("dump-me", class_maintenance, maintenance_dump_me, _("\
1299 Get fatal error; make debugger dump its core.\n\
1300 GDB sets its handling of SIGQUIT back to SIG_DFL and then sends\n\
1301 itself a SIGQUIT signal."),
1302 &maintenancelist);
1303 #endif
1304
1305 add_cmd ("internal-error", class_maintenance,
1306 maintenance_internal_error, _("\
1307 Give GDB an internal error.\n\
1308 Cause GDB to behave as if an internal error was detected."),
1309 &maintenancelist);
1310
1311 add_cmd ("internal-warning", class_maintenance,
1312 maintenance_internal_warning, _("\
1313 Give GDB an internal warning.\n\
1314 Cause GDB to behave as if an internal warning was reported."),
1315 &maintenancelist);
1316
1317 add_cmd ("demangler-warning", class_maintenance,
1318 maintenance_demangler_warning, _("\
1319 Give GDB a demangler warning.\n\
1320 Cause GDB to behave as if a demangler warning was reported."),
1321 &maintenancelist);
1322
1323 cmd = add_cmd ("demangle", class_maintenance, maintenance_demangle, _("\
1324 This command has been moved to \"demangle\"."),
1325 &maintenancelist);
1326 deprecate_cmd (cmd, "demangle");
1327
1328 add_prefix_cmd ("per-command", class_maintenance, set_per_command_cmd, _("\
1329 Per-command statistics settings."),
1330 &per_command_setlist,
1331 1/*allow-unknown*/, &maintenance_set_cmdlist);
1332
1333 add_show_prefix_cmd ("per-command", class_maintenance, _("\
1334 Show per-command statistics settings."),
1335 &per_command_showlist,
1336 0/*allow-unknown*/, &maintenance_show_cmdlist);
1337
1338 add_setshow_boolean_cmd ("time", class_maintenance,
1339 &per_command_time, _("\
1340 Set whether to display per-command execution time."), _("\
1341 Show whether to display per-command execution time."),
1342 _("\
1343 If enabled, the execution time for each command will be\n\
1344 displayed following the command's output."),
1345 NULL, NULL,
1346 &per_command_setlist, &per_command_showlist);
1347
1348 add_setshow_boolean_cmd ("space", class_maintenance,
1349 &per_command_space, _("\
1350 Set whether to display per-command space usage."), _("\
1351 Show whether to display per-command space usage."),
1352 _("\
1353 If enabled, the space usage for each command will be\n\
1354 displayed following the command's output."),
1355 NULL, NULL,
1356 &per_command_setlist, &per_command_showlist);
1357
1358 add_setshow_boolean_cmd ("symtab", class_maintenance,
1359 &per_command_symtab, _("\
1360 Set whether to display per-command symtab statistics."), _("\
1361 Show whether to display per-command symtab statistics."),
1362 _("\
1363 If enabled, the basic symtab statistics for each command will be\n\
1364 displayed following the command's output."),
1365 NULL, NULL,
1366 &per_command_setlist, &per_command_showlist);
1367
1368 /* This is equivalent to "mt set per-command time on".
1369 Kept because some people are used to typing "mt time 1". */
1370 add_cmd ("time", class_maintenance, maintenance_time_display, _("\
1371 Set the display of time usage.\n\
1372 If nonzero, will cause the execution time for each command to be\n\
1373 displayed, following the command's output."),
1374 &maintenancelist);
1375
1376 /* This is equivalent to "mt set per-command space on".
1377 Kept because some people are used to typing "mt space 1". */
1378 add_cmd ("space", class_maintenance, maintenance_space_display, _("\
1379 Set the display of space usage.\n\
1380 If nonzero, will cause the execution space for each command to be\n\
1381 displayed, following the command's output."),
1382 &maintenancelist);
1383
1384 cmd = add_cmd ("type", class_maintenance, maintenance_print_type, _("\
1385 Print a type chain for a given symbol.\n\
1386 For each node in a type chain, print the raw data for each member of\n\
1387 the type structure, and the interpretation of the data."),
1388 &maintenanceprintlist);
1389 set_cmd_completer (cmd, expression_completer);
1390
1391 add_cmd ("statistics", class_maintenance, maintenance_print_statistics,
1392 _("Print statistics about internal gdb state."),
1393 &maintenanceprintlist);
1394
1395 add_cmd ("architecture", class_maintenance,
1396 maintenance_print_architecture, _("\
1397 Print the internal architecture configuration.\n\
1398 Takes an optional file parameter."),
1399 &maintenanceprintlist);
1400
1401 add_basic_prefix_cmd ("check", class_maintenance, _("\
1402 Commands for checking internal gdb state."),
1403 &maintenancechecklist, 0,
1404 &maintenancelist);
1405
1406 add_cmd ("translate-address", class_maintenance,
1407 maintenance_translate_address,
1408 _("Translate a section name and address to a symbol."),
1409 &maintenancelist);
1410
1411 add_cmd ("deprecate", class_maintenance, maintenance_deprecate, _("\
1412 Deprecate a command (for testing purposes).\n\
1413 Usage: maintenance deprecate COMMANDNAME [\"REPLACEMENT\"]\n\
1414 This is used by the testsuite to check the command deprecator.\n\
1415 You probably shouldn't use this,\n\
1416 rather you should use the C function deprecate_cmd()."), &maintenancelist);
1417
1418 add_cmd ("undeprecate", class_maintenance, maintenance_undeprecate, _("\
1419 Undeprecate a command (for testing purposes).\n\
1420 Usage: maintenance undeprecate COMMANDNAME\n\
1421 This is used by the testsuite to check the command deprecator.\n\
1422 You probably shouldn't use this."),
1423 &maintenancelist);
1424
1425 cmd_list_element *maintenance_selftest_cmd
1426 = add_cmd ("selftest", class_maintenance, maintenance_selftest, _("\
1427 Run gdb's unit tests.\n\
1428 Usage: maintenance selftest [FILTER]\n\
1429 This will run any unit tests that were built in to gdb.\n\
1430 If a filter is given, only the tests with that value in their name will ran."),
1431 &maintenancelist);
1432 set_cmd_completer_handle_brkchars (maintenance_selftest_cmd,
1433 maintenance_selftest_completer);
1434
1435 add_cmd ("selftests", class_maintenance, maintenance_info_selftests,
1436 _("List the registered selftests."), &maintenanceinfolist);
1437
1438 add_setshow_boolean_cmd ("profile", class_maintenance,
1439 &maintenance_profile_p, _("\
1440 Set internal profiling."), _("\
1441 Show internal profiling."), _("\
1442 When enabled GDB is profiled."),
1443 maintenance_set_profile_cmd,
1444 show_maintenance_profile_p,
1445 &maintenance_set_cmdlist,
1446 &maintenance_show_cmdlist);
1447
1448 add_setshow_zuinteger_unlimited_cmd ("worker-threads",
1449 class_maintenance,
1450 &n_worker_threads, _("\
1451 Set the number of worker threads GDB can use."), _("\
1452 Show the number of worker threads GDB can use."), _("\
1453 GDB may use multiple threads to speed up certain CPU-intensive operations,\n\
1454 such as demangling symbol names."),
1455 maintenance_set_worker_threads,
1456 maintenance_show_worker_threads,
1457 &maintenance_set_cmdlist,
1458 &maintenance_show_cmdlist);
1459
1460 /* Add the "maint set/show selftest" commands. */
1461 static cmd_list_element *set_selftest_cmdlist = nullptr;
1462 static cmd_list_element *show_selftest_cmdlist = nullptr;
1463
1464 add_setshow_prefix_cmd ("selftest", class_maintenance,
1465 _("Self tests-related settings."),
1466 _("Self tests-related settings."),
1467 &set_selftest_cmdlist, &show_selftest_cmdlist,
1468 &maintenance_set_cmdlist, &maintenance_show_cmdlist);
1469
1470 /* Add setting commands matching "maintenance selftest" options. */
1471 gdb::option::add_setshow_cmds_for_options (class_maintenance,
1472 &user_maintenance_selftest_options,
1473 maintenance_selftest_option_defs,
1474 &set_selftest_cmdlist,
1475 &show_selftest_cmdlist);
1476
1477 update_thread_pool_size ();
1478 }