]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/maint.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / maint.c
1 /* Support for GDB maintenance commands.
2
3 Copyright (C) 1992-2024 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"
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 ("%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 ("%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_start == nullptr)
335 return nullptr;
336
337 obj_section *osect
338 = &ofile->sections_start[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_start != 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.get (),
456 ofile, arg);
457 else if (opts.all_objects)
458 maint_print_all_sections (_("Object file: "), ofile->obfd.get (),
459 ofile, arg);
460 }
461
462 if (core_bfd)
463 maint_print_all_sections (_("Core file: "), core_bfd, nullptr, arg);
464 }
465
466 /* Implement the "maintenance info target-sections" command. */
467
468 static void
469 maintenance_info_target_sections (const char *arg, int from_tty)
470 {
471 bfd *abfd = nullptr;
472 int digits = 0;
473 const std::vector<target_section> *table
474 = target_get_section_table (current_inferior ()->top_target ());
475 if (table == nullptr)
476 return;
477
478 for (const target_section &sec : *table)
479 {
480 if (abfd == nullptr || sec.the_bfd_section->owner != abfd)
481 {
482 abfd = sec.the_bfd_section->owner;
483 digits = std::max (index_digits (gdb_bfd_count_sections (abfd)),
484 digits);
485 }
486 }
487
488 struct gdbarch *gdbarch = nullptr;
489 int addr_size = 0;
490 abfd = nullptr;
491 for (const target_section &sec : *table)
492 {
493 if (sec.the_bfd_section->owner != abfd)
494 {
495 abfd = sec.the_bfd_section->owner;
496 gdbarch = gdbarch_from_bfd (abfd);
497 addr_size = gdbarch_addr_bit (gdbarch) / 8;
498
499 gdb_printf (_("From '%s', file type %s:\n"),
500 bfd_get_filename (abfd), bfd_get_target (abfd));
501 }
502 print_bfd_section_info (abfd,
503 sec.the_bfd_section,
504 nullptr,
505 digits);
506 /* The magic '8 + digits' here ensures that the 'Start' is aligned
507 with the output of print_bfd_section_info. */
508 gdb_printf ("%*sStart: %s, End: %s, Owner token: %p\n",
509 (8 + digits), "",
510 hex_string_custom (sec.addr, addr_size),
511 hex_string_custom (sec.endaddr, addr_size),
512 sec.owner.v ());
513 }
514 }
515
516 static void
517 maintenance_print_statistics (const char *args, int from_tty)
518 {
519 print_objfile_statistics ();
520 }
521
522 static void
523 maintenance_print_architecture (const char *args, int from_tty)
524 {
525 struct gdbarch *gdbarch = get_current_arch ();
526
527 if (args == NULL)
528 gdbarch_dump (gdbarch, gdb_stdout);
529 else
530 {
531 stdio_file file;
532
533 if (!file.open (args, "w"))
534 perror_with_name (_("maintenance print architecture"));
535 gdbarch_dump (gdbarch, &file);
536 }
537 }
538
539 /* The "maintenance translate-address" command converts a section and address
540 to a symbol. This can be called in two ways:
541 maintenance translate-address <secname> <addr>
542 or maintenance translate-address <addr>. */
543
544 static void
545 maintenance_translate_address (const char *arg, int from_tty)
546 {
547 CORE_ADDR address;
548 struct obj_section *sect;
549 const char *p;
550 struct bound_minimal_symbol sym;
551
552 if (arg == NULL || *arg == 0)
553 error (_("requires argument (address or section + address)"));
554
555 sect = NULL;
556 p = arg;
557
558 if (!isdigit (*p))
559 { /* See if we have a valid section name. */
560 while (*p && !isspace (*p)) /* Find end of section name. */
561 p++;
562 if (*p == '\000') /* End of command? */
563 error (_("Need to specify section name and address"));
564
565 int arg_len = p - arg;
566 p = skip_spaces (p + 1);
567
568 for (objfile *objfile : current_program_space->objfiles ())
569 for (obj_section *iter : objfile->sections ())
570 {
571 if (strncmp (iter->the_bfd_section->name, arg, arg_len) == 0)
572 goto found;
573 }
574
575 error (_("Unknown section %s."), arg);
576 found: ;
577 }
578
579 address = parse_and_eval_address (p);
580
581 if (sect)
582 sym = lookup_minimal_symbol_by_pc_section (address, sect);
583 else
584 sym = lookup_minimal_symbol_by_pc (address);
585
586 if (sym.minsym)
587 {
588 const char *symbol_name = sym.minsym->print_name ();
589 const char *symbol_offset
590 = pulongest (address - sym.value_address ());
591
592 sect = sym.obj_section ();
593 if (sect != NULL)
594 {
595 const char *section_name;
596 const char *obj_name;
597
598 gdb_assert (sect->the_bfd_section && sect->the_bfd_section->name);
599 section_name = sect->the_bfd_section->name;
600
601 gdb_assert (sect->objfile && objfile_name (sect->objfile));
602 obj_name = objfile_name (sect->objfile);
603
604 if (current_program_space->multi_objfile_p ())
605 gdb_printf (_("%s + %s in section %s of %s\n"),
606 symbol_name, symbol_offset,
607 section_name, obj_name);
608 else
609 gdb_printf (_("%s + %s in section %s\n"),
610 symbol_name, symbol_offset, section_name);
611 }
612 else
613 gdb_printf (_("%s + %s\n"), symbol_name, symbol_offset);
614 }
615 else if (sect)
616 gdb_printf (_("no symbol at %s:%s\n"),
617 sect->the_bfd_section->name, hex_string (address));
618 else
619 gdb_printf (_("no symbol at %s\n"), hex_string (address));
620
621 return;
622 }
623
624
625 /* When a command is deprecated the user will be warned the first time
626 the command is used. If possible, a replacement will be
627 offered. */
628
629 static void
630 maintenance_deprecate (const char *args, int from_tty)
631 {
632 if (args == NULL || *args == '\0')
633 {
634 gdb_printf (_("\"maintenance deprecate\" takes an argument,\n\
635 the command you want to deprecate, and optionally the replacement command\n\
636 enclosed in quotes.\n"));
637 }
638
639 maintenance_do_deprecate (args, 1);
640 }
641
642
643 static void
644 maintenance_undeprecate (const char *args, int from_tty)
645 {
646 if (args == NULL || *args == '\0')
647 {
648 gdb_printf (_("\"maintenance undeprecate\" takes an argument, \n\
649 the command you want to undeprecate.\n"));
650 }
651
652 maintenance_do_deprecate (args, 0);
653 }
654
655 /* You really shouldn't be using this. It is just for the testsuite.
656 Rather, you should use deprecate_cmd() when the command is created
657 in _initialize_blah().
658
659 This function deprecates a command and optionally assigns it a
660 replacement. */
661
662 static void
663 maintenance_do_deprecate (const char *text, int deprecate)
664 {
665 struct cmd_list_element *alias = NULL;
666 struct cmd_list_element *prefix_cmd = NULL;
667 struct cmd_list_element *cmd = NULL;
668
669 const char *start_ptr = NULL;
670 const char *end_ptr = NULL;
671 int len;
672 char *replacement = NULL;
673
674 if (text == NULL)
675 return;
676
677 if (!lookup_cmd_composition (text, &alias, &prefix_cmd, &cmd))
678 {
679 gdb_printf (_("Can't find command '%s' to deprecate.\n"), text);
680 return;
681 }
682
683 if (deprecate)
684 {
685 /* Look for a replacement command. */
686 start_ptr = strchr (text, '\"');
687 if (start_ptr != NULL)
688 {
689 start_ptr++;
690 end_ptr = strrchr (start_ptr, '\"');
691 if (end_ptr != NULL)
692 {
693 len = end_ptr - start_ptr;
694 replacement = savestring (start_ptr, len);
695 }
696 }
697 }
698
699 if (!start_ptr || !end_ptr)
700 replacement = NULL;
701
702
703 /* If they used an alias, we only want to deprecate the alias.
704
705 Note the MALLOCED_REPLACEMENT test. If the command's replacement
706 string was allocated at compile time we don't want to free the
707 memory. */
708 if (alias)
709 {
710 if (alias->malloced_replacement)
711 xfree ((char *) alias->replacement);
712
713 if (deprecate)
714 {
715 alias->deprecated_warn_user = 1;
716 alias->cmd_deprecated = 1;
717 }
718 else
719 {
720 alias->deprecated_warn_user = 0;
721 alias->cmd_deprecated = 0;
722 }
723 alias->replacement = replacement;
724 alias->malloced_replacement = 1;
725 return;
726 }
727 else if (cmd)
728 {
729 if (cmd->malloced_replacement)
730 xfree ((char *) cmd->replacement);
731
732 if (deprecate)
733 {
734 cmd->deprecated_warn_user = 1;
735 cmd->cmd_deprecated = 1;
736 }
737 else
738 {
739 cmd->deprecated_warn_user = 0;
740 cmd->cmd_deprecated = 0;
741 }
742 cmd->replacement = replacement;
743 cmd->malloced_replacement = 1;
744 return;
745 }
746 xfree (replacement);
747 }
748
749 /* Maintenance set/show framework. */
750
751 struct cmd_list_element *maintenance_set_cmdlist;
752 struct cmd_list_element *maintenance_show_cmdlist;
753
754 /* "maintenance with" command. */
755
756 static void
757 maintenance_with_cmd (const char *args, int from_tty)
758 {
759 with_command_1 ("maintenance set ", maintenance_set_cmdlist, args, from_tty);
760 }
761
762 /* "maintenance with" command completer. */
763
764 static void
765 maintenance_with_cmd_completer (struct cmd_list_element *ignore,
766 completion_tracker &tracker,
767 const char *text, const char * /*word*/)
768 {
769 with_command_completer_1 ("maintenance set ", tracker, text);
770 }
771
772 /* Profiling support. */
773
774 static bool maintenance_profile_p;
775 static void
776 show_maintenance_profile_p (struct ui_file *file, int from_tty,
777 struct cmd_list_element *c, const char *value)
778 {
779 gdb_printf (file, _("Internal profiling is %s.\n"), value);
780 }
781
782 #ifdef HAVE__ETEXT
783 extern char _etext;
784 #define TEXTEND &_etext
785 #elif defined (HAVE_ETEXT)
786 extern char etext;
787 #define TEXTEND &etext
788 #endif
789
790 #if defined (HAVE_MONSTARTUP) && defined (HAVE__MCLEANUP) && defined (TEXTEND)
791
792 static int profiling_state;
793
794 extern "C" void _mcleanup (void);
795
796 static void
797 mcleanup_wrapper (void)
798 {
799 if (profiling_state)
800 _mcleanup ();
801 }
802
803 extern "C" void monstartup (unsigned long, unsigned long);
804 extern int main (int, char **);
805
806 static void
807 maintenance_set_profile_cmd (const char *args, int from_tty,
808 struct cmd_list_element *c)
809 {
810 if (maintenance_profile_p == profiling_state)
811 return;
812
813 profiling_state = maintenance_profile_p;
814
815 if (maintenance_profile_p)
816 {
817 static int profiling_initialized;
818
819 if (!profiling_initialized)
820 {
821 atexit (mcleanup_wrapper);
822 profiling_initialized = 1;
823 }
824
825 /* "main" is now always the first function in the text segment, so use
826 its address for monstartup. */
827 monstartup ((unsigned long) &main, (unsigned long) TEXTEND);
828 }
829 else
830 {
831 extern void _mcleanup (void);
832
833 _mcleanup ();
834 }
835 }
836 #else
837 static void
838 maintenance_set_profile_cmd (const char *args, int from_tty,
839 struct cmd_list_element *c)
840 {
841 error (_("Profiling support is not available on this system."));
842 }
843 #endif
844
845 static int n_worker_threads = -1;
846
847 /* See maint.h. */
848
849 void
850 update_thread_pool_size ()
851 {
852 #if CXX_STD_THREAD
853 int n_threads = n_worker_threads;
854
855 if (n_threads < 0)
856 {
857 const int hardware_threads = std::thread::hardware_concurrency ();
858 /* Testing in PR gdb/29959 indicates that parallel efficiency drops
859 between n_threads=5 to 8. Therefore, use no more than 8 threads
860 to avoid an excessive number of threads in the pool on many-core
861 systems. */
862 const int max_thread_count = 8;
863 n_threads = std::min (hardware_threads, max_thread_count);
864 }
865
866 gdb::thread_pool::g_thread_pool->set_thread_count (n_threads);
867 #endif
868 }
869
870 static void
871 maintenance_set_worker_threads (const char *args, int from_tty,
872 struct cmd_list_element *c)
873 {
874 update_thread_pool_size ();
875 }
876
877 static void
878 maintenance_show_worker_threads (struct ui_file *file, int from_tty,
879 struct cmd_list_element *c,
880 const char *value)
881 {
882 #if CXX_STD_THREAD
883 if (n_worker_threads == -1)
884 {
885 gdb_printf (file, _("The number of worker threads GDB "
886 "can use is the default (currently %zu).\n"),
887 gdb::thread_pool::g_thread_pool->thread_count ());
888 return;
889 }
890 #endif
891
892 int report_threads = 0;
893 #if CXX_STD_THREAD
894 report_threads = n_worker_threads;
895 #endif
896 gdb_printf (file, _("The number of worker threads GDB "
897 "can use is %d.\n"),
898 report_threads);
899 }
900
901 \f
902 /* If true, display time usage both at startup and for each command. */
903
904 static bool per_command_time;
905
906 /* If true, display space usage both at startup and for each command. */
907
908 static bool per_command_space;
909
910 /* If true, display basic symtab stats for each command. */
911
912 static bool per_command_symtab;
913
914 /* mt per-command commands. */
915
916 static struct cmd_list_element *per_command_setlist;
917 static struct cmd_list_element *per_command_showlist;
918
919 /* Set whether to display time statistics to NEW_VALUE
920 (non-zero means true). */
921
922 void
923 set_per_command_time (int new_value)
924 {
925 per_command_time = new_value;
926 }
927
928 /* Set whether to display space statistics to NEW_VALUE
929 (non-zero means true). */
930
931 void
932 set_per_command_space (int new_value)
933 {
934 per_command_space = new_value;
935 }
936
937 /* Count the number of symtabs and blocks. */
938
939 static void
940 count_symtabs_and_blocks (int *nr_symtabs_ptr, int *nr_compunit_symtabs_ptr,
941 int *nr_blocks_ptr)
942 {
943 int nr_symtabs = 0;
944 int nr_compunit_symtabs = 0;
945 int nr_blocks = 0;
946
947 /* When collecting statistics during startup, this is called before
948 pretty much anything in gdb has been initialized, and thus
949 current_program_space may be NULL. */
950 if (current_program_space != NULL)
951 {
952 for (objfile *o : current_program_space->objfiles ())
953 {
954 for (compunit_symtab *cu : o->compunits ())
955 {
956 ++nr_compunit_symtabs;
957 nr_blocks += cu->blockvector ()->num_blocks ();
958 nr_symtabs += std::distance (cu->filetabs ().begin (),
959 cu->filetabs ().end ());
960 }
961 }
962 }
963
964 *nr_symtabs_ptr = nr_symtabs;
965 *nr_compunit_symtabs_ptr = nr_compunit_symtabs;
966 *nr_blocks_ptr = nr_blocks;
967 }
968
969 /* As indicated by display_time and display_space, report GDB's
970 elapsed time and space usage from the base time and space recorded
971 in this object. */
972
973 scoped_command_stats::~scoped_command_stats ()
974 {
975 /* Early exit if we're not reporting any stats. It can be expensive to
976 compute the pre-command values so don't collect them at all if we're
977 not reporting stats. Alas this doesn't work in the startup case because
978 we don't know yet whether we will be reporting the stats. For the
979 startup case collect the data anyway (it should be cheap at this point),
980 and leave it to the reporter to decide whether to print them. */
981 if (m_msg_type
982 && !per_command_time
983 && !per_command_space
984 && !per_command_symtab)
985 return;
986
987 if (m_time_enabled && per_command_time)
988 {
989 print_time (_("command finished"));
990
991 using namespace std::chrono;
992
993 run_time_clock::duration cmd_time
994 = run_time_clock::now () - m_start_cpu_time;
995
996 steady_clock::duration wall_time
997 = steady_clock::now () - m_start_wall_time;
998 /* Subtract time spend in prompt_for_continue from walltime. */
999 wall_time -= get_prompt_for_continue_wait_time ();
1000
1001 gdb_printf (gdb_stdlog,
1002 !m_msg_type
1003 ? _("Startup time: %.6f (cpu), %.6f (wall)\n")
1004 : _("Command execution time: %.6f (cpu), %.6f (wall)\n"),
1005 duration<double> (cmd_time).count (),
1006 duration<double> (wall_time).count ());
1007 }
1008
1009 if (m_space_enabled && per_command_space)
1010 {
1011 #ifdef HAVE_USEFUL_SBRK
1012 char *lim = (char *) sbrk (0);
1013
1014 long space_now = lim - lim_at_start;
1015 long space_diff = space_now - m_start_space;
1016
1017 gdb_printf (gdb_stdlog,
1018 !m_msg_type
1019 ? _("Space used: %ld (%s%ld during startup)\n")
1020 : _("Space used: %ld (%s%ld for this command)\n"),
1021 space_now,
1022 (space_diff >= 0 ? "+" : ""),
1023 space_diff);
1024 #endif
1025 }
1026
1027 if (m_symtab_enabled && per_command_symtab)
1028 {
1029 int nr_symtabs, nr_compunit_symtabs, nr_blocks;
1030
1031 count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
1032 gdb_printf (gdb_stdlog,
1033 _("#symtabs: %d (+%d),"
1034 " #compunits: %d (+%d),"
1035 " #blocks: %d (+%d)\n"),
1036 nr_symtabs,
1037 nr_symtabs - m_start_nr_symtabs,
1038 nr_compunit_symtabs,
1039 (nr_compunit_symtabs
1040 - m_start_nr_compunit_symtabs),
1041 nr_blocks,
1042 nr_blocks - m_start_nr_blocks);
1043 }
1044 }
1045
1046 scoped_command_stats::scoped_command_stats (bool msg_type)
1047 : m_msg_type (msg_type)
1048 {
1049 if (!m_msg_type || per_command_space)
1050 {
1051 #ifdef HAVE_USEFUL_SBRK
1052 char *lim = (char *) sbrk (0);
1053 m_start_space = lim - lim_at_start;
1054 m_space_enabled = true;
1055 #endif
1056 }
1057 else
1058 m_space_enabled = false;
1059
1060 if (msg_type == 0 || per_command_time)
1061 {
1062 using namespace std::chrono;
1063
1064 m_start_cpu_time = run_time_clock::now ();
1065 m_start_wall_time = steady_clock::now ();
1066 m_time_enabled = true;
1067
1068 if (per_command_time)
1069 print_time (_("command started"));
1070 }
1071 else
1072 m_time_enabled = false;
1073
1074 if (msg_type == 0 || per_command_symtab)
1075 {
1076 int nr_symtabs, nr_compunit_symtabs, nr_blocks;
1077
1078 count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
1079 m_start_nr_symtabs = nr_symtabs;
1080 m_start_nr_compunit_symtabs = nr_compunit_symtabs;
1081 m_start_nr_blocks = nr_blocks;
1082 m_symtab_enabled = true;
1083 }
1084 else
1085 m_symtab_enabled = false;
1086
1087 /* Initialize timer to keep track of how long we waited for the user. */
1088 reset_prompt_for_continue_wait_time ();
1089 }
1090
1091 /* See maint.h. */
1092
1093 void
1094 scoped_command_stats::print_time (const char *msg)
1095 {
1096 using namespace std::chrono;
1097
1098 auto now = system_clock::now ();
1099 auto ticks = now.time_since_epoch ().count () / (1000 * 1000);
1100 auto millis = ticks % 1000;
1101
1102 std::time_t as_time = system_clock::to_time_t (now);
1103 struct tm tm;
1104 localtime_r (&as_time, &tm);
1105
1106 char out[100];
1107 strftime (out, sizeof (out), "%F %H:%M:%S", &tm);
1108
1109 gdb_printf (gdb_stdlog, "%s.%03d - %s\n", out, (int) millis, msg);
1110 }
1111
1112 /* Handle unknown "mt set per-command" arguments.
1113 In this case have "mt set per-command on|off" affect every setting. */
1114
1115 static void
1116 set_per_command_cmd (const char *args, int from_tty)
1117 {
1118 struct cmd_list_element *list;
1119 int val;
1120
1121 val = parse_cli_boolean_value (args);
1122 if (val < 0)
1123 error (_("Bad value for 'mt set per-command no'."));
1124
1125 for (list = per_command_setlist; list != NULL; list = list->next)
1126 if (list->var->type () == var_boolean)
1127 {
1128 gdb_assert (list->type == set_cmd);
1129 do_set_command (args, from_tty, list);
1130 }
1131 }
1132
1133 /* Options affecting the "maintenance selftest" command. */
1134
1135 struct maintenance_selftest_options
1136 {
1137 bool verbose = false;
1138 } user_maintenance_selftest_options;
1139
1140 static const gdb::option::option_def maintenance_selftest_option_defs[] = {
1141 gdb::option::boolean_option_def<maintenance_selftest_options> {
1142 "verbose",
1143 [] (maintenance_selftest_options *opt) { return &opt->verbose; },
1144 nullptr,
1145 N_("Set whether selftests run in verbose mode."),
1146 N_("Show whether selftests run in verbose mode."),
1147 N_("\
1148 When on, selftests may print verbose information."),
1149 },
1150 };
1151
1152 /* Make option groups for the "maintenance selftest" command. */
1153
1154 static std::array<gdb::option::option_def_group, 1>
1155 make_maintenance_selftest_option_group (maintenance_selftest_options *opts)
1156 {
1157 return {{
1158 {{maintenance_selftest_option_defs}, opts},
1159 }};
1160 }
1161
1162 /* The "maintenance selftest" command. */
1163
1164 static void
1165 maintenance_selftest (const char *args, int from_tty)
1166 {
1167 #if GDB_SELF_TEST
1168 maintenance_selftest_options opts = user_maintenance_selftest_options;
1169 auto grp = make_maintenance_selftest_option_group (&opts);
1170 gdb::option::process_options
1171 (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp);
1172 const gdb_argv argv (args);
1173 selftests::run_tests (argv.as_array_view (), opts.verbose);
1174 #else
1175 gdb_printf (_("\
1176 Selftests have been disabled for this build.\n"));
1177 #endif
1178 }
1179
1180 /* Completer for the "maintenance selftest" command. */
1181
1182 static void
1183 maintenance_selftest_completer (cmd_list_element *cmd,
1184 completion_tracker &tracker,
1185 const char *text,
1186 const char *word)
1187 {
1188 auto grp = make_maintenance_selftest_option_group (nullptr);
1189
1190 if (gdb::option::complete_options
1191 (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp))
1192 return;
1193
1194 #if GDB_SELF_TEST
1195 for (const auto &test : selftests::all_selftests ())
1196 {
1197 if (startswith (test.name.c_str (), text))
1198 tracker.add_completion (make_unique_xstrdup (test.name.c_str ()));
1199 }
1200 #endif
1201 }
1202
1203 static void
1204 maintenance_info_selftests (const char *arg, int from_tty)
1205 {
1206 #if GDB_SELF_TEST
1207 gdb_printf ("Registered selftests:\n");
1208 for (const auto &test : selftests::all_selftests ())
1209 gdb_printf (" - %s\n", test.name.c_str ());
1210 #else
1211 gdb_printf (_("\
1212 Selftests have been disabled for this build.\n"));
1213 #endif
1214 }
1215
1216 \f
1217 void _initialize_maint_cmds ();
1218 void
1219 _initialize_maint_cmds ()
1220 {
1221 struct cmd_list_element *cmd;
1222
1223 cmd_list_element *maintenance_cmd
1224 = add_basic_prefix_cmd ("maintenance", class_maintenance, _("\
1225 Commands for use by GDB maintainers.\n\
1226 Includes commands to dump specific internal GDB structures in\n\
1227 a human readable form, to cause GDB to deliberately dump core, etc."),
1228 &maintenancelist, 0,
1229 &cmdlist);
1230
1231 add_com_alias ("mt", maintenance_cmd, class_maintenance, 1);
1232
1233 cmd_list_element *maintenance_info_cmd
1234 = add_basic_prefix_cmd ("info", class_maintenance, _("\
1235 Commands for showing internal info about the program being debugged."),
1236 &maintenanceinfolist, 0,
1237 &maintenancelist);
1238 add_alias_cmd ("i", maintenance_info_cmd, class_maintenance, 1,
1239 &maintenancelist);
1240
1241 const auto opts = make_maint_info_sections_options_def_group (nullptr);
1242 static std::string maint_info_sections_command_help
1243 = gdb::option::build_help (_("\
1244 List the BFD sections of the exec and core files.\n\
1245 \n\
1246 Usage: maintenance info sections [-all-objects] [FILTERS]\n\
1247 \n\
1248 FILTERS is a list of words, each word is either:\n\
1249 + A section name - any section with this name will be printed, or\n\
1250 + A section flag - any section with this flag will be printed. The\n\
1251 known flags are:\n\
1252 ALLOC LOAD RELOC READONLY CODE DATA ROM CONSTRUCTOR\n\
1253 HAS_CONTENTS NEVER_LOAD COFF_SHARED_LIBRARY IS_COMMON\n\
1254 \n\
1255 Sections matching any of the FILTERS will be listed (no FILTERS implies\n\
1256 all sections should be printed).\n\
1257 \n\
1258 Options:\n\
1259 %OPTIONS%"), opts);
1260 cmd = add_cmd ("sections", class_maintenance, maintenance_info_sections,
1261 maint_info_sections_command_help.c_str (),
1262 &maintenanceinfolist);
1263 set_cmd_completer_handle_brkchars (cmd, maint_info_sections_completer);
1264
1265 add_cmd ("target-sections", class_maintenance,
1266 maintenance_info_target_sections, _("\
1267 List GDB's internal section table.\n\
1268 \n\
1269 Print the current targets section list. This is a sub-set of all\n\
1270 sections, from all objects currently loaded. Usually the ALLOC\n\
1271 sections."),
1272 &maintenanceinfolist);
1273
1274 add_basic_prefix_cmd ("print", class_maintenance,
1275 _("Maintenance command for printing GDB internal state."),
1276 &maintenanceprintlist, 0,
1277 &maintenancelist);
1278
1279 add_basic_prefix_cmd ("flush", class_maintenance,
1280 _("Maintenance command for flushing GDB internal caches."),
1281 &maintenanceflushlist, 0,
1282 &maintenancelist);
1283
1284 add_basic_prefix_cmd ("set", class_maintenance, _("\
1285 Set GDB internal variables used by the GDB maintainer.\n\
1286 Configure variables internal to GDB that aid in GDB's maintenance"),
1287 &maintenance_set_cmdlist,
1288 0/*allow-unknown*/,
1289 &maintenancelist);
1290
1291 add_show_prefix_cmd ("show", class_maintenance, _("\
1292 Show GDB internal variables used by the GDB maintainer.\n\
1293 Configure variables internal to GDB that aid in GDB's maintenance"),
1294 &maintenance_show_cmdlist,
1295 0/*allow-unknown*/,
1296 &maintenancelist);
1297
1298 cmd = add_cmd ("with", class_maintenance, maintenance_with_cmd, _("\
1299 Like \"with\", but works with \"maintenance set\" variables.\n\
1300 Usage: maintenance with SETTING [VALUE] [-- COMMAND]\n\
1301 With no COMMAND, repeats the last executed command.\n\
1302 SETTING is any setting you can change with the \"maintenance set\"\n\
1303 subcommands."),
1304 &maintenancelist);
1305 set_cmd_completer_handle_brkchars (cmd, maintenance_with_cmd_completer);
1306
1307 #ifndef _WIN32
1308 add_cmd ("dump-me", class_maintenance, maintenance_dump_me, _("\
1309 Get fatal error; make debugger dump its core.\n\
1310 GDB sets its handling of SIGQUIT back to SIG_DFL and then sends\n\
1311 itself a SIGQUIT signal."),
1312 &maintenancelist);
1313 #endif
1314
1315 add_cmd ("internal-error", class_maintenance,
1316 maintenance_internal_error, _("\
1317 Give GDB an internal error.\n\
1318 Cause GDB to behave as if an internal error was detected."),
1319 &maintenancelist);
1320
1321 add_cmd ("internal-warning", class_maintenance,
1322 maintenance_internal_warning, _("\
1323 Give GDB an internal warning.\n\
1324 Cause GDB to behave as if an internal warning was reported."),
1325 &maintenancelist);
1326
1327 add_cmd ("demangler-warning", class_maintenance,
1328 maintenance_demangler_warning, _("\
1329 Give GDB a demangler warning.\n\
1330 Cause GDB to behave as if a demangler warning was reported."),
1331 &maintenancelist);
1332
1333 cmd = add_cmd ("demangle", class_maintenance, maintenance_demangle, _("\
1334 This command has been moved to \"demangle\"."),
1335 &maintenancelist);
1336 deprecate_cmd (cmd, "demangle");
1337
1338 add_prefix_cmd ("per-command", class_maintenance, set_per_command_cmd, _("\
1339 Per-command statistics settings."),
1340 &per_command_setlist,
1341 1/*allow-unknown*/, &maintenance_set_cmdlist);
1342
1343 add_show_prefix_cmd ("per-command", class_maintenance, _("\
1344 Show per-command statistics settings."),
1345 &per_command_showlist,
1346 0/*allow-unknown*/, &maintenance_show_cmdlist);
1347
1348 add_setshow_boolean_cmd ("time", class_maintenance,
1349 &per_command_time, _("\
1350 Set whether to display per-command execution time."), _("\
1351 Show whether to display per-command execution time."),
1352 _("\
1353 If enabled, the execution time 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 ("space", class_maintenance,
1359 &per_command_space, _("\
1360 Set whether to display per-command space usage."), _("\
1361 Show whether to display per-command space usage."),
1362 _("\
1363 If enabled, the space usage 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 add_setshow_boolean_cmd ("symtab", class_maintenance,
1369 &per_command_symtab, _("\
1370 Set whether to display per-command symtab statistics."), _("\
1371 Show whether to display per-command symtab statistics."),
1372 _("\
1373 If enabled, the basic symtab statistics for each command will be\n\
1374 displayed following the command's output."),
1375 NULL, NULL,
1376 &per_command_setlist, &per_command_showlist);
1377
1378 /* This is equivalent to "mt set per-command time on".
1379 Kept because some people are used to typing "mt time 1". */
1380 add_cmd ("time", class_maintenance, maintenance_time_display, _("\
1381 Set the display of time usage.\n\
1382 If nonzero, will cause the execution time for each command to be\n\
1383 displayed, following the command's output."),
1384 &maintenancelist);
1385
1386 /* This is equivalent to "mt set per-command space on".
1387 Kept because some people are used to typing "mt space 1". */
1388 add_cmd ("space", class_maintenance, maintenance_space_display, _("\
1389 Set the display of space usage.\n\
1390 If nonzero, will cause the execution space for each command to be\n\
1391 displayed, following the command's output."),
1392 &maintenancelist);
1393
1394 cmd = add_cmd ("type", class_maintenance, maintenance_print_type, _("\
1395 Print a type chain for a given symbol.\n\
1396 For each node in a type chain, print the raw data for each member of\n\
1397 the type structure, and the interpretation of the data."),
1398 &maintenanceprintlist);
1399 set_cmd_completer (cmd, expression_completer);
1400
1401 add_cmd ("statistics", class_maintenance, maintenance_print_statistics,
1402 _("Print statistics about internal gdb state."),
1403 &maintenanceprintlist);
1404
1405 add_cmd ("architecture", class_maintenance,
1406 maintenance_print_architecture, _("\
1407 Print the internal architecture configuration.\n\
1408 Takes an optional file parameter."),
1409 &maintenanceprintlist);
1410
1411 add_basic_prefix_cmd ("check", class_maintenance, _("\
1412 Commands for checking internal gdb state."),
1413 &maintenancechecklist, 0,
1414 &maintenancelist);
1415
1416 add_cmd ("translate-address", class_maintenance,
1417 maintenance_translate_address,
1418 _("Translate a section name and address to a symbol."),
1419 &maintenancelist);
1420
1421 add_cmd ("deprecate", class_maintenance, maintenance_deprecate, _("\
1422 Deprecate a command (for testing purposes).\n\
1423 Usage: maintenance deprecate COMMANDNAME [\"REPLACEMENT\"]\n\
1424 This is used by the testsuite to check the command deprecator.\n\
1425 You probably shouldn't use this,\n\
1426 rather you should use the C function deprecate_cmd()."), &maintenancelist);
1427
1428 add_cmd ("undeprecate", class_maintenance, maintenance_undeprecate, _("\
1429 Undeprecate a command (for testing purposes).\n\
1430 Usage: maintenance undeprecate COMMANDNAME\n\
1431 This is used by the testsuite to check the command deprecator.\n\
1432 You probably shouldn't use this."),
1433 &maintenancelist);
1434
1435 cmd_list_element *maintenance_selftest_cmd
1436 = add_cmd ("selftest", class_maintenance, maintenance_selftest, _("\
1437 Run gdb's unit tests.\n\
1438 Usage: maintenance selftest [FILTER]\n\
1439 This will run any unit tests that were built in to gdb.\n\
1440 If a filter is given, only the tests with that value in their name will ran."),
1441 &maintenancelist);
1442 set_cmd_completer_handle_brkchars (maintenance_selftest_cmd,
1443 maintenance_selftest_completer);
1444
1445 add_cmd ("selftests", class_maintenance, maintenance_info_selftests,
1446 _("List the registered selftests."), &maintenanceinfolist);
1447
1448 add_setshow_boolean_cmd ("profile", class_maintenance,
1449 &maintenance_profile_p, _("\
1450 Set internal profiling."), _("\
1451 Show internal profiling."), _("\
1452 When enabled GDB is profiled."),
1453 maintenance_set_profile_cmd,
1454 show_maintenance_profile_p,
1455 &maintenance_set_cmdlist,
1456 &maintenance_show_cmdlist);
1457
1458 add_setshow_zuinteger_unlimited_cmd ("worker-threads",
1459 class_maintenance,
1460 &n_worker_threads, _("\
1461 Set the number of worker threads GDB can use."), _("\
1462 Show the number of worker threads GDB can use."), _("\
1463 GDB may use multiple threads to speed up certain CPU-intensive operations,\n\
1464 such as demangling symbol names."),
1465 maintenance_set_worker_threads,
1466 maintenance_show_worker_threads,
1467 &maintenance_set_cmdlist,
1468 &maintenance_show_cmdlist);
1469
1470 /* Add the "maint set/show selftest" commands. */
1471 static cmd_list_element *set_selftest_cmdlist = nullptr;
1472 static cmd_list_element *show_selftest_cmdlist = nullptr;
1473
1474 add_setshow_prefix_cmd ("selftest", class_maintenance,
1475 _("Self tests-related settings."),
1476 _("Self tests-related settings."),
1477 &set_selftest_cmdlist, &show_selftest_cmdlist,
1478 &maintenance_set_cmdlist, &maintenance_show_cmdlist);
1479
1480 /* Add setting commands matching "maintenance selftest" options. */
1481 gdb::option::add_setshow_cmds_for_options (class_maintenance,
1482 &user_maintenance_selftest_options,
1483 maintenance_selftest_option_defs,
1484 &set_selftest_cmdlist,
1485 &show_selftest_cmdlist);
1486 }