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