/* Support for GDB maintenance commands.
- Copyright (C) 1992-2021 Free Software Foundation, Inc.
+ Copyright (C) 1992-2022 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support.
#include "maint.h"
#include "gdbsupport/selftest.h"
#include "inferior.h"
+#include "gdbsupport/thread-pool.h"
#include "cli/cli-decode.h"
#include "cli/cli-utils.h"
#include "cli/cli-setshow.h"
#include "cli/cli-cmds.h"
-#if CXX_STD_THREAD
-#include "gdbsupport/thread-pool.h"
-#endif
-
static void maintenance_do_deprecate (const char *, int);
#ifndef _WIN32
static void
maintenance_demangle (const char *args, int from_tty)
{
- printf_filtered (_("This command has been moved to \"demangle\".\n"));
+ gdb_printf (_("This command has been moved to \"demangle\".\n"));
}
static void
maintenance_time_display (const char *args, int from_tty)
{
if (args == NULL || *args == '\0')
- printf_unfiltered (_("\"maintenance time\" takes a numeric argument.\n"));
+ gdb_printf (_("\"maintenance time\" takes a numeric argument.\n"));
else
set_per_command_time (strtol (args, NULL, 10));
}
maintenance_space_display (const char *args, int from_tty)
{
if (args == NULL || *args == '\0')
- printf_unfiltered ("\"maintenance space\" takes a numeric argument.\n");
+ gdb_printf ("\"maintenance space\" takes a numeric argument.\n");
else
set_per_command_space (strtol (args, NULL, 10));
}
for (const auto &f : bfd_flag_info)
{
if (flags & f.value)
- printf_filtered (" %s", f.name);
+ gdb_printf (" %s", f.name);
}
}
CORE_ADDR addr, CORE_ADDR endaddr,
unsigned long filepos, int addr_size)
{
- printf_filtered (" %s", hex_string_custom (addr, addr_size));
- printf_filtered ("->%s", hex_string_custom (endaddr, addr_size));
- printf_filtered (" at %s",
- hex_string_custom ((unsigned long) filepos, 8));
- printf_filtered (": %s", name);
+ gdb_printf (" %s", hex_string_custom (addr, addr_size));
+ gdb_printf ("->%s", hex_string_custom (endaddr, addr_size));
+ gdb_printf (" at %s",
+ hex_string_custom ((unsigned long) filepos, 8));
+ gdb_printf (": %s", name);
print_bfd_flags (flags);
- printf_filtered ("\n");
+ gdb_printf ("\n");
}
/* Return the number of digits required to display COUNT in decimal.
std::string result
= string_printf (" [%d] ", gdb_bfd_section_index (abfd, asect));
/* The '+ 4' for the leading and trailing characters. */
- printf_filtered ("%-*s", (index_digits + 4), result.c_str ());
+ gdb_printf ("%-*s", (index_digits + 4), result.c_str ());
}
/* Print information about ASECT from ABFD. The section will be printed using
from ABFD. It might be that no such wrapper exists (for example debug
sections don't have such wrappers) in which case nullptr is returned. */
-static obj_section *
+obj_section *
maint_obj_section_from_bfd_section (bfd *abfd,
asection *asection,
objfile *ofile)
maint_print_all_sections (const char *header, bfd *abfd, objfile *objfile,
const char *arg)
{
- puts_filtered (header);
- wrap_here (" ");
- printf_filtered ("`%s', ", bfd_get_filename (abfd));
- wrap_here (" ");
- printf_filtered (_("file type %s.\n"), bfd_get_target (abfd));
+ gdb_puts (header);
+ gdb_stdout->wrap_here (8);
+ gdb_printf ("`%s', ", bfd_get_filename (abfd));
+ gdb_stdout->wrap_here (8);
+ gdb_printf (_("file type %s.\n"), bfd_get_target (abfd));
int section_count = gdb_bfd_count_sections (abfd);
int digits = index_digits (section_count);
gdbarch = gdbarch_from_bfd (abfd);
addr_size = gdbarch_addr_bit (gdbarch) / 8;
- printf_filtered (_("From '%s', file type %s:\n"),
- bfd_get_filename (abfd), bfd_get_target (abfd));
+ gdb_printf (_("From '%s', file type %s:\n"),
+ bfd_get_filename (abfd), bfd_get_target (abfd));
}
print_bfd_section_info (abfd,
sec.the_bfd_section,
digits);
/* The magic '8 + digits' here ensures that the 'Start' is aligned
with the output of print_bfd_section_info. */
- printf_filtered ("%*sStart: %s, End: %s, Owner token: %p\n",
- (8 + digits), "",
- hex_string_custom (sec.addr, addr_size),
- hex_string_custom (sec.endaddr, addr_size),
- sec.owner);
+ gdb_printf ("%*sStart: %s, End: %s, Owner token: %p\n",
+ (8 + digits), "",
+ hex_string_custom (sec.addr, addr_size),
+ hex_string_custom (sec.endaddr, addr_size),
+ sec.owner);
}
}
{
const char *symbol_name = sym.minsym->print_name ();
const char *symbol_offset
- = pulongest (address - BMSYMBOL_VALUE_ADDRESS (sym));
+ = pulongest (address - sym.value_address ());
sect = sym.obj_section ();
if (sect != NULL)
obj_name = objfile_name (sect->objfile);
if (current_program_space->multi_objfile_p ())
- printf_filtered (_("%s + %s in section %s of %s\n"),
- symbol_name, symbol_offset,
- section_name, obj_name);
+ gdb_printf (_("%s + %s in section %s of %s\n"),
+ symbol_name, symbol_offset,
+ section_name, obj_name);
else
- printf_filtered (_("%s + %s in section %s\n"),
- symbol_name, symbol_offset, section_name);
+ gdb_printf (_("%s + %s in section %s\n"),
+ symbol_name, symbol_offset, section_name);
}
else
- printf_filtered (_("%s + %s\n"), symbol_name, symbol_offset);
+ gdb_printf (_("%s + %s\n"), symbol_name, symbol_offset);
}
else if (sect)
- printf_filtered (_("no symbol at %s:%s\n"),
- sect->the_bfd_section->name, hex_string (address));
+ gdb_printf (_("no symbol at %s:%s\n"),
+ sect->the_bfd_section->name, hex_string (address));
else
- printf_filtered (_("no symbol at %s\n"), hex_string (address));
+ gdb_printf (_("no symbol at %s\n"), hex_string (address));
return;
}
{
if (args == NULL || *args == '\0')
{
- printf_unfiltered (_("\"maintenance deprecate\" takes an argument,\n\
+ gdb_printf (_("\"maintenance deprecate\" takes an argument,\n\
the command you want to deprecate, and optionally the replacement command\n\
enclosed in quotes.\n"));
}
{
if (args == NULL || *args == '\0')
{
- printf_unfiltered (_("\"maintenance undeprecate\" takes an argument, \n\
+ gdb_printf (_("\"maintenance undeprecate\" takes an argument, \n\
the command you want to undeprecate.\n"));
}
if (!lookup_cmd_composition (text, &alias, &prefix_cmd, &cmd))
{
- printf_filtered (_("Can't find command '%s' to deprecate.\n"), text);
+ gdb_printf (_("Can't find command '%s' to deprecate.\n"), text);
return;
}
show_maintenance_profile_p (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- fprintf_filtered (file, _("Internal profiling is %s.\n"), value);
+ gdb_printf (file, _("Internal profiling is %s.\n"), value);
}
#ifdef HAVE__ETEXT
}
EXTERN_C void monstartup (unsigned long, unsigned long);
-extern int main ();
+extern int main (int, char **);
static void
maintenance_set_profile_cmd (const char *args, int from_tty,
struct cmd_list_element *c,
const char *value)
{
+#if CXX_STD_THREAD
if (n_worker_threads == -1)
- fprintf_filtered (file, _("The number of worker threads GDB "
- "can use is unlimited (currently %zu).\n"),
- gdb::thread_pool::g_thread_pool->thread_count ());
- else
- fprintf_filtered (file, _("The number of worker threads GDB "
- "can use is %d.\n"),
- n_worker_threads);
+ {
+ gdb_printf (file, _("The number of worker threads GDB "
+ "can use is unlimited (currently %zu).\n"),
+ gdb::thread_pool::g_thread_pool->thread_count ());
+ return;
+ }
+#endif
+
+ int report_threads = 0;
+#if CXX_STD_THREAD
+ report_threads = n_worker_threads;
+#endif
+ gdb_printf (file, _("The number of worker threads GDB "
+ "can use is %d.\n"),
+ report_threads);
}
\f
for (compunit_symtab *cu : o->compunits ())
{
++nr_compunit_symtabs;
- nr_blocks += BLOCKVECTOR_NBLOCKS (COMPUNIT_BLOCKVECTOR (cu));
- nr_symtabs += std::distance (compunit_filetabs (cu).begin (),
- compunit_filetabs (cu).end ());
+ nr_blocks += cu->blockvector ()->num_blocks ();
+ nr_symtabs += std::distance (cu->filetabs ().begin (),
+ cu->filetabs ().end ());
}
}
}
/* Subtract time spend in prompt_for_continue from walltime. */
wall_time -= get_prompt_for_continue_wait_time ();
- printf_unfiltered (!m_msg_type
- ? _("Startup time: %.6f (cpu), %.6f (wall)\n")
- : _("Command execution time: %.6f (cpu), %.6f (wall)\n"),
- duration<double> (cmd_time).count (),
- duration<double> (wall_time).count ());
+ gdb_printf (gdb_stdlog,
+ !m_msg_type
+ ? _("Startup time: %.6f (cpu), %.6f (wall)\n")
+ : _("Command execution time: %.6f (cpu), %.6f (wall)\n"),
+ duration<double> (cmd_time).count (),
+ duration<double> (wall_time).count ());
}
if (m_space_enabled && per_command_space)
long space_now = lim - lim_at_start;
long space_diff = space_now - m_start_space;
- printf_unfiltered (!m_msg_type
- ? _("Space used: %ld (%s%ld during startup)\n")
- : _("Space used: %ld (%s%ld for this command)\n"),
- space_now,
- (space_diff >= 0 ? "+" : ""),
- space_diff);
+ gdb_printf (gdb_stdlog,
+ !m_msg_type
+ ? _("Space used: %ld (%s%ld during startup)\n")
+ : _("Space used: %ld (%s%ld for this command)\n"),
+ space_now,
+ (space_diff >= 0 ? "+" : ""),
+ space_diff);
#endif
}
int nr_symtabs, nr_compunit_symtabs, nr_blocks;
count_symtabs_and_blocks (&nr_symtabs, &nr_compunit_symtabs, &nr_blocks);
- printf_unfiltered (_("#symtabs: %d (+%d),"
- " #compunits: %d (+%d),"
- " #blocks: %d (+%d)\n"),
- nr_symtabs,
- nr_symtabs - m_start_nr_symtabs,
- nr_compunit_symtabs,
- (nr_compunit_symtabs
- - m_start_nr_compunit_symtabs),
- nr_blocks,
- nr_blocks - m_start_nr_blocks);
+ gdb_printf (gdb_stdlog,
+ _("#symtabs: %d (+%d),"
+ " #compunits: %d (+%d),"
+ " #blocks: %d (+%d)\n"),
+ nr_symtabs,
+ nr_symtabs - m_start_nr_symtabs,
+ nr_compunit_symtabs,
+ (nr_compunit_symtabs
+ - m_start_nr_compunit_symtabs),
+ nr_blocks,
+ nr_blocks - m_start_nr_blocks);
}
}
char out[100];
strftime (out, sizeof (out), "%F %H:%M:%S", &tm);
- printf_unfiltered ("%s.%03d - %s\n", out, (int) millis, msg);
+ gdb_printf (gdb_stdlog, "%s.%03d - %s\n", out, (int) millis, msg);
}
/* Handle unknown "mt set per-command" arguments.
error (_("Bad value for 'mt set per-command no'."));
for (list = per_command_setlist; list != NULL; list = list->next)
- if (list->var_type == var_boolean)
+ if (list->var->type () == var_boolean)
{
gdb_assert (list->type == set_cmd);
do_set_command (args, from_tty, list);
}
}
-\f
+/* Options affecting the "maintenance selftest" command. */
+
+struct maintenance_selftest_options
+{
+ bool verbose = false;
+} user_maintenance_selftest_options;
+
+static const gdb::option::option_def maintenance_selftest_option_defs[] = {
+ gdb::option::boolean_option_def<maintenance_selftest_options> {
+ "verbose",
+ [] (maintenance_selftest_options *opt) { return &opt->verbose; },
+ nullptr,
+ N_("Set whether selftests run in verbose mode."),
+ N_("Show whether selftests run in verbose mode."),
+ N_("\
+When on, selftests may print verbose information."),
+ },
+};
+
+/* Make option groups for the "maintenance selftest" command. */
+
+static std::array<gdb::option::option_def_group, 1>
+make_maintenance_selftest_option_group (maintenance_selftest_options *opts)
+{
+ return {{
+ {{maintenance_selftest_option_defs}, opts},
+ }};
+}
/* The "maintenance selftest" command. */
maintenance_selftest (const char *args, int from_tty)
{
#if GDB_SELF_TEST
- gdb_argv argv (args);
- selftests::run_tests (argv.as_array_view ());
+ maintenance_selftest_options opts = user_maintenance_selftest_options;
+ auto grp = make_maintenance_selftest_option_group (&opts);
+ gdb::option::process_options
+ (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp);
+ const gdb_argv argv (args);
+ selftests::run_tests (argv.as_array_view (), opts.verbose);
#else
- printf_filtered (_("\
+ gdb_printf (_("\
Selftests have been disabled for this build.\n"));
#endif
}
+/* Completer for the "maintenance selftest" command. */
+
+static void
+maintenance_selftest_completer (cmd_list_element *cmd,
+ completion_tracker &tracker,
+ const char *text,
+ const char *word)
+{
+ auto grp = make_maintenance_selftest_option_group (nullptr);
+
+ if (gdb::option::complete_options
+ (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, grp))
+ return;
+
+#if GDB_SELF_TEST
+ for (const auto &test : selftests::all_selftests ())
+ {
+ if (startswith (test.name.c_str (), text))
+ tracker.add_completion (make_unique_xstrdup (test.name.c_str ()));
+ }
+#endif
+}
+
static void
maintenance_info_selftests (const char *arg, int from_tty)
{
#if GDB_SELF_TEST
- printf_filtered ("Registered selftests:\n");
- selftests::for_each_selftest ([] (const std::string &name) {
- printf_filtered (" - %s\n", name.c_str ());
- });
+ gdb_printf ("Registered selftests:\n");
+ for (const auto &test : selftests::all_selftests ())
+ gdb_printf (" - %s\n", test.name.c_str ());
#else
- printf_filtered (_("\
+ gdb_printf (_("\
Selftests have been disabled for this build.\n"));
#endif
}
You probably shouldn't use this."),
&maintenancelist);
- add_cmd ("selftest", class_maintenance, maintenance_selftest, _("\
+ cmd_list_element *maintenance_selftest_cmd
+ = add_cmd ("selftest", class_maintenance, maintenance_selftest, _("\
Run gdb's unit tests.\n\
Usage: maintenance selftest [FILTER]\n\
This will run any unit tests that were built in to gdb.\n\
If a filter is given, only the tests with that value in their name will ran."),
- &maintenancelist);
+ &maintenancelist);
+ set_cmd_completer_handle_brkchars (maintenance_selftest_cmd,
+ maintenance_selftest_completer);
add_cmd ("selftests", class_maintenance, maintenance_info_selftests,
_("List the registered selftests."), &maintenanceinfolist);
&maintenance_set_cmdlist,
&maintenance_show_cmdlist);
+ /* Add the "maint set/show selftest" commands. */
+ static cmd_list_element *set_selftest_cmdlist = nullptr;
+ static cmd_list_element *show_selftest_cmdlist = nullptr;
+
+ add_setshow_prefix_cmd ("selftest", class_maintenance,
+ _("Self tests-related settings."),
+ _("Self tests-related settings."),
+ &set_selftest_cmdlist, &show_selftest_cmdlist,
+ &maintenance_set_cmdlist, &maintenance_show_cmdlist);
+
+ /* Add setting commands matching "maintenance selftest" options. */
+ gdb::option::add_setshow_cmds_for_options (class_maintenance,
+ &user_maintenance_selftest_options,
+ maintenance_selftest_option_defs,
+ &set_selftest_cmdlist,
+ &show_selftest_cmdlist);
+
update_thread_pool_size ();
}