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