Home | History | Annotate | Line # | Download | only in gdb
maint.c revision 1.1.1.7
      1 /* Support for GDB maintenance commands.
      2 
      3    Copyright (C) 1992-2020 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 
     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 #if CXX_STD_THREAD
     50 #include "gdbsupport/thread-pool.h"
     51 #endif
     52 
     53 static void maintenance_do_deprecate (const char *, int);
     54 
     55 #ifndef _WIN32
     56 static void
     57 maintenance_dump_me (const char *args, int from_tty)
     58 {
     59   if (query (_("Should GDB dump core? ")))
     60     {
     61 #ifdef __DJGPP__
     62       /* SIGQUIT by default is ignored, so use SIGABRT instead.  */
     63       signal (SIGABRT, SIG_DFL);
     64       kill (getpid (), SIGABRT);
     65 #else
     66       signal (SIGQUIT, SIG_DFL);
     67       kill (getpid (), SIGQUIT);
     68 #endif
     69     }
     70 }
     71 #endif
     72 
     73 /* Stimulate the internal error mechanism that GDB uses when an
     74    internal problem is detected.  Allows testing of the mechanism.
     75    Also useful when the user wants to drop a core file but not exit
     76    GDB.  */
     77 
     78 static void
     79 maintenance_internal_error (const char *args, int from_tty)
     80 {
     81   internal_error (__FILE__, __LINE__, "%s", (args == NULL ? "" : args));
     82 }
     83 
     84 /* Stimulate the internal error mechanism that GDB uses when an
     85    internal problem is detected.  Allows testing of the mechanism.
     86    Also useful when the user wants to drop a core file but not exit
     87    GDB.  */
     88 
     89 static void
     90 maintenance_internal_warning (const char *args, int from_tty)
     91 {
     92   internal_warning (__FILE__, __LINE__, "%s", (args == NULL ? "" : args));
     93 }
     94 
     95 /* Stimulate the internal error mechanism that GDB uses when an
     96    demangler problem is detected.  Allows testing of the mechanism.  */
     97 
     98 static void
     99 maintenance_demangler_warning (const char *args, int from_tty)
    100 {
    101   demangler_warning (__FILE__, __LINE__, "%s", (args == NULL ? "" : args));
    102 }
    103 
    104 /* Old command to demangle a string.  The command has been moved to "demangle".
    105    It is kept for now because otherwise "mt demangle" gets interpreted as
    106    "mt demangler-warning" which artificially creates an internal gdb error.  */
    107 
    108 static void
    109 maintenance_demangle (const char *args, int from_tty)
    110 {
    111   printf_filtered (_("This command has been moved to \"demangle\".\n"));
    112 }
    113 
    114 static void
    115 maintenance_time_display (const char *args, int from_tty)
    116 {
    117   if (args == NULL || *args == '\0')
    118     printf_unfiltered (_("\"maintenance time\" takes a numeric argument.\n"));
    119   else
    120     set_per_command_time (strtol (args, NULL, 10));
    121 }
    122 
    123 static void
    124 maintenance_space_display (const char *args, int from_tty)
    125 {
    126   if (args == NULL || *args == '\0')
    127     printf_unfiltered ("\"maintenance space\" takes a numeric argument.\n");
    128   else
    129     set_per_command_space (strtol (args, NULL, 10));
    130 }
    131 
    132 /* Mini tokenizing lexer for 'maint info sections' command.  */
    133 
    134 static int
    135 match_substring (const char *string, const char *substr)
    136 {
    137   int substr_len = strlen(substr);
    138   const char *tok;
    139 
    140   while ((tok = strstr (string, substr)) != NULL)
    141     {
    142       /* Got a partial match.  Is it a whole word?  */
    143       if (tok == string
    144 	  || tok[-1] == ' '
    145 	  || tok[-1] == '\t')
    146       {
    147 	/* Token is delimited at the front...  */
    148 	if (tok[substr_len] == ' '
    149 	    || tok[substr_len] == '\t'
    150 	    || tok[substr_len] == '\0')
    151 	{
    152 	  /* Token is delimited at the rear.  Got a whole-word match.  */
    153 	  return 1;
    154 	}
    155       }
    156       /* Token didn't match as a whole word.  Advance and try again.  */
    157       string = tok + 1;
    158     }
    159   return 0;
    160 }
    161 
    162 static int
    163 match_bfd_flags (const char *string, flagword flags)
    164 {
    165   if (flags & SEC_ALLOC)
    166     if (match_substring (string, "ALLOC"))
    167       return 1;
    168   if (flags & SEC_LOAD)
    169     if (match_substring (string, "LOAD"))
    170       return 1;
    171   if (flags & SEC_RELOC)
    172     if (match_substring (string, "RELOC"))
    173       return 1;
    174   if (flags & SEC_READONLY)
    175     if (match_substring (string, "READONLY"))
    176       return 1;
    177   if (flags & SEC_CODE)
    178     if (match_substring (string, "CODE"))
    179       return 1;
    180   if (flags & SEC_DATA)
    181     if (match_substring (string, "DATA"))
    182       return 1;
    183   if (flags & SEC_ROM)
    184     if (match_substring (string, "ROM"))
    185       return 1;
    186   if (flags & SEC_CONSTRUCTOR)
    187     if (match_substring (string, "CONSTRUCTOR"))
    188       return 1;
    189   if (flags & SEC_HAS_CONTENTS)
    190     if (match_substring (string, "HAS_CONTENTS"))
    191       return 1;
    192   if (flags & SEC_NEVER_LOAD)
    193     if (match_substring (string, "NEVER_LOAD"))
    194       return 1;
    195   if (flags & SEC_COFF_SHARED_LIBRARY)
    196     if (match_substring (string, "COFF_SHARED_LIBRARY"))
    197       return 1;
    198   if (flags & SEC_IS_COMMON)
    199     if (match_substring (string, "IS_COMMON"))
    200       return 1;
    201 
    202   return 0;
    203 }
    204 
    205 static void
    206 print_bfd_flags (flagword flags)
    207 {
    208   if (flags & SEC_ALLOC)
    209     printf_filtered (" ALLOC");
    210   if (flags & SEC_LOAD)
    211     printf_filtered (" LOAD");
    212   if (flags & SEC_RELOC)
    213     printf_filtered (" RELOC");
    214   if (flags & SEC_READONLY)
    215     printf_filtered (" READONLY");
    216   if (flags & SEC_CODE)
    217     printf_filtered (" CODE");
    218   if (flags & SEC_DATA)
    219     printf_filtered (" DATA");
    220   if (flags & SEC_ROM)
    221     printf_filtered (" ROM");
    222   if (flags & SEC_CONSTRUCTOR)
    223     printf_filtered (" CONSTRUCTOR");
    224   if (flags & SEC_HAS_CONTENTS)
    225     printf_filtered (" HAS_CONTENTS");
    226   if (flags & SEC_NEVER_LOAD)
    227     printf_filtered (" NEVER_LOAD");
    228   if (flags & SEC_COFF_SHARED_LIBRARY)
    229     printf_filtered (" COFF_SHARED_LIBRARY");
    230   if (flags & SEC_IS_COMMON)
    231     printf_filtered (" IS_COMMON");
    232 }
    233 
    234 static void
    235 maint_print_section_info (const char *name, flagword flags,
    236 			  CORE_ADDR addr, CORE_ADDR endaddr,
    237 			  unsigned long filepos, int addr_size)
    238 {
    239   printf_filtered ("    %s", hex_string_custom (addr, addr_size));
    240   printf_filtered ("->%s", hex_string_custom (endaddr, addr_size));
    241   printf_filtered (" at %s",
    242 		   hex_string_custom ((unsigned long) filepos, 8));
    243   printf_filtered (": %s", name);
    244   print_bfd_flags (flags);
    245   printf_filtered ("\n");
    246 }
    247 
    248 /* Return the number of digits required to display COUNT in decimal.
    249 
    250    Used when pretty printing index numbers to ensure all of the indexes line
    251    up.*/
    252 
    253 static int
    254 index_digits (int count)
    255 {
    256   return ((int) log10 ((float) count)) + 1;
    257 }
    258 
    259 /* Helper function to pretty-print the section index of ASECT from ABFD.
    260    The INDEX_DIGITS is the number of digits in the largest index that will
    261    be printed, and is used to pretty-print the resulting string.  */
    262 
    263 static void
    264 print_section_index (bfd *abfd,
    265 		     asection *asect,
    266 		     int index_digits)
    267 {
    268   std::string result
    269     = string_printf (" [%d] ", gdb_bfd_section_index (abfd, asect));
    270   /* The '+ 4' for the leading and trailing characters.  */
    271   printf_filtered ("%-*s", (index_digits + 4), result.c_str ());
    272 }
    273 
    274 /* Print information about ASECT from ABFD.  The section will be printed using
    275    the VMA's from the bfd, which will not be the relocated addresses for bfds
    276    that should be relocated.  The information must be printed with the same
    277    layout as PRINT_OBJFILE_SECTION_INFO below.
    278 
    279    ARG is the argument string passed by the user to the top level maintenance
    280    info sections command.  Used for filtering which sections are printed.  */
    281 
    282 static void
    283 print_bfd_section_info (bfd *abfd, asection *asect, const char *arg,
    284 			int index_digits)
    285 {
    286   flagword flags = bfd_section_flags (asect);
    287   const char *name = bfd_section_name (asect);
    288 
    289   if (arg == NULL || *arg == '\0'
    290       || match_substring (arg, name)
    291       || match_bfd_flags (arg, flags))
    292     {
    293       struct gdbarch *gdbarch = gdbarch_from_bfd (abfd);
    294       int addr_size = gdbarch_addr_bit (gdbarch) / 8;
    295       CORE_ADDR addr, endaddr;
    296 
    297       addr = bfd_section_vma (asect);
    298       endaddr = addr + bfd_section_size (asect);
    299       print_section_index (abfd, asect, index_digits);
    300       maint_print_section_info (name, flags, addr, endaddr,
    301 				asect->filepos, addr_size);
    302     }
    303 }
    304 
    305 /* Print information about ASECT which is GDB's wrapper around a section
    306    from ABFD.  The information must be printed with the same layout as
    307    PRINT_BFD_SECTION_INFO above.  PRINT_DATA holds information used to
    308    filter which sections are printed, and for formatting the output.
    309 
    310    ARG is the argument string passed by the user to the top level maintenance
    311    info sections command.  Used for filtering which sections are printed.  */
    312 
    313 static void
    314 print_objfile_section_info (bfd *abfd, struct obj_section *asect,
    315 			    const char *arg, int index_digits)
    316 {
    317   flagword flags = bfd_section_flags (asect->the_bfd_section);
    318   const char *name = bfd_section_name (asect->the_bfd_section);
    319 
    320   if (arg == NULL || *arg == '\0'
    321       || match_substring (arg, name)
    322       || match_bfd_flags (arg, flags))
    323     {
    324       struct gdbarch *gdbarch = gdbarch_from_bfd (abfd);
    325       int addr_size = gdbarch_addr_bit (gdbarch) / 8;
    326 
    327       print_section_index (abfd, asect->the_bfd_section, index_digits);
    328       maint_print_section_info (name, flags,
    329 				obj_section_addr (asect),
    330 				obj_section_endaddr (asect),
    331 				asect->the_bfd_section->filepos,
    332 				addr_size);
    333     }
    334 }
    335 
    336 /* Find an obj_section, GDB's wrapper around a bfd section for ASECTION
    337    from ABFD.  It might be that no such wrapper exists (for example debug
    338    sections don't have such wrappers) in which case nullptr is returned.  */
    339 
    340 static obj_section *
    341 maint_obj_section_from_bfd_section (bfd *abfd,
    342 				    asection *asection,
    343 				    objfile *ofile)
    344 {
    345   if (ofile->sections == nullptr)
    346     return nullptr;
    347 
    348   obj_section *osect
    349     = &ofile->sections[gdb_bfd_section_index (abfd, asection)];
    350 
    351   if (osect >= ofile->sections_end)
    352     return nullptr;
    353 
    354   return osect;
    355 }
    356 
    357 /* Print information about ASECT from ABFD.  Where possible the information for
    358    ASECT will print the relocated addresses of the section.
    359 
    360    ARG is the argument string passed by the user to the top level maintenance
    361    info sections command.  Used for filtering which sections are printed.  */
    362 
    363 static void
    364 print_bfd_section_info_maybe_relocated (bfd *abfd, asection *asect,
    365 					objfile *objfile, const char *arg,
    366 					int index_digits)
    367 {
    368   gdb_assert (objfile->sections != NULL);
    369   obj_section *osect
    370     = maint_obj_section_from_bfd_section (abfd, asect, objfile);
    371 
    372   if (osect->the_bfd_section == NULL)
    373     print_bfd_section_info (abfd, asect, arg, index_digits);
    374   else
    375     print_objfile_section_info (abfd, osect, arg, index_digits);
    376 }
    377 
    378 /* Implement the "maintenance info sections" command.  */
    379 
    380 static void
    381 maintenance_info_sections (const char *arg, int from_tty)
    382 {
    383   if (exec_bfd)
    384     {
    385       bool allobj = false;
    386 
    387       printf_filtered (_("Exec file:\n"));
    388       printf_filtered ("    `%s', ", bfd_get_filename (exec_bfd));
    389       wrap_here ("        ");
    390       printf_filtered (_("file type %s.\n"), bfd_get_target (exec_bfd));
    391 
    392       /* Only this function cares about the 'ALLOBJ' argument;
    393 	 if 'ALLOBJ' is the only argument, discard it rather than
    394 	 passing it down to print_objfile_section_info (which
    395 	 wouldn't know how to handle it).  */
    396       if (arg && strcmp (arg, "ALLOBJ") == 0)
    397 	{
    398 	  arg = NULL;
    399 	  allobj = true;
    400 	}
    401 
    402       for (objfile *ofile : current_program_space->objfiles ())
    403 	{
    404 	  if (allobj)
    405 	    printf_filtered (_("  Object file: %s\n"),
    406 			     bfd_get_filename (ofile->obfd));
    407 	  else if (ofile->obfd != exec_bfd)
    408 	    continue;
    409 
    410 	  int section_count = gdb_bfd_count_sections (ofile->obfd);
    411 
    412 	  for (asection *sect : gdb_bfd_sections (ofile->obfd))
    413 	    print_bfd_section_info_maybe_relocated
    414 	      (ofile->obfd, sect, ofile, arg, index_digits (section_count));
    415 	}
    416     }
    417 
    418   if (core_bfd)
    419     {
    420       printf_filtered (_("Core file:\n"));
    421       printf_filtered ("    `%s', ", bfd_get_filename (core_bfd));
    422       wrap_here ("        ");
    423       printf_filtered (_("file type %s.\n"), bfd_get_target (core_bfd));
    424 
    425       int section_count = gdb_bfd_count_sections (core_bfd);
    426 
    427       for (asection *sect : gdb_bfd_sections (core_bfd))
    428 	print_bfd_section_info (core_bfd, sect, arg,
    429 				index_digits (section_count));
    430     }
    431 }
    432 
    433 static void
    434 maintenance_print_statistics (const char *args, int from_tty)
    435 {
    436   print_objfile_statistics ();
    437   print_symbol_bcache_statistics ();
    438 }
    439 
    440 static void
    441 maintenance_print_architecture (const char *args, int from_tty)
    442 {
    443   struct gdbarch *gdbarch = get_current_arch ();
    444 
    445   if (args == NULL)
    446     gdbarch_dump (gdbarch, gdb_stdout);
    447   else
    448     {
    449       stdio_file file;
    450 
    451       if (!file.open (args, "w"))
    452 	perror_with_name (_("maintenance print architecture"));
    453       gdbarch_dump (gdbarch, &file);
    454     }
    455 }
    456 
    457 /* The "maintenance translate-address" command converts a section and address
    458    to a symbol.  This can be called in two ways:
    459    maintenance translate-address <secname> <addr>
    460    or   maintenance translate-address <addr>.  */
    461 
    462 static void
    463 maintenance_translate_address (const char *arg, int from_tty)
    464 {
    465   CORE_ADDR address;
    466   struct obj_section *sect;
    467   const char *p;
    468   struct bound_minimal_symbol sym;
    469 
    470   if (arg == NULL || *arg == 0)
    471     error (_("requires argument (address or section + address)"));
    472 
    473   sect = NULL;
    474   p = arg;
    475 
    476   if (!isdigit (*p))
    477     {				/* See if we have a valid section name.  */
    478       while (*p && !isspace (*p))	/* Find end of section name.  */
    479 	p++;
    480       if (*p == '\000')		/* End of command?  */
    481 	error (_("Need to specify section name and address"));
    482 
    483       int arg_len = p - arg;
    484       p = skip_spaces (p + 1);
    485 
    486       for (objfile *objfile : current_program_space->objfiles ())
    487 	ALL_OBJFILE_OSECTIONS (objfile, sect)
    488 	  {
    489 	    if (strncmp (sect->the_bfd_section->name, arg, arg_len) == 0)
    490 	      goto found;
    491 	  }
    492 
    493       error (_("Unknown section %s."), arg);
    494     found: ;
    495     }
    496 
    497   address = parse_and_eval_address (p);
    498 
    499   if (sect)
    500     sym = lookup_minimal_symbol_by_pc_section (address, sect);
    501   else
    502     sym = lookup_minimal_symbol_by_pc (address);
    503 
    504   if (sym.minsym)
    505     {
    506       const char *symbol_name = sym.minsym->print_name ();
    507       const char *symbol_offset
    508 	= pulongest (address - BMSYMBOL_VALUE_ADDRESS (sym));
    509 
    510       sect = MSYMBOL_OBJ_SECTION(sym.objfile, sym.minsym);
    511       if (sect != NULL)
    512 	{
    513 	  const char *section_name;
    514 	  const char *obj_name;
    515 
    516 	  gdb_assert (sect->the_bfd_section && sect->the_bfd_section->name);
    517 	  section_name = sect->the_bfd_section->name;
    518 
    519 	  gdb_assert (sect->objfile && objfile_name (sect->objfile));
    520 	  obj_name = objfile_name (sect->objfile);
    521 
    522 	  if (current_program_space->multi_objfile_p ())
    523 	    printf_filtered (_("%s + %s in section %s of %s\n"),
    524 			     symbol_name, symbol_offset,
    525 			     section_name, obj_name);
    526 	  else
    527 	    printf_filtered (_("%s + %s in section %s\n"),
    528 			     symbol_name, symbol_offset, section_name);
    529 	}
    530       else
    531 	printf_filtered (_("%s + %s\n"), symbol_name, symbol_offset);
    532     }
    533   else if (sect)
    534     printf_filtered (_("no symbol at %s:%s\n"),
    535 		     sect->the_bfd_section->name, hex_string (address));
    536   else
    537     printf_filtered (_("no symbol at %s\n"), hex_string (address));
    538 
    539   return;
    540 }
    541 
    542 
    543 /* When a command is deprecated the user will be warned the first time
    544    the command is used.  If possible, a replacement will be
    545    offered.  */
    546 
    547 static void
    548 maintenance_deprecate (const char *args, int from_tty)
    549 {
    550   if (args == NULL || *args == '\0')
    551     {
    552       printf_unfiltered (_("\"maintenance deprecate\" takes an argument,\n\
    553 the command you want to deprecate, and optionally the replacement command\n\
    554 enclosed in quotes.\n"));
    555     }
    556 
    557   maintenance_do_deprecate (args, 1);
    558 }
    559 
    560 
    561 static void
    562 maintenance_undeprecate (const char *args, int from_tty)
    563 {
    564   if (args == NULL || *args == '\0')
    565     {
    566       printf_unfiltered (_("\"maintenance undeprecate\" takes an argument, \n\
    567 the command you want to undeprecate.\n"));
    568     }
    569 
    570   maintenance_do_deprecate (args, 0);
    571 }
    572 
    573 /* You really shouldn't be using this.  It is just for the testsuite.
    574    Rather, you should use deprecate_cmd() when the command is created
    575    in _initialize_blah().
    576 
    577    This function deprecates a command and optionally assigns it a
    578    replacement.  */
    579 
    580 static void
    581 maintenance_do_deprecate (const char *text, int deprecate)
    582 {
    583   struct cmd_list_element *alias = NULL;
    584   struct cmd_list_element *prefix_cmd = NULL;
    585   struct cmd_list_element *cmd = NULL;
    586 
    587   const char *start_ptr = NULL;
    588   const char *end_ptr = NULL;
    589   int len;
    590   char *replacement = NULL;
    591 
    592   if (text == NULL)
    593     return;
    594 
    595   if (!lookup_cmd_composition (text, &alias, &prefix_cmd, &cmd))
    596     {
    597       printf_filtered (_("Can't find command '%s' to deprecate.\n"), text);
    598       return;
    599     }
    600 
    601   if (deprecate)
    602     {
    603       /* Look for a replacement command.  */
    604       start_ptr = strchr (text, '\"');
    605       if (start_ptr != NULL)
    606 	{
    607 	  start_ptr++;
    608 	  end_ptr = strrchr (start_ptr, '\"');
    609 	  if (end_ptr != NULL)
    610 	    {
    611 	      len = end_ptr - start_ptr;
    612 	      replacement = savestring (start_ptr, len);
    613 	    }
    614 	}
    615     }
    616 
    617   if (!start_ptr || !end_ptr)
    618     replacement = NULL;
    619 
    620 
    621   /* If they used an alias, we only want to deprecate the alias.
    622 
    623      Note the MALLOCED_REPLACEMENT test.  If the command's replacement
    624      string was allocated at compile time we don't want to free the
    625      memory.  */
    626   if (alias)
    627     {
    628       if (alias->malloced_replacement)
    629 	xfree ((char *) alias->replacement);
    630 
    631       if (deprecate)
    632 	{
    633 	  alias->deprecated_warn_user = 1;
    634 	  alias->cmd_deprecated = 1;
    635 	}
    636       else
    637 	{
    638 	  alias->deprecated_warn_user = 0;
    639 	  alias->cmd_deprecated = 0;
    640 	}
    641       alias->replacement = replacement;
    642       alias->malloced_replacement = 1;
    643       return;
    644     }
    645   else if (cmd)
    646     {
    647       if (cmd->malloced_replacement)
    648 	xfree ((char *) cmd->replacement);
    649 
    650       if (deprecate)
    651 	{
    652 	  cmd->deprecated_warn_user = 1;
    653 	  cmd->cmd_deprecated = 1;
    654 	}
    655       else
    656 	{
    657 	  cmd->deprecated_warn_user = 0;
    658 	  cmd->cmd_deprecated = 0;
    659 	}
    660       cmd->replacement = replacement;
    661       cmd->malloced_replacement = 1;
    662       return;
    663     }
    664   xfree (replacement);
    665 }
    666 
    667 /* Maintenance set/show framework.  */
    668 
    669 struct cmd_list_element *maintenance_set_cmdlist;
    670 struct cmd_list_element *maintenance_show_cmdlist;
    671 
    672 /* "maintenance with" command.  */
    673 
    674 static void
    675 maintenance_with_cmd (const char *args, int from_tty)
    676 {
    677   with_command_1 ("maintenance set ", maintenance_set_cmdlist, args, from_tty);
    678 }
    679 
    680 /* "maintenance with" command completer.  */
    681 
    682 static void
    683 maintenance_with_cmd_completer (struct cmd_list_element *ignore,
    684 				completion_tracker &tracker,
    685 				const char *text, const char * /*word*/)
    686 {
    687   with_command_completer_1 ("maintenance set ", tracker,  text);
    688 }
    689 
    690 /* Profiling support.  */
    691 
    692 static bool maintenance_profile_p;
    693 static void
    694 show_maintenance_profile_p (struct ui_file *file, int from_tty,
    695 			    struct cmd_list_element *c, const char *value)
    696 {
    697   fprintf_filtered (file, _("Internal profiling is %s.\n"), value);
    698 }
    699 
    700 #ifdef HAVE__ETEXT
    701 extern char _etext;
    702 #define TEXTEND &_etext
    703 #elif defined (HAVE_ETEXT)
    704 extern char etext;
    705 #define TEXTEND &etext
    706 #endif
    707 
    708 #if defined (HAVE_MONSTARTUP) && defined (HAVE__MCLEANUP) && defined (TEXTEND)
    709 
    710 static int profiling_state;
    711 
    712 EXTERN_C void _mcleanup (void);
    713 
    714 static void
    715 mcleanup_wrapper (void)
    716 {
    717   if (profiling_state)
    718     _mcleanup ();
    719 }
    720 
    721 EXTERN_C void monstartup (unsigned long, unsigned long);
    722 extern int main ();
    723 
    724 static void
    725 maintenance_set_profile_cmd (const char *args, int from_tty,
    726 			     struct cmd_list_element *c)
    727 {
    728   if (maintenance_profile_p == profiling_state)
    729     return;
    730 
    731   profiling_state = maintenance_profile_p;
    732 
    733   if (maintenance_profile_p)
    734     {
    735       static int profiling_initialized;
    736 
    737       if (!profiling_initialized)
    738 	{
    739 	  atexit (mcleanup_wrapper);
    740 	  profiling_initialized = 1;
    741 	}
    742 
    743       /* "main" is now always the first function in the text segment, so use
    744 	 its address for monstartup.  */
    745       monstartup ((unsigned long) &main, (unsigned long) TEXTEND);
    746     }
    747   else
    748     {
    749       extern void _mcleanup (void);
    750 
    751       _mcleanup ();
    752     }
    753 }
    754 #else
    755 static void
    756 maintenance_set_profile_cmd (const char *args, int from_tty,
    757 			     struct cmd_list_element *c)
    758 {
    759   error (_("Profiling support is not available on this system."));
    760 }
    761 #endif
    762 
    763 static int n_worker_threads = -1;
    764 
    765 /* Update the thread pool for the desired number of threads.  */
    766 static void
    767 update_thread_pool_size ()
    768 {
    769 #if CXX_STD_THREAD
    770   int n_threads = n_worker_threads;
    771 
    772   if (n_threads < 0)
    773     n_threads = std::thread::hardware_concurrency ();
    774 
    775   gdb::thread_pool::g_thread_pool->set_thread_count (n_threads);
    776 #endif
    777 }
    778 
    779 static void
    780 maintenance_set_worker_threads (const char *args, int from_tty,
    781 				struct cmd_list_element *c)
    782 {
    783   update_thread_pool_size ();
    784 }
    785 
    786 
    787 /* If true, display time usage both at startup and for each command.  */
    789 
    790 static bool per_command_time;
    791 
    792 /* If true, display space usage both at startup and for each command.  */
    793 
    794 static bool per_command_space;
    795 
    796 /* If true, display basic symtab stats for each command.  */
    797 
    798 static bool per_command_symtab;
    799 
    800 /* mt per-command commands.  */
    801 
    802 static struct cmd_list_element *per_command_setlist;
    803 static struct cmd_list_element *per_command_showlist;
    804 
    805 /* Set whether to display time statistics to NEW_VALUE
    806    (non-zero means true).  */
    807 
    808 void
    809 set_per_command_time (int new_value)
    810 {
    811   per_command_time = new_value;
    812 }
    813 
    814 /* Set whether to display space statistics to NEW_VALUE
    815    (non-zero means true).  */
    816 
    817 void
    818 set_per_command_space (int new_value)
    819 {
    820   per_command_space = new_value;
    821 }
    822 
    823 /* Count the number of symtabs and blocks.  */
    824 
    825 static void
    826 count_symtabs_and_blocks (int *nr_symtabs_ptr, int *nr_compunit_symtabs_ptr,
    827 			  int *nr_blocks_ptr)
    828 {
    829   int nr_symtabs = 0;
    830   int nr_compunit_symtabs = 0;
    831   int nr_blocks = 0;
    832 
    833   /* When collecting statistics during startup, this is called before
    834      pretty much anything in gdb has been initialized, and thus
    835      current_program_space may be NULL.  */
    836   if (current_program_space != NULL)
    837     {
    838       for (objfile *o : current_program_space->objfiles ())
    839 	{
    840 	  for (compunit_symtab *cu : o->compunits ())
    841 	    {
    842 	      ++nr_compunit_symtabs;
    843 	      nr_blocks += BLOCKVECTOR_NBLOCKS (COMPUNIT_BLOCKVECTOR (cu));
    844 	      nr_symtabs += std::distance (compunit_filetabs (cu).begin (),
    845 					   compunit_filetabs (cu).end ());
    846 	    }
    847 	}
    848     }
    849 
    850   *nr_symtabs_ptr = nr_symtabs;
    851   *nr_compunit_symtabs_ptr = nr_compunit_symtabs;
    852   *nr_blocks_ptr = nr_blocks;
    853 }
    854 
    855 /* As indicated by display_time and display_space, report GDB's
    856    elapsed time and space usage from the base time and space recorded
    857    in this object.  */
    858 
    859 scoped_command_stats::~scoped_command_stats ()
    860 {
    861   /* Early exit if we're not reporting any stats.  It can be expensive to
    862      compute the pre-command values so don't collect them at all if we're
    863      not reporting stats.  Alas this doesn't work in the startup case because
    864      we don't know yet whether we will be reporting the stats.  For the
    865      startup case collect the data anyway (it should be cheap at this point),
    866      and leave it to the reporter to decide whether to print them.  */
    867   if (m_msg_type
    868       && !per_command_time
    869       && !per_command_space
    870       && !per_command_symtab)
    871     return;
    872 
    873   if (m_time_enabled && per_command_time)
    874     {
    875       print_time (_("command finished"));
    876 
    877       using namespace std::chrono;
    878 
    879       run_time_clock::duration cmd_time
    880 	= run_time_clock::now () - m_start_cpu_time;
    881 
    882       steady_clock::duration wall_time
    883 	= steady_clock::now () - m_start_wall_time;
    884       /* Subtract time spend in prompt_for_continue from walltime.  */
    885       wall_time -= get_prompt_for_continue_wait_time ();
    886 
    887       printf_unfiltered (!m_msg_type
    888 			 ? _("Startup time: %.6f (cpu), %.6f (wall)\n")
    889 			 : _("Command execution time: %.6f (cpu), %.6f (wall)\n"),
    890 			 duration<double> (cmd_time).count (),
    891 			 duration<double> (wall_time).count ());
    892     }
    893 
    894   if (m_space_enabled && per_command_space)
    895     {
    896 #ifdef HAVE_USEFUL_SBRK
    897       char *lim = (char *) sbrk (0);
    898 
    899       long space_now = lim - lim_at_start;
    900       long space_diff = space_now - m_start_space;
    901 
    902       printf_unfiltered (!m_msg_type
    903 			 ? _("Space used: %ld (%s%ld during startup)\n")
    904 			 : _("Space used: %ld (%s%ld for this command)\n"),
    905 			 space_now,
    906 			 (space_diff >= 0 ? "+" : ""),
    907 			 space_diff);
    908 #endif
    909     }
    910 
    911   if (m_symtab_enabled && per_command_symtab)
    912     {
    913       int nr_symtabs, nr_compunit_symtabs, nr_blocks;
    914 
    915       count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
    916       printf_unfiltered (_("#symtabs: %d (+%d),"
    917 			   " #compunits: %d (+%d),"
    918 			   " #blocks: %d (+%d)\n"),
    919 			 nr_symtabs,
    920 			 nr_symtabs - m_start_nr_symtabs,
    921 			 nr_compunit_symtabs,
    922 			 (nr_compunit_symtabs
    923 			  - m_start_nr_compunit_symtabs),
    924 			 nr_blocks,
    925 			 nr_blocks - m_start_nr_blocks);
    926     }
    927 }
    928 
    929 scoped_command_stats::scoped_command_stats (bool msg_type)
    930 : m_msg_type (msg_type)
    931 {
    932   if (!m_msg_type || per_command_space)
    933     {
    934 #ifdef HAVE_USEFUL_SBRK
    935       char *lim = (char *) sbrk (0);
    936       m_start_space = lim - lim_at_start;
    937       m_space_enabled = 1;
    938 #endif
    939     }
    940   else
    941     m_space_enabled = 0;
    942 
    943   if (msg_type == 0 || per_command_time)
    944     {
    945       using namespace std::chrono;
    946 
    947       m_start_cpu_time = run_time_clock::now ();
    948       m_start_wall_time = steady_clock::now ();
    949       m_time_enabled = 1;
    950 
    951       if (per_command_time)
    952 	print_time (_("command started"));
    953     }
    954   else
    955     m_time_enabled = 0;
    956 
    957   if (msg_type == 0 || per_command_symtab)
    958     {
    959       int nr_symtabs, nr_compunit_symtabs, nr_blocks;
    960 
    961       count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
    962       m_start_nr_symtabs = nr_symtabs;
    963       m_start_nr_compunit_symtabs = nr_compunit_symtabs;
    964       m_start_nr_blocks = nr_blocks;
    965       m_symtab_enabled = 1;
    966     }
    967   else
    968     m_symtab_enabled = 0;
    969 
    970   /* Initialize timer to keep track of how long we waited for the user.  */
    971   reset_prompt_for_continue_wait_time ();
    972 }
    973 
    974 /* See maint.h.  */
    975 
    976 void
    977 scoped_command_stats::print_time (const char *msg)
    978 {
    979   using namespace std::chrono;
    980 
    981   auto now = system_clock::now ();
    982   auto ticks = now.time_since_epoch ().count () / (1000 * 1000);
    983   auto millis = ticks % 1000;
    984 
    985   std::time_t as_time = system_clock::to_time_t (now);
    986   struct tm tm;
    987   localtime_r (&as_time, &tm);
    988 
    989   char out[100];
    990   strftime (out, sizeof (out), "%F %H:%M:%S", &tm);
    991 
    992   printf_unfiltered ("%s.%03d - %s\n", out, (int) millis, msg);
    993 }
    994 
    995 /* Handle unknown "mt set per-command" arguments.
    996    In this case have "mt set per-command on|off" affect every setting.  */
    997 
    998 static void
    999 set_per_command_cmd (const char *args, int from_tty)
   1000 {
   1001   struct cmd_list_element *list;
   1002   int val;
   1003 
   1004   val = parse_cli_boolean_value (args);
   1005   if (val < 0)
   1006     error (_("Bad value for 'mt set per-command no'."));
   1007 
   1008   for (list = per_command_setlist; list != NULL; list = list->next)
   1009     if (list->var_type == var_boolean)
   1010       {
   1011 	gdb_assert (list->type == set_cmd);
   1012 	do_set_command (args, from_tty, list);
   1013       }
   1014 }
   1015 
   1016 
   1017 
   1019 /* The "maintenance selftest" command.  */
   1020 
   1021 static void
   1022 maintenance_selftest (const char *args, int from_tty)
   1023 {
   1024 #if GDB_SELF_TEST
   1025   gdb_argv argv (args);
   1026   selftests::run_tests (argv.as_array_view ());
   1027 #else
   1028   printf_filtered (_("\
   1029 Selftests have been disabled for this build.\n"));
   1030 #endif
   1031 }
   1032 
   1033 static void
   1034 maintenance_info_selftests (const char *arg, int from_tty)
   1035 {
   1036 #if GDB_SELF_TEST
   1037   printf_filtered ("Registered selftests:\n");
   1038   selftests::for_each_selftest ([] (const std::string &name) {
   1039     printf_filtered (" - %s\n", name.c_str ());
   1040   });
   1041 #else
   1042   printf_filtered (_("\
   1043 Selftests have been disabled for this build.\n"));
   1044 #endif
   1045 }
   1046 
   1047 
   1048 void _initialize_maint_cmds ();
   1050 void
   1051 _initialize_maint_cmds ()
   1052 {
   1053   struct cmd_list_element *cmd;
   1054 
   1055   add_basic_prefix_cmd ("maintenance", class_maintenance, _("\
   1056 Commands for use by GDB maintainers.\n\
   1057 Includes commands to dump specific internal GDB structures in\n\
   1058 a human readable form, to cause GDB to deliberately dump core, etc."),
   1059 			&maintenancelist, "maintenance ", 0,
   1060 			&cmdlist);
   1061 
   1062   add_com_alias ("mt", "maintenance", class_maintenance, 1);
   1063 
   1064   add_basic_prefix_cmd ("info", class_maintenance, _("\
   1065 Commands for showing internal info about the program being debugged."),
   1066 			&maintenanceinfolist, "maintenance info ", 0,
   1067 			&maintenancelist);
   1068   add_alias_cmd ("i", "info", class_maintenance, 1, &maintenancelist);
   1069 
   1070   add_cmd ("sections", class_maintenance, maintenance_info_sections, _("\
   1071 List the BFD sections of the exec and core files.\n\
   1072 Arguments may be any combination of:\n\
   1073 	[one or more section names]\n\
   1074 	ALLOC LOAD RELOC READONLY CODE DATA ROM CONSTRUCTOR\n\
   1075 	HAS_CONTENTS NEVER_LOAD COFF_SHARED_LIBRARY IS_COMMON\n\
   1076 Sections matching any argument will be listed (no argument\n\
   1077 implies all sections).  In addition, the special argument\n\
   1078 	ALLOBJ\n\
   1079 lists all sections from all object files, including shared libraries."),
   1080 	   &maintenanceinfolist);
   1081 
   1082   add_basic_prefix_cmd ("print", class_maintenance,
   1083 			_("Maintenance command for printing GDB internal state."),
   1084 			&maintenanceprintlist, "maintenance print ", 0,
   1085 			&maintenancelist);
   1086 
   1087   add_basic_prefix_cmd ("set", class_maintenance, _("\
   1088 Set GDB internal variables used by the GDB maintainer.\n\
   1089 Configure variables internal to GDB that aid in GDB's maintenance"),
   1090 			&maintenance_set_cmdlist, "maintenance set ",
   1091 			0/*allow-unknown*/,
   1092 			&maintenancelist);
   1093 
   1094   add_show_prefix_cmd ("show", class_maintenance, _("\
   1095 Show GDB internal variables used by the GDB maintainer.\n\
   1096 Configure variables internal to GDB that aid in GDB's maintenance"),
   1097 		       &maintenance_show_cmdlist, "maintenance show ",
   1098 		       0/*allow-unknown*/,
   1099 		       &maintenancelist);
   1100 
   1101   cmd = add_cmd ("with", class_maintenance, maintenance_with_cmd, _("\
   1102 Like \"with\", but works with \"maintenance set\" variables.\n\
   1103 Usage: maintenance with SETTING [VALUE] [-- COMMAND]\n\
   1104 With no COMMAND, repeats the last executed command.\n\
   1105 SETTING is any setting you can change with the \"maintenance set\"\n\
   1106 subcommands."),
   1107 		 &maintenancelist);
   1108   set_cmd_completer_handle_brkchars (cmd, maintenance_with_cmd_completer);
   1109 
   1110 #ifndef _WIN32
   1111   add_cmd ("dump-me", class_maintenance, maintenance_dump_me, _("\
   1112 Get fatal error; make debugger dump its core.\n\
   1113 GDB sets its handling of SIGQUIT back to SIG_DFL and then sends\n\
   1114 itself a SIGQUIT signal."),
   1115 	   &maintenancelist);
   1116 #endif
   1117 
   1118   add_cmd ("internal-error", class_maintenance,
   1119 	   maintenance_internal_error, _("\
   1120 Give GDB an internal error.\n\
   1121 Cause GDB to behave as if an internal error was detected."),
   1122 	   &maintenancelist);
   1123 
   1124   add_cmd ("internal-warning", class_maintenance,
   1125 	   maintenance_internal_warning, _("\
   1126 Give GDB an internal warning.\n\
   1127 Cause GDB to behave as if an internal warning was reported."),
   1128 	   &maintenancelist);
   1129 
   1130   add_cmd ("demangler-warning", class_maintenance,
   1131 	   maintenance_demangler_warning, _("\
   1132 Give GDB a demangler warning.\n\
   1133 Cause GDB to behave as if a demangler warning was reported."),
   1134 	   &maintenancelist);
   1135 
   1136   cmd = add_cmd ("demangle", class_maintenance, maintenance_demangle, _("\
   1137 This command has been moved to \"demangle\"."),
   1138 		 &maintenancelist);
   1139   deprecate_cmd (cmd, "demangle");
   1140 
   1141   add_prefix_cmd ("per-command", class_maintenance, set_per_command_cmd, _("\
   1142 Per-command statistics settings."),
   1143 		    &per_command_setlist, "maintenance set per-command ",
   1144 		    1/*allow-unknown*/, &maintenance_set_cmdlist);
   1145 
   1146   add_show_prefix_cmd ("per-command", class_maintenance, _("\
   1147 Show per-command statistics settings."),
   1148 		       &per_command_showlist, "maintenance show per-command ",
   1149 		       0/*allow-unknown*/, &maintenance_show_cmdlist);
   1150 
   1151   add_setshow_boolean_cmd ("time", class_maintenance,
   1152 			   &per_command_time, _("\
   1153 Set whether to display per-command execution time."), _("\
   1154 Show whether to display per-command execution time."),
   1155 			   _("\
   1156 If enabled, the execution time for each command will be\n\
   1157 displayed following the command's output."),
   1158 			   NULL, NULL,
   1159 			   &per_command_setlist, &per_command_showlist);
   1160 
   1161   add_setshow_boolean_cmd ("space", class_maintenance,
   1162 			   &per_command_space, _("\
   1163 Set whether to display per-command space usage."), _("\
   1164 Show whether to display per-command space usage."),
   1165 			   _("\
   1166 If enabled, the space usage for each command will be\n\
   1167 displayed following the command's output."),
   1168 			   NULL, NULL,
   1169 			   &per_command_setlist, &per_command_showlist);
   1170 
   1171   add_setshow_boolean_cmd ("symtab", class_maintenance,
   1172 			   &per_command_symtab, _("\
   1173 Set whether to display per-command symtab statistics."), _("\
   1174 Show whether to display per-command symtab statistics."),
   1175 			   _("\
   1176 If enabled, the basic symtab statistics for each command will be\n\
   1177 displayed following the command's output."),
   1178 			   NULL, NULL,
   1179 			   &per_command_setlist, &per_command_showlist);
   1180 
   1181   /* This is equivalent to "mt set per-command time on".
   1182      Kept because some people are used to typing "mt time 1".  */
   1183   add_cmd ("time", class_maintenance, maintenance_time_display, _("\
   1184 Set the display of time usage.\n\
   1185 If nonzero, will cause the execution time for each command to be\n\
   1186 displayed, following the command's output."),
   1187 	   &maintenancelist);
   1188 
   1189   /* This is equivalent to "mt set per-command space on".
   1190      Kept because some people are used to typing "mt space 1".  */
   1191   add_cmd ("space", class_maintenance, maintenance_space_display, _("\
   1192 Set the display of space usage.\n\
   1193 If nonzero, will cause the execution space for each command to be\n\
   1194 displayed, following the command's output."),
   1195 	   &maintenancelist);
   1196 
   1197   add_cmd ("type", class_maintenance, maintenance_print_type, _("\
   1198 Print a type chain for a given symbol.\n\
   1199 For each node in a type chain, print the raw data for each member of\n\
   1200 the type structure, and the interpretation of the data."),
   1201 	   &maintenanceprintlist);
   1202 
   1203   add_cmd ("statistics", class_maintenance, maintenance_print_statistics,
   1204 	   _("Print statistics about internal gdb state."),
   1205 	   &maintenanceprintlist);
   1206 
   1207   add_cmd ("architecture", class_maintenance,
   1208 	   maintenance_print_architecture, _("\
   1209 Print the internal architecture configuration.\n\
   1210 Takes an optional file parameter."),
   1211 	   &maintenanceprintlist);
   1212 
   1213   add_basic_prefix_cmd ("check", class_maintenance, _("\
   1214 Commands for checking internal gdb state."),
   1215 			&maintenancechecklist, "maintenance check ", 0,
   1216 			&maintenancelist);
   1217 
   1218   add_cmd ("translate-address", class_maintenance,
   1219 	   maintenance_translate_address,
   1220 	   _("Translate a section name and address to a symbol."),
   1221 	   &maintenancelist);
   1222 
   1223   add_cmd ("deprecate", class_maintenance, maintenance_deprecate, _("\
   1224 Deprecate a command (for testing purposes).\n\
   1225 Usage: maintenance deprecate COMMANDNAME [\"REPLACEMENT\"]\n\
   1226 This is used by the testsuite to check the command deprecator.\n\
   1227 You probably shouldn't use this,\n\
   1228 rather you should use the C function deprecate_cmd()."), &maintenancelist);
   1229 
   1230   add_cmd ("undeprecate", class_maintenance, maintenance_undeprecate, _("\
   1231 Undeprecate a command (for testing purposes).\n\
   1232 Usage: maintenance undeprecate COMMANDNAME\n\
   1233 This is used by the testsuite to check the command deprecator.\n\
   1234 You probably shouldn't use this."),
   1235 	   &maintenancelist);
   1236 
   1237   add_cmd ("selftest", class_maintenance, maintenance_selftest, _("\
   1238 Run gdb's unit tests.\n\
   1239 Usage: maintenance selftest [FILTER]\n\
   1240 This will run any unit tests that were built in to gdb.\n\
   1241 If a filter is given, only the tests with that value in their name will ran."),
   1242 	   &maintenancelist);
   1243 
   1244   add_cmd ("selftests", class_maintenance, maintenance_info_selftests,
   1245 	 _("List the registered selftests."), &maintenanceinfolist);
   1246 
   1247   add_setshow_boolean_cmd ("profile", class_maintenance,
   1248 			   &maintenance_profile_p, _("\
   1249 Set internal profiling."), _("\
   1250 Show internal profiling."), _("\
   1251 When enabled GDB is profiled."),
   1252 			   maintenance_set_profile_cmd,
   1253 			   show_maintenance_profile_p,
   1254 			   &maintenance_set_cmdlist,
   1255 			   &maintenance_show_cmdlist);
   1256 
   1257   add_setshow_zuinteger_unlimited_cmd ("worker-threads",
   1258 				       class_maintenance,
   1259 				       &n_worker_threads, _("\
   1260 Set the number of worker threads GDB can use."), _("\
   1261 Show the number of worker threads GDB can use."), _("\
   1262 GDB may use multiple threads to speed up certain CPU-intensive operations,\n\
   1263 such as demangling symbol names."),
   1264 				       maintenance_set_worker_threads, NULL,
   1265 				       &maintenance_set_cmdlist,
   1266 				       &maintenance_show_cmdlist);
   1267 
   1268   update_thread_pool_size ();
   1269 }
   1270