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