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
53static void maintenance_do_deprecate (const char *, int);
54
55#ifndef _WIN32
56static void
57maintenance_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
78static void
79maintenance_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
89static void
90maintenance_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
98static void
99maintenance_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
108static void
109maintenance_demangle (const char *args, int from_tty)
110{
111  printf_filtered (_("This command has been moved to \"demangle\".\n"));
112}
113
114static void
115maintenance_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
123static void
124maintenance_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
134static int
135match_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
162static int
163match_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
205static void
206print_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
234static void
235maint_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
253static int
254index_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
263static void
264print_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
282static void
283print_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
313static void
314print_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
340static obj_section *
341maint_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
363static void
364print_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
380static void
381maintenance_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
433static void
434maintenance_print_statistics (const char *args, int from_tty)
435{
436  print_objfile_statistics ();
437  print_symbol_bcache_statistics ();
438}
439
440static void
441maintenance_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
462static void
463maintenance_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
547static void
548maintenance_deprecate (const char *args, int from_tty)
549{
550  if (args == NULL || *args == '\0')
551    {
552      printf_unfiltered (_("\"maintenance deprecate\" takes an argument,\n\
553the command you want to deprecate, and optionally the replacement command\n\
554enclosed in quotes.\n"));
555    }
556
557  maintenance_do_deprecate (args, 1);
558}
559
560
561static void
562maintenance_undeprecate (const char *args, int from_tty)
563{
564  if (args == NULL || *args == '\0')
565    {
566      printf_unfiltered (_("\"maintenance undeprecate\" takes an argument, \n\
567the 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
580static void
581maintenance_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
669struct cmd_list_element *maintenance_set_cmdlist;
670struct cmd_list_element *maintenance_show_cmdlist;
671
672/* "maintenance with" command.  */
673
674static void
675maintenance_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
682static void
683maintenance_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
692static bool maintenance_profile_p;
693static void
694show_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
701extern char _etext;
702#define TEXTEND &_etext
703#elif defined (HAVE_ETEXT)
704extern char etext;
705#define TEXTEND &etext
706#endif
707
708#if defined (HAVE_MONSTARTUP) && defined (HAVE__MCLEANUP) && defined (TEXTEND)
709
710static int profiling_state;
711
712EXTERN_C void _mcleanup (void);
713
714static void
715mcleanup_wrapper (void)
716{
717  if (profiling_state)
718    _mcleanup ();
719}
720
721EXTERN_C void monstartup (unsigned long, unsigned long);
722extern int main ();
723
724static void
725maintenance_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
755static void
756maintenance_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
763static int n_worker_threads = -1;
764
765/* Update the thread pool for the desired number of threads.  */
766static void
767update_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
779static void
780maintenance_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.  */
788
789static bool per_command_time;
790
791/* If true, display space usage both at startup and for each command.  */
792
793static bool per_command_space;
794
795/* If true, display basic symtab stats for each command.  */
796
797static bool per_command_symtab;
798
799/* mt per-command commands.  */
800
801static struct cmd_list_element *per_command_setlist;
802static struct cmd_list_element *per_command_showlist;
803
804/* Set whether to display time statistics to NEW_VALUE
805   (non-zero means true).  */
806
807void
808set_per_command_time (int new_value)
809{
810  per_command_time = new_value;
811}
812
813/* Set whether to display space statistics to NEW_VALUE
814   (non-zero means true).  */
815
816void
817set_per_command_space (int new_value)
818{
819  per_command_space = new_value;
820}
821
822/* Count the number of symtabs and blocks.  */
823
824static void
825count_symtabs_and_blocks (int *nr_symtabs_ptr, int *nr_compunit_symtabs_ptr,
826			  int *nr_blocks_ptr)
827{
828  int nr_symtabs = 0;
829  int nr_compunit_symtabs = 0;
830  int nr_blocks = 0;
831
832  /* When collecting statistics during startup, this is called before
833     pretty much anything in gdb has been initialized, and thus
834     current_program_space may be NULL.  */
835  if (current_program_space != NULL)
836    {
837      for (objfile *o : current_program_space->objfiles ())
838	{
839	  for (compunit_symtab *cu : o->compunits ())
840	    {
841	      ++nr_compunit_symtabs;
842	      nr_blocks += BLOCKVECTOR_NBLOCKS (COMPUNIT_BLOCKVECTOR (cu));
843	      nr_symtabs += std::distance (compunit_filetabs (cu).begin (),
844					   compunit_filetabs (cu).end ());
845	    }
846	}
847    }
848
849  *nr_symtabs_ptr = nr_symtabs;
850  *nr_compunit_symtabs_ptr = nr_compunit_symtabs;
851  *nr_blocks_ptr = nr_blocks;
852}
853
854/* As indicated by display_time and display_space, report GDB's
855   elapsed time and space usage from the base time and space recorded
856   in this object.  */
857
858scoped_command_stats::~scoped_command_stats ()
859{
860  /* Early exit if we're not reporting any stats.  It can be expensive to
861     compute the pre-command values so don't collect them at all if we're
862     not reporting stats.  Alas this doesn't work in the startup case because
863     we don't know yet whether we will be reporting the stats.  For the
864     startup case collect the data anyway (it should be cheap at this point),
865     and leave it to the reporter to decide whether to print them.  */
866  if (m_msg_type
867      && !per_command_time
868      && !per_command_space
869      && !per_command_symtab)
870    return;
871
872  if (m_time_enabled && per_command_time)
873    {
874      print_time (_("command finished"));
875
876      using namespace std::chrono;
877
878      run_time_clock::duration cmd_time
879	= run_time_clock::now () - m_start_cpu_time;
880
881      steady_clock::duration wall_time
882	= steady_clock::now () - m_start_wall_time;
883      /* Subtract time spend in prompt_for_continue from walltime.  */
884      wall_time -= get_prompt_for_continue_wait_time ();
885
886      printf_unfiltered (!m_msg_type
887			 ? _("Startup time: %.6f (cpu), %.6f (wall)\n")
888			 : _("Command execution time: %.6f (cpu), %.6f (wall)\n"),
889			 duration<double> (cmd_time).count (),
890			 duration<double> (wall_time).count ());
891    }
892
893  if (m_space_enabled && per_command_space)
894    {
895#ifdef HAVE_USEFUL_SBRK
896      char *lim = (char *) sbrk (0);
897
898      long space_now = lim - lim_at_start;
899      long space_diff = space_now - m_start_space;
900
901      printf_unfiltered (!m_msg_type
902			 ? _("Space used: %ld (%s%ld during startup)\n")
903			 : _("Space used: %ld (%s%ld for this command)\n"),
904			 space_now,
905			 (space_diff >= 0 ? "+" : ""),
906			 space_diff);
907#endif
908    }
909
910  if (m_symtab_enabled && per_command_symtab)
911    {
912      int nr_symtabs, nr_compunit_symtabs, nr_blocks;
913
914      count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
915      printf_unfiltered (_("#symtabs: %d (+%d),"
916			   " #compunits: %d (+%d),"
917			   " #blocks: %d (+%d)\n"),
918			 nr_symtabs,
919			 nr_symtabs - m_start_nr_symtabs,
920			 nr_compunit_symtabs,
921			 (nr_compunit_symtabs
922			  - m_start_nr_compunit_symtabs),
923			 nr_blocks,
924			 nr_blocks - m_start_nr_blocks);
925    }
926}
927
928scoped_command_stats::scoped_command_stats (bool msg_type)
929: m_msg_type (msg_type)
930{
931  if (!m_msg_type || per_command_space)
932    {
933#ifdef HAVE_USEFUL_SBRK
934      char *lim = (char *) sbrk (0);
935      m_start_space = lim - lim_at_start;
936      m_space_enabled = 1;
937#endif
938    }
939  else
940    m_space_enabled = 0;
941
942  if (msg_type == 0 || per_command_time)
943    {
944      using namespace std::chrono;
945
946      m_start_cpu_time = run_time_clock::now ();
947      m_start_wall_time = steady_clock::now ();
948      m_time_enabled = 1;
949
950      if (per_command_time)
951	print_time (_("command started"));
952    }
953  else
954    m_time_enabled = 0;
955
956  if (msg_type == 0 || per_command_symtab)
957    {
958      int nr_symtabs, nr_compunit_symtabs, nr_blocks;
959
960      count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
961      m_start_nr_symtabs = nr_symtabs;
962      m_start_nr_compunit_symtabs = nr_compunit_symtabs;
963      m_start_nr_blocks = nr_blocks;
964      m_symtab_enabled = 1;
965    }
966  else
967    m_symtab_enabled = 0;
968
969  /* Initialize timer to keep track of how long we waited for the user.  */
970  reset_prompt_for_continue_wait_time ();
971}
972
973/* See maint.h.  */
974
975void
976scoped_command_stats::print_time (const char *msg)
977{
978  using namespace std::chrono;
979
980  auto now = system_clock::now ();
981  auto ticks = now.time_since_epoch ().count () / (1000 * 1000);
982  auto millis = ticks % 1000;
983
984  std::time_t as_time = system_clock::to_time_t (now);
985  struct tm tm;
986  localtime_r (&as_time, &tm);
987
988  char out[100];
989  strftime (out, sizeof (out), "%F %H:%M:%S", &tm);
990
991  printf_unfiltered ("%s.%03d - %s\n", out, (int) millis, msg);
992}
993
994/* Handle unknown "mt set per-command" arguments.
995   In this case have "mt set per-command on|off" affect every setting.  */
996
997static void
998set_per_command_cmd (const char *args, int from_tty)
999{
1000  struct cmd_list_element *list;
1001  int val;
1002
1003  val = parse_cli_boolean_value (args);
1004  if (val < 0)
1005    error (_("Bad value for 'mt set per-command no'."));
1006
1007  for (list = per_command_setlist; list != NULL; list = list->next)
1008    if (list->var_type == var_boolean)
1009      {
1010	gdb_assert (list->type == set_cmd);
1011	do_set_command (args, from_tty, list);
1012      }
1013}
1014
1015
1016
1017/* The "maintenance selftest" command.  */
1018
1019static void
1020maintenance_selftest (const char *args, int from_tty)
1021{
1022#if GDB_SELF_TEST
1023  gdb_argv argv (args);
1024  selftests::run_tests (argv.as_array_view ());
1025#else
1026  printf_filtered (_("\
1027Selftests have been disabled for this build.\n"));
1028#endif
1029}
1030
1031static void
1032maintenance_info_selftests (const char *arg, int from_tty)
1033{
1034#if GDB_SELF_TEST
1035  printf_filtered ("Registered selftests:\n");
1036  selftests::for_each_selftest ([] (const std::string &name) {
1037    printf_filtered (" - %s\n", name.c_str ());
1038  });
1039#else
1040  printf_filtered (_("\
1041Selftests have been disabled for this build.\n"));
1042#endif
1043}
1044
1045
1046void _initialize_maint_cmds ();
1047void
1048_initialize_maint_cmds ()
1049{
1050  struct cmd_list_element *cmd;
1051
1052  add_basic_prefix_cmd ("maintenance", class_maintenance, _("\
1053Commands for use by GDB maintainers.\n\
1054Includes commands to dump specific internal GDB structures in\n\
1055a human readable form, to cause GDB to deliberately dump core, etc."),
1056			&maintenancelist, "maintenance ", 0,
1057			&cmdlist);
1058
1059  add_com_alias ("mt", "maintenance", class_maintenance, 1);
1060
1061  add_basic_prefix_cmd ("info", class_maintenance, _("\
1062Commands for showing internal info about the program being debugged."),
1063			&maintenanceinfolist, "maintenance info ", 0,
1064			&maintenancelist);
1065  add_alias_cmd ("i", "info", class_maintenance, 1, &maintenancelist);
1066
1067  add_cmd ("sections", class_maintenance, maintenance_info_sections, _("\
1068List the BFD sections of the exec and core files.\n\
1069Arguments may be any combination of:\n\
1070	[one or more section names]\n\
1071	ALLOC LOAD RELOC READONLY CODE DATA ROM CONSTRUCTOR\n\
1072	HAS_CONTENTS NEVER_LOAD COFF_SHARED_LIBRARY IS_COMMON\n\
1073Sections matching any argument will be listed (no argument\n\
1074implies all sections).  In addition, the special argument\n\
1075	ALLOBJ\n\
1076lists all sections from all object files, including shared libraries."),
1077	   &maintenanceinfolist);
1078
1079  add_basic_prefix_cmd ("print", class_maintenance,
1080			_("Maintenance command for printing GDB internal state."),
1081			&maintenanceprintlist, "maintenance print ", 0,
1082			&maintenancelist);
1083
1084  add_basic_prefix_cmd ("set", class_maintenance, _("\
1085Set GDB internal variables used by the GDB maintainer.\n\
1086Configure variables internal to GDB that aid in GDB's maintenance"),
1087			&maintenance_set_cmdlist, "maintenance set ",
1088			0/*allow-unknown*/,
1089			&maintenancelist);
1090
1091  add_show_prefix_cmd ("show", class_maintenance, _("\
1092Show GDB internal variables used by the GDB maintainer.\n\
1093Configure variables internal to GDB that aid in GDB's maintenance"),
1094		       &maintenance_show_cmdlist, "maintenance show ",
1095		       0/*allow-unknown*/,
1096		       &maintenancelist);
1097
1098  cmd = add_cmd ("with", class_maintenance, maintenance_with_cmd, _("\
1099Like \"with\", but works with \"maintenance set\" variables.\n\
1100Usage: maintenance with SETTING [VALUE] [-- COMMAND]\n\
1101With no COMMAND, repeats the last executed command.\n\
1102SETTING is any setting you can change with the \"maintenance set\"\n\
1103subcommands."),
1104		 &maintenancelist);
1105  set_cmd_completer_handle_brkchars (cmd, maintenance_with_cmd_completer);
1106
1107#ifndef _WIN32
1108  add_cmd ("dump-me", class_maintenance, maintenance_dump_me, _("\
1109Get fatal error; make debugger dump its core.\n\
1110GDB sets its handling of SIGQUIT back to SIG_DFL and then sends\n\
1111itself a SIGQUIT signal."),
1112	   &maintenancelist);
1113#endif
1114
1115  add_cmd ("internal-error", class_maintenance,
1116	   maintenance_internal_error, _("\
1117Give GDB an internal error.\n\
1118Cause GDB to behave as if an internal error was detected."),
1119	   &maintenancelist);
1120
1121  add_cmd ("internal-warning", class_maintenance,
1122	   maintenance_internal_warning, _("\
1123Give GDB an internal warning.\n\
1124Cause GDB to behave as if an internal warning was reported."),
1125	   &maintenancelist);
1126
1127  add_cmd ("demangler-warning", class_maintenance,
1128	   maintenance_demangler_warning, _("\
1129Give GDB a demangler warning.\n\
1130Cause GDB to behave as if a demangler warning was reported."),
1131	   &maintenancelist);
1132
1133  cmd = add_cmd ("demangle", class_maintenance, maintenance_demangle, _("\
1134This command has been moved to \"demangle\"."),
1135		 &maintenancelist);
1136  deprecate_cmd (cmd, "demangle");
1137
1138  add_prefix_cmd ("per-command", class_maintenance, set_per_command_cmd, _("\
1139Per-command statistics settings."),
1140		    &per_command_setlist, "maintenance set per-command ",
1141		    1/*allow-unknown*/, &maintenance_set_cmdlist);
1142
1143  add_show_prefix_cmd ("per-command", class_maintenance, _("\
1144Show per-command statistics settings."),
1145		       &per_command_showlist, "maintenance show per-command ",
1146		       0/*allow-unknown*/, &maintenance_show_cmdlist);
1147
1148  add_setshow_boolean_cmd ("time", class_maintenance,
1149			   &per_command_time, _("\
1150Set whether to display per-command execution time."), _("\
1151Show whether to display per-command execution time."),
1152			   _("\
1153If enabled, the execution time for each command will be\n\
1154displayed following the command's output."),
1155			   NULL, NULL,
1156			   &per_command_setlist, &per_command_showlist);
1157
1158  add_setshow_boolean_cmd ("space", class_maintenance,
1159			   &per_command_space, _("\
1160Set whether to display per-command space usage."), _("\
1161Show whether to display per-command space usage."),
1162			   _("\
1163If enabled, the space usage for each command will be\n\
1164displayed following the command's output."),
1165			   NULL, NULL,
1166			   &per_command_setlist, &per_command_showlist);
1167
1168  add_setshow_boolean_cmd ("symtab", class_maintenance,
1169			   &per_command_symtab, _("\
1170Set whether to display per-command symtab statistics."), _("\
1171Show whether to display per-command symtab statistics."),
1172			   _("\
1173If enabled, the basic symtab statistics for each command will be\n\
1174displayed following the command's output."),
1175			   NULL, NULL,
1176			   &per_command_setlist, &per_command_showlist);
1177
1178  /* This is equivalent to "mt set per-command time on".
1179     Kept because some people are used to typing "mt time 1".  */
1180  add_cmd ("time", class_maintenance, maintenance_time_display, _("\
1181Set the display of time usage.\n\
1182If nonzero, will cause the execution time for each command to be\n\
1183displayed, following the command's output."),
1184	   &maintenancelist);
1185
1186  /* This is equivalent to "mt set per-command space on".
1187     Kept because some people are used to typing "mt space 1".  */
1188  add_cmd ("space", class_maintenance, maintenance_space_display, _("\
1189Set the display of space usage.\n\
1190If nonzero, will cause the execution space for each command to be\n\
1191displayed, following the command's output."),
1192	   &maintenancelist);
1193
1194  add_cmd ("type", class_maintenance, maintenance_print_type, _("\
1195Print a type chain for a given symbol.\n\
1196For each node in a type chain, print the raw data for each member of\n\
1197the type structure, and the interpretation of the data."),
1198	   &maintenanceprintlist);
1199
1200  add_cmd ("statistics", class_maintenance, maintenance_print_statistics,
1201	   _("Print statistics about internal gdb state."),
1202	   &maintenanceprintlist);
1203
1204  add_cmd ("architecture", class_maintenance,
1205	   maintenance_print_architecture, _("\
1206Print the internal architecture configuration.\n\
1207Takes an optional file parameter."),
1208	   &maintenanceprintlist);
1209
1210  add_basic_prefix_cmd ("check", class_maintenance, _("\
1211Commands for checking internal gdb state."),
1212			&maintenancechecklist, "maintenance check ", 0,
1213			&maintenancelist);
1214
1215  add_cmd ("translate-address", class_maintenance,
1216	   maintenance_translate_address,
1217	   _("Translate a section name and address to a symbol."),
1218	   &maintenancelist);
1219
1220  add_cmd ("deprecate", class_maintenance, maintenance_deprecate, _("\
1221Deprecate a command (for testing purposes).\n\
1222Usage: maintenance deprecate COMMANDNAME [\"REPLACEMENT\"]\n\
1223This is used by the testsuite to check the command deprecator.\n\
1224You probably shouldn't use this,\n\
1225rather you should use the C function deprecate_cmd()."), &maintenancelist);
1226
1227  add_cmd ("undeprecate", class_maintenance, maintenance_undeprecate, _("\
1228Undeprecate a command (for testing purposes).\n\
1229Usage: maintenance undeprecate COMMANDNAME\n\
1230This is used by the testsuite to check the command deprecator.\n\
1231You probably shouldn't use this."),
1232	   &maintenancelist);
1233
1234  add_cmd ("selftest", class_maintenance, maintenance_selftest, _("\
1235Run gdb's unit tests.\n\
1236Usage: maintenance selftest [FILTER]\n\
1237This will run any unit tests that were built in to gdb.\n\
1238If a filter is given, only the tests with that value in their name will ran."),
1239	   &maintenancelist);
1240
1241  add_cmd ("selftests", class_maintenance, maintenance_info_selftests,
1242	 _("List the registered selftests."), &maintenanceinfolist);
1243
1244  add_setshow_boolean_cmd ("profile", class_maintenance,
1245			   &maintenance_profile_p, _("\
1246Set internal profiling."), _("\
1247Show internal profiling."), _("\
1248When enabled GDB is profiled."),
1249			   maintenance_set_profile_cmd,
1250			   show_maintenance_profile_p,
1251			   &maintenance_set_cmdlist,
1252			   &maintenance_show_cmdlist);
1253
1254  add_setshow_zuinteger_unlimited_cmd ("worker-threads",
1255				       class_maintenance,
1256				       &n_worker_threads, _("\
1257Set the number of worker threads GDB can use."), _("\
1258Show the number of worker threads GDB can use."), _("\
1259GDB may use multiple threads to speed up certain CPU-intensive operations,\n\
1260such as demangling symbol names."),
1261				       maintenance_set_worker_threads, NULL,
1262				       &maintenance_set_cmdlist,
1263				       &maintenance_show_cmdlist);
1264
1265  update_thread_pool_size ();
1266}
1267