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