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