RISC-V: update docs for -mpriv-spec/--with-priv-spec for 1.12
[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
45 #include "cli/cli-decode.h"
46 #include "cli/cli-utils.h"
47 #include "cli/cli-setshow.h"
48 #include "cli/cli-cmds.h"
49
50 #if CXX_STD_THREAD
51 #include "gdbsupport/thread-pool.h"
52 #endif
53
54 static void maintenance_do_deprecate (const char *, int);
55
56 #ifndef _WIN32
57 static void
58 maintenance_dump_me (const char *args, int from_tty)
59 {
60 if (query (_("Should GDB dump core? ")))
61 {
62 #ifdef __DJGPP__
63 /* SIGQUIT by default is ignored, so use SIGABRT instead. */
64 signal (SIGABRT, SIG_DFL);
65 kill (getpid (), SIGABRT);
66 #else
67 signal (SIGQUIT, SIG_DFL);
68 kill (getpid (), SIGQUIT);
69 #endif
70 }
71 }
72 #endif
73
74 /* Stimulate the internal error mechanism that GDB uses when an
75 internal problem is detected. Allows testing of the mechanism.
76 Also useful when the user wants to drop a core file but not exit
77 GDB. */
78
79 static void
80 maintenance_internal_error (const char *args, int from_tty)
81 {
82 internal_error (__FILE__, __LINE__, "%s", (args == NULL ? "" : args));
83 }
84
85 /* Stimulate the internal error mechanism that GDB uses when an
86 internal problem is detected. Allows testing of the mechanism.
87 Also useful when the user wants to drop a core file but not exit
88 GDB. */
89
90 static void
91 maintenance_internal_warning (const char *args, int from_tty)
92 {
93 internal_warning (__FILE__, __LINE__, "%s", (args == NULL ? "" : args));
94 }
95
96 /* Stimulate the internal error mechanism that GDB uses when an
97 demangler problem is detected. Allows testing of the mechanism. */
98
99 static void
100 maintenance_demangler_warning (const char *args, int from_tty)
101 {
102 demangler_warning (__FILE__, __LINE__, "%s", (args == NULL ? "" : args));
103 }
104
105 /* Old command to demangle a string. The command has been moved to "demangle".
106 It is kept for now because otherwise "mt demangle" gets interpreted as
107 "mt demangler-warning" which artificially creates an internal gdb error. */
108
109 static void
110 maintenance_demangle (const char *args, int from_tty)
111 {
112 printf_filtered (_("This command has been moved to \"demangle\".\n"));
113 }
114
115 static void
116 maintenance_time_display (const char *args, int from_tty)
117 {
118 if (args == NULL || *args == '\0')
119 printf_filtered (_("\"maintenance time\" takes a numeric argument.\n"));
120 else
121 set_per_command_time (strtol (args, NULL, 10));
122 }
123
124 static void
125 maintenance_space_display (const char *args, int from_tty)
126 {
127 if (args == NULL || *args == '\0')
128 printf_filtered ("\"maintenance space\" takes a numeric argument.\n");
129 else
130 set_per_command_space (strtol (args, NULL, 10));
131 }
132
133 /* Mini tokenizing lexer for 'maint info sections' command. */
134
135 static bool
136 match_substring (const char *string, const char *substr)
137 {
138 int substr_len = strlen (substr);
139 const char *tok;
140
141 while ((tok = strstr (string, substr)) != NULL)
142 {
143 /* Got a partial match. Is it a whole word? */
144 if (tok == string
145 || tok[-1] == ' '
146 || tok[-1] == '\t')
147 {
148 /* Token is delimited at the front... */
149 if (tok[substr_len] == ' '
150 || tok[substr_len] == '\t'
151 || tok[substr_len] == '\0')
152 {
153 /* Token is delimited at the rear. Got a whole-word match. */
154 return true;
155 }
156 }
157 /* Token didn't match as a whole word. Advance and try again. */
158 string = tok + 1;
159 }
160 return false;
161 }
162
163 /* Structure holding information about a single bfd section flag. This is
164 used by the "maintenance info sections" command to print the sections,
165 and for filtering which sections are printed. */
166
167 struct single_bfd_flag_info
168 {
169 /* The name of the section. This is what is printed for the flag, and
170 what the user enter in order to filter by flag. */
171 const char *name;
172
173 /* The bfd defined SEC_* flagword value for this flag. */
174 flagword value;
175 };
176
177 /* Vector of all the known bfd flags. */
178
179 static const single_bfd_flag_info bfd_flag_info[] =
180 {
181 { "ALLOC", SEC_ALLOC },
182 { "LOAD", SEC_LOAD },
183 { "RELOC", SEC_RELOC },
184 { "READONLY", SEC_READONLY },
185 { "CODE", SEC_CODE },
186 { "DATA", SEC_DATA },
187 { "ROM", SEC_ROM },
188 { "CONSTRUCTOR", SEC_CONSTRUCTOR },
189 { "HAS_CONTENTS", SEC_HAS_CONTENTS },
190 { "NEVER_LOAD", SEC_NEVER_LOAD },
191 { "COFF_SHARED_LIBRARY", SEC_COFF_SHARED_LIBRARY },
192 { "IS_COMMON", SEC_IS_COMMON }
193 };
194
195 /* For each flag in the global BFD_FLAG_INFO list, if FLAGS has a flag's
196 flagword value set, and STRING contains the flag's name then return
197 true, otherwise return false. STRING is never nullptr. */
198
199 static bool
200 match_bfd_flags (const char *string, flagword flags)
201 {
202 gdb_assert (string != nullptr);
203
204 for (const auto &f : bfd_flag_info)
205 {
206 if (flags & f.value
207 && match_substring (string, f.name))
208 return true;
209 }
210
211 return false;
212 }
213
214 /* Print the names of all flags set in FLAGS. The names are taken from the
215 BFD_FLAG_INFO global. */
216
217 static void
218 print_bfd_flags (flagword flags)
219 {
220 for (const auto &f : bfd_flag_info)
221 {
222 if (flags & f.value)
223 printf_filtered (" %s", f.name);
224 }
225 }
226
227 static void
228 maint_print_section_info (const char *name, flagword flags,
229 CORE_ADDR addr, CORE_ADDR endaddr,
230 unsigned long filepos, int addr_size)
231 {
232 printf_filtered (" %s", hex_string_custom (addr, addr_size));
233 printf_filtered ("->%s", hex_string_custom (endaddr, addr_size));
234 printf_filtered (" at %s",
235 hex_string_custom ((unsigned long) filepos, 8));
236 printf_filtered (": %s", name);
237 print_bfd_flags (flags);
238 printf_filtered ("\n");
239 }
240
241 /* Return the number of digits required to display COUNT in decimal.
242
243 Used when pretty printing index numbers to ensure all of the indexes line
244 up.*/
245
246 static int
247 index_digits (int count)
248 {
249 return ((int) log10 ((float) count)) + 1;
250 }
251
252 /* Helper function to pretty-print the section index of ASECT from ABFD.
253 The INDEX_DIGITS is the number of digits in the largest index that will
254 be printed, and is used to pretty-print the resulting string. */
255
256 static void
257 print_section_index (bfd *abfd,
258 asection *asect,
259 int index_digits)
260 {
261 std::string result
262 = string_printf (" [%d] ", gdb_bfd_section_index (abfd, asect));
263 /* The '+ 4' for the leading and trailing characters. */
264 printf_filtered ("%-*s", (index_digits + 4), result.c_str ());
265 }
266
267 /* Print information about ASECT from ABFD. The section will be printed using
268 the VMA's from the bfd, which will not be the relocated addresses for bfds
269 that should be relocated. The information must be printed with the same
270 layout as PRINT_OBJFILE_SECTION_INFO below.
271
272 ARG is the argument string passed by the user to the top level maintenance
273 info sections command. Used for filtering which sections are printed. */
274
275 static void
276 print_bfd_section_info (bfd *abfd, asection *asect, const char *arg,
277 int index_digits)
278 {
279 flagword flags = bfd_section_flags (asect);
280 const char *name = bfd_section_name (asect);
281
282 if (arg == NULL || *arg == '\0'
283 || match_substring (arg, name)
284 || match_bfd_flags (arg, flags))
285 {
286 struct gdbarch *gdbarch = gdbarch_from_bfd (abfd);
287 int addr_size = gdbarch_addr_bit (gdbarch) / 8;
288 CORE_ADDR addr, endaddr;
289
290 addr = bfd_section_vma (asect);
291 endaddr = addr + bfd_section_size (asect);
292 print_section_index (abfd, asect, index_digits);
293 maint_print_section_info (name, flags, addr, endaddr,
294 asect->filepos, addr_size);
295 }
296 }
297
298 /* Print information about ASECT which is GDB's wrapper around a section
299 from ABFD. The information must be printed with the same layout as
300 PRINT_BFD_SECTION_INFO above. PRINT_DATA holds information used to
301 filter which sections are printed, and for formatting the output.
302
303 ARG is the argument string passed by the user to the top level maintenance
304 info sections command. Used for filtering which sections are printed. */
305
306 static void
307 print_objfile_section_info (bfd *abfd, struct obj_section *asect,
308 const char *arg, int index_digits)
309 {
310 flagword flags = bfd_section_flags (asect->the_bfd_section);
311 const char *name = bfd_section_name (asect->the_bfd_section);
312
313 if (arg == NULL || *arg == '\0'
314 || match_substring (arg, name)
315 || match_bfd_flags (arg, flags))
316 {
317 struct gdbarch *gdbarch = gdbarch_from_bfd (abfd);
318 int addr_size = gdbarch_addr_bit (gdbarch) / 8;
319
320 print_section_index (abfd, asect->the_bfd_section, index_digits);
321 maint_print_section_info (name, flags,
322 asect->addr (), asect->endaddr (),
323 asect->the_bfd_section->filepos,
324 addr_size);
325 }
326 }
327
328 /* Find an obj_section, GDB's wrapper around a bfd section for ASECTION
329 from ABFD. It might be that no such wrapper exists (for example debug
330 sections don't have such wrappers) in which case nullptr is returned. */
331
332 obj_section *
333 maint_obj_section_from_bfd_section (bfd *abfd,
334 asection *asection,
335 objfile *ofile)
336 {
337 if (ofile->sections == nullptr)
338 return nullptr;
339
340 obj_section *osect
341 = &ofile->sections[gdb_bfd_section_index (abfd, asection)];
342
343 if (osect >= ofile->sections_end)
344 return nullptr;
345
346 return osect;
347 }
348
349 /* Print information about all sections from ABFD, which is the bfd
350 corresponding to OBJFILE. It is fine for OBJFILE to be nullptr, but
351 ABFD must never be nullptr. If OBJFILE is provided then the sections of
352 ABFD will (potentially) be displayed relocated (i.e. the object file was
353 loaded with add-symbol-file and custom offsets were provided).
354
355 HEADER is a string that describes this file, e.g. 'Exec file: ', or
356 'Core file: '.
357
358 ARG is a string used for filtering which sections are printed, this can
359 be nullptr for no filtering. See the top level 'maint info sections'
360 for a fuller description of the possible filtering strings. */
361
362 static void
363 maint_print_all_sections (const char *header, bfd *abfd, objfile *objfile,
364 const char *arg)
365 {
366 puts_filtered (header);
367 wrap_here (" ");
368 printf_filtered ("`%s', ", bfd_get_filename (abfd));
369 wrap_here (" ");
370 printf_filtered (_("file type %s.\n"), bfd_get_target (abfd));
371
372 int section_count = gdb_bfd_count_sections (abfd);
373 int digits = index_digits (section_count);
374
375 for (asection *sect : gdb_bfd_sections (abfd))
376 {
377 obj_section *osect = nullptr;
378
379 if (objfile != nullptr)
380 {
381 gdb_assert (objfile->sections != nullptr);
382 osect
383 = maint_obj_section_from_bfd_section (abfd, sect, objfile);
384 if (osect->the_bfd_section == nullptr)
385 osect = nullptr;
386 }
387
388 if (osect == nullptr)
389 print_bfd_section_info (abfd, sect, arg, digits);
390 else
391 print_objfile_section_info (abfd, osect, arg, digits);
392 }
393 }
394
395 /* The options for the "maintenance info sections" command. */
396
397 struct maint_info_sections_opts
398 {
399 /* For "-all-objects". */
400 bool all_objects = false;
401 };
402
403 static const gdb::option::option_def maint_info_sections_option_defs[] = {
404
405 gdb::option::flag_option_def<maint_info_sections_opts> {
406 "all-objects",
407 [] (maint_info_sections_opts *opts) { return &opts->all_objects; },
408 N_("Display information from all loaded object files."),
409 },
410 };
411
412 /* Create an option_def_group for the "maintenance info sections" options,
413 with CC_OPTS as context. */
414
415 static inline gdb::option::option_def_group
416 make_maint_info_sections_options_def_group (maint_info_sections_opts *cc_opts)
417 {
418 return {{maint_info_sections_option_defs}, cc_opts};
419 }
420
421 /* Completion for the "maintenance info sections" command. */
422
423 static void
424 maint_info_sections_completer (struct cmd_list_element *cmd,
425 completion_tracker &tracker,
426 const char *text, const char * /* word */)
427 {
428 /* Complete command options. */
429 const auto group = make_maint_info_sections_options_def_group (nullptr);
430 if (gdb::option::complete_options
431 (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group))
432 return;
433 const char *word = advance_to_expression_complete_word_point (tracker, text);
434
435 /* Offer completion for section flags, but not section names. This is
436 only a maintenance command after all, no point going over the top. */
437 std::vector<const char *> flags;
438 for (const auto &f : bfd_flag_info)
439 flags.push_back (f.name);
440 flags.push_back (nullptr);
441 complete_on_enum (tracker, flags.data (), text, word);
442 }
443
444 /* Implement the "maintenance info sections" command. */
445
446 static void
447 maintenance_info_sections (const char *arg, int from_tty)
448 {
449 /* Check if the "-all-objects" flag was passed. */
450 maint_info_sections_opts opts;
451 const auto group = make_maint_info_sections_options_def_group (&opts);
452 gdb::option::process_options
453 (&arg, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group);
454
455 for (objfile *ofile : current_program_space->objfiles ())
456 {
457 if (ofile->obfd == current_program_space->exec_bfd ())
458 maint_print_all_sections (_("Exec file: "), ofile->obfd, ofile, arg);
459 else if (opts.all_objects)
460 maint_print_all_sections (_("Object file: "), ofile->obfd, ofile, arg);
461 }
462
463 if (core_bfd)
464 maint_print_all_sections (_("Core file: "), core_bfd, nullptr, arg);
465 }
466
467 /* Implement the "maintenance info target-sections" command. */
468
469 static void
470 maintenance_info_target_sections (const char *arg, int from_tty)
471 {
472 bfd *abfd = nullptr;
473 int digits = 0;
474 const target_section_table *table
475 = target_get_section_table (current_inferior ()->top_target ());
476 if (table == nullptr)
477 return;
478
479 for (const target_section &sec : *table)
480 {
481 if (abfd == nullptr || sec.the_bfd_section->owner != abfd)
482 {
483 abfd = sec.the_bfd_section->owner;
484 digits = std::max (index_digits (gdb_bfd_count_sections (abfd)),
485 digits);
486 }
487 }
488
489 struct gdbarch *gdbarch = nullptr;
490 int addr_size = 0;
491 abfd = nullptr;
492 for (const target_section &sec : *table)
493 {
494 if (sec.the_bfd_section->owner != abfd)
495 {
496 abfd = sec.the_bfd_section->owner;
497 gdbarch = gdbarch_from_bfd (abfd);
498 addr_size = gdbarch_addr_bit (gdbarch) / 8;
499
500 printf_filtered (_("From '%s', file type %s:\n"),
501 bfd_get_filename (abfd), bfd_get_target (abfd));
502 }
503 print_bfd_section_info (abfd,
504 sec.the_bfd_section,
505 nullptr,
506 digits);
507 /* The magic '8 + digits' here ensures that the 'Start' is aligned
508 with the output of print_bfd_section_info. */
509 printf_filtered ("%*sStart: %s, End: %s, Owner token: %p\n",
510 (8 + digits), "",
511 hex_string_custom (sec.addr, addr_size),
512 hex_string_custom (sec.endaddr, addr_size),
513 sec.owner);
514 }
515 }
516
517 static void
518 maintenance_print_statistics (const char *args, int from_tty)
519 {
520 print_objfile_statistics ();
521 }
522
523 static void
524 maintenance_print_architecture (const char *args, int from_tty)
525 {
526 struct gdbarch *gdbarch = get_current_arch ();
527
528 if (args == NULL)
529 gdbarch_dump (gdbarch, gdb_stdout);
530 else
531 {
532 stdio_file file;
533
534 if (!file.open (args, "w"))
535 perror_with_name (_("maintenance print architecture"));
536 gdbarch_dump (gdbarch, &file);
537 }
538 }
539
540 /* The "maintenance translate-address" command converts a section and address
541 to a symbol. This can be called in two ways:
542 maintenance translate-address <secname> <addr>
543 or maintenance translate-address <addr>. */
544
545 static void
546 maintenance_translate_address (const char *arg, int from_tty)
547 {
548 CORE_ADDR address;
549 struct obj_section *sect;
550 const char *p;
551 struct bound_minimal_symbol sym;
552
553 if (arg == NULL || *arg == 0)
554 error (_("requires argument (address or section + address)"));
555
556 sect = NULL;
557 p = arg;
558
559 if (!isdigit (*p))
560 { /* See if we have a valid section name. */
561 while (*p && !isspace (*p)) /* Find end of section name. */
562 p++;
563 if (*p == '\000') /* End of command? */
564 error (_("Need to specify section name and address"));
565
566 int arg_len = p - arg;
567 p = skip_spaces (p + 1);
568
569 for (objfile *objfile : current_program_space->objfiles ())
570 ALL_OBJFILE_OSECTIONS (objfile, sect)
571 {
572 if (strncmp (sect->the_bfd_section->name, arg, arg_len) == 0)
573 goto found;
574 }
575
576 error (_("Unknown section %s."), arg);
577 found: ;
578 }
579
580 address = parse_and_eval_address (p);
581
582 if (sect)
583 sym = lookup_minimal_symbol_by_pc_section (address, sect);
584 else
585 sym = lookup_minimal_symbol_by_pc (address);
586
587 if (sym.minsym)
588 {
589 const char *symbol_name = sym.minsym->print_name ();
590 const char *symbol_offset
591 = pulongest (address - BMSYMBOL_VALUE_ADDRESS (sym));
592
593 sect = sym.obj_section ();
594 if (sect != NULL)
595 {
596 const char *section_name;
597 const char *obj_name;
598
599 gdb_assert (sect->the_bfd_section && sect->the_bfd_section->name);
600 section_name = sect->the_bfd_section->name;
601
602 gdb_assert (sect->objfile && objfile_name (sect->objfile));
603 obj_name = objfile_name (sect->objfile);
604
605 if (current_program_space->multi_objfile_p ())
606 printf_filtered (_("%s + %s in section %s of %s\n"),
607 symbol_name, symbol_offset,
608 section_name, obj_name);
609 else
610 printf_filtered (_("%s + %s in section %s\n"),
611 symbol_name, symbol_offset, section_name);
612 }
613 else
614 printf_filtered (_("%s + %s\n"), symbol_name, symbol_offset);
615 }
616 else if (sect)
617 printf_filtered (_("no symbol at %s:%s\n"),
618 sect->the_bfd_section->name, hex_string (address));
619 else
620 printf_filtered (_("no symbol at %s\n"), hex_string (address));
621
622 return;
623 }
624
625
626 /* When a command is deprecated the user will be warned the first time
627 the command is used. If possible, a replacement will be
628 offered. */
629
630 static void
631 maintenance_deprecate (const char *args, int from_tty)
632 {
633 if (args == NULL || *args == '\0')
634 {
635 printf_filtered (_("\"maintenance deprecate\" takes an argument,\n\
636 the command you want to deprecate, and optionally the replacement command\n\
637 enclosed in quotes.\n"));
638 }
639
640 maintenance_do_deprecate (args, 1);
641 }
642
643
644 static void
645 maintenance_undeprecate (const char *args, int from_tty)
646 {
647 if (args == NULL || *args == '\0')
648 {
649 printf_filtered (_("\"maintenance undeprecate\" takes an argument, \n\
650 the command you want to undeprecate.\n"));
651 }
652
653 maintenance_do_deprecate (args, 0);
654 }
655
656 /* You really shouldn't be using this. It is just for the testsuite.
657 Rather, you should use deprecate_cmd() when the command is created
658 in _initialize_blah().
659
660 This function deprecates a command and optionally assigns it a
661 replacement. */
662
663 static void
664 maintenance_do_deprecate (const char *text, int deprecate)
665 {
666 struct cmd_list_element *alias = NULL;
667 struct cmd_list_element *prefix_cmd = NULL;
668 struct cmd_list_element *cmd = NULL;
669
670 const char *start_ptr = NULL;
671 const char *end_ptr = NULL;
672 int len;
673 char *replacement = NULL;
674
675 if (text == NULL)
676 return;
677
678 if (!lookup_cmd_composition (text, &alias, &prefix_cmd, &cmd))
679 {
680 printf_filtered (_("Can't find command '%s' to deprecate.\n"), text);
681 return;
682 }
683
684 if (deprecate)
685 {
686 /* Look for a replacement command. */
687 start_ptr = strchr (text, '\"');
688 if (start_ptr != NULL)
689 {
690 start_ptr++;
691 end_ptr = strrchr (start_ptr, '\"');
692 if (end_ptr != NULL)
693 {
694 len = end_ptr - start_ptr;
695 replacement = savestring (start_ptr, len);
696 }
697 }
698 }
699
700 if (!start_ptr || !end_ptr)
701 replacement = NULL;
702
703
704 /* If they used an alias, we only want to deprecate the alias.
705
706 Note the MALLOCED_REPLACEMENT test. If the command's replacement
707 string was allocated at compile time we don't want to free the
708 memory. */
709 if (alias)
710 {
711 if (alias->malloced_replacement)
712 xfree ((char *) alias->replacement);
713
714 if (deprecate)
715 {
716 alias->deprecated_warn_user = 1;
717 alias->cmd_deprecated = 1;
718 }
719 else
720 {
721 alias->deprecated_warn_user = 0;
722 alias->cmd_deprecated = 0;
723 }
724 alias->replacement = replacement;
725 alias->malloced_replacement = 1;
726 return;
727 }
728 else if (cmd)
729 {
730 if (cmd->malloced_replacement)
731 xfree ((char *) cmd->replacement);
732
733 if (deprecate)
734 {
735 cmd->deprecated_warn_user = 1;
736 cmd->cmd_deprecated = 1;
737 }
738 else
739 {
740 cmd->deprecated_warn_user = 0;
741 cmd->cmd_deprecated = 0;
742 }
743 cmd->replacement = replacement;
744 cmd->malloced_replacement = 1;
745 return;
746 }
747 xfree (replacement);
748 }
749
750 /* Maintenance set/show framework. */
751
752 struct cmd_list_element *maintenance_set_cmdlist;
753 struct cmd_list_element *maintenance_show_cmdlist;
754
755 /* "maintenance with" command. */
756
757 static void
758 maintenance_with_cmd (const char *args, int from_tty)
759 {
760 with_command_1 ("maintenance set ", maintenance_set_cmdlist, args, from_tty);
761 }
762
763 /* "maintenance with" command completer. */
764
765 static void
766 maintenance_with_cmd_completer (struct cmd_list_element *ignore,
767 completion_tracker &tracker,
768 const char *text, const char * /*word*/)
769 {
770 with_command_completer_1 ("maintenance set ", tracker, text);
771 }
772
773 /* Profiling support. */
774
775 static bool maintenance_profile_p;
776 static void
777 show_maintenance_profile_p (struct ui_file *file, int from_tty,
778 struct cmd_list_element *c, const char *value)
779 {
780 fprintf_filtered (file, _("Internal profiling is %s.\n"), value);
781 }
782
783 #ifdef HAVE__ETEXT
784 extern char _etext;
785 #define TEXTEND &_etext
786 #elif defined (HAVE_ETEXT)
787 extern char etext;
788 #define TEXTEND &etext
789 #endif
790
791 #if defined (HAVE_MONSTARTUP) && defined (HAVE__MCLEANUP) && defined (TEXTEND)
792
793 static int profiling_state;
794
795 EXTERN_C void _mcleanup (void);
796
797 static void
798 mcleanup_wrapper (void)
799 {
800 if (profiling_state)
801 _mcleanup ();
802 }
803
804 EXTERN_C void monstartup (unsigned long, unsigned long);
805 extern int main ();
806
807 static void
808 maintenance_set_profile_cmd (const char *args, int from_tty,
809 struct cmd_list_element *c)
810 {
811 if (maintenance_profile_p == profiling_state)
812 return;
813
814 profiling_state = maintenance_profile_p;
815
816 if (maintenance_profile_p)
817 {
818 static int profiling_initialized;
819
820 if (!profiling_initialized)
821 {
822 atexit (mcleanup_wrapper);
823 profiling_initialized = 1;
824 }
825
826 /* "main" is now always the first function in the text segment, so use
827 its address for monstartup. */
828 monstartup ((unsigned long) &main, (unsigned long) TEXTEND);
829 }
830 else
831 {
832 extern void _mcleanup (void);
833
834 _mcleanup ();
835 }
836 }
837 #else
838 static void
839 maintenance_set_profile_cmd (const char *args, int from_tty,
840 struct cmd_list_element *c)
841 {
842 error (_("Profiling support is not available on this system."));
843 }
844 #endif
845
846 static int n_worker_threads = -1;
847
848 /* Update the thread pool for the desired number of threads. */
849 static 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 n_threads = std::thread::hardware_concurrency ();
857
858 gdb::thread_pool::g_thread_pool->set_thread_count (n_threads);
859 #endif
860 }
861
862 static void
863 maintenance_set_worker_threads (const char *args, int from_tty,
864 struct cmd_list_element *c)
865 {
866 update_thread_pool_size ();
867 }
868
869 static void
870 maintenance_show_worker_threads (struct ui_file *file, int from_tty,
871 struct cmd_list_element *c,
872 const char *value)
873 {
874 #if CXX_STD_THREAD
875 if (n_worker_threads == -1)
876 {
877 fprintf_filtered (file, _("The number of worker threads GDB "
878 "can use is unlimited (currently %zu).\n"),
879 gdb::thread_pool::g_thread_pool->thread_count ());
880 return;
881 }
882 #endif
883
884 int report_threads = 0;
885 #if CXX_STD_THREAD
886 report_threads = n_worker_threads;
887 #endif
888 fprintf_filtered (file, _("The number of worker threads GDB "
889 "can use is %d.\n"),
890 report_threads);
891 }
892
893 \f
894 /* If true, display time usage both at startup and for each command. */
895
896 static bool per_command_time;
897
898 /* If true, display space usage both at startup and for each command. */
899
900 static bool per_command_space;
901
902 /* If true, display basic symtab stats for each command. */
903
904 static bool per_command_symtab;
905
906 /* mt per-command commands. */
907
908 static struct cmd_list_element *per_command_setlist;
909 static struct cmd_list_element *per_command_showlist;
910
911 /* Set whether to display time statistics to NEW_VALUE
912 (non-zero means true). */
913
914 void
915 set_per_command_time (int new_value)
916 {
917 per_command_time = new_value;
918 }
919
920 /* Set whether to display space statistics to NEW_VALUE
921 (non-zero means true). */
922
923 void
924 set_per_command_space (int new_value)
925 {
926 per_command_space = new_value;
927 }
928
929 /* Count the number of symtabs and blocks. */
930
931 static void
932 count_symtabs_and_blocks (int *nr_symtabs_ptr, int *nr_compunit_symtabs_ptr,
933 int *nr_blocks_ptr)
934 {
935 int nr_symtabs = 0;
936 int nr_compunit_symtabs = 0;
937 int nr_blocks = 0;
938
939 /* When collecting statistics during startup, this is called before
940 pretty much anything in gdb has been initialized, and thus
941 current_program_space may be NULL. */
942 if (current_program_space != NULL)
943 {
944 for (objfile *o : current_program_space->objfiles ())
945 {
946 for (compunit_symtab *cu : o->compunits ())
947 {
948 ++nr_compunit_symtabs;
949 nr_blocks += BLOCKVECTOR_NBLOCKS (COMPUNIT_BLOCKVECTOR (cu));
950 nr_symtabs += std::distance (compunit_filetabs (cu).begin (),
951 compunit_filetabs (cu).end ());
952 }
953 }
954 }
955
956 *nr_symtabs_ptr = nr_symtabs;
957 *nr_compunit_symtabs_ptr = nr_compunit_symtabs;
958 *nr_blocks_ptr = nr_blocks;
959 }
960
961 /* As indicated by display_time and display_space, report GDB's
962 elapsed time and space usage from the base time and space recorded
963 in this object. */
964
965 scoped_command_stats::~scoped_command_stats ()
966 {
967 /* Early exit if we're not reporting any stats. It can be expensive to
968 compute the pre-command values so don't collect them at all if we're
969 not reporting stats. Alas this doesn't work in the startup case because
970 we don't know yet whether we will be reporting the stats. For the
971 startup case collect the data anyway (it should be cheap at this point),
972 and leave it to the reporter to decide whether to print them. */
973 if (m_msg_type
974 && !per_command_time
975 && !per_command_space
976 && !per_command_symtab)
977 return;
978
979 if (m_time_enabled && per_command_time)
980 {
981 print_time (_("command finished"));
982
983 using namespace std::chrono;
984
985 run_time_clock::duration cmd_time
986 = run_time_clock::now () - m_start_cpu_time;
987
988 steady_clock::duration wall_time
989 = steady_clock::now () - m_start_wall_time;
990 /* Subtract time spend in prompt_for_continue from walltime. */
991 wall_time -= get_prompt_for_continue_wait_time ();
992
993 printf_unfiltered (!m_msg_type
994 ? _("Startup time: %.6f (cpu), %.6f (wall)\n")
995 : _("Command execution time: %.6f (cpu), %.6f (wall)\n"),
996 duration<double> (cmd_time).count (),
997 duration<double> (wall_time).count ());
998 }
999
1000 if (m_space_enabled && per_command_space)
1001 {
1002 #ifdef HAVE_USEFUL_SBRK
1003 char *lim = (char *) sbrk (0);
1004
1005 long space_now = lim - lim_at_start;
1006 long space_diff = space_now - m_start_space;
1007
1008 printf_unfiltered (!m_msg_type
1009 ? _("Space used: %ld (%s%ld during startup)\n")
1010 : _("Space used: %ld (%s%ld for this command)\n"),
1011 space_now,
1012 (space_diff >= 0 ? "+" : ""),
1013 space_diff);
1014 #endif
1015 }
1016
1017 if (m_symtab_enabled && per_command_symtab)
1018 {
1019 int nr_symtabs, nr_compunit_symtabs, nr_blocks;
1020
1021 count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
1022 printf_unfiltered (_("#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 printf_unfiltered ("%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 printf_filtered (_("\
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 printf_filtered ("Registered selftests:\n");
1197 selftests::for_each_selftest ([] (const std::string &name) {
1198 printf_filtered (" - %s\n", name.c_str ());
1199 });
1200 #else
1201 printf_filtered (_("\
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 }