/* Top level stuff for GDB, the GNU debugger.
- Copyright (C) 1986-2019 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdb_select.h"
#include "gdbsupport/scope-exit.h"
#include "gdbarch.h"
+#include "gdbsupport/pathstuff.h"
+#include "cli/cli-style.h"
/* readline include files. */
#include "readline/readline.h"
extern void initialize_all_files (void);
+static bool history_filename_empty (void);
+
#define PROMPT(X) the_prompts.prompt_stack[the_prompts.top + X].prompt
#define PREFIX(X) the_prompts.prompt_stack[the_prompts.top + X].prefix
#define SUFFIX(X) the_prompts.prompt_stack[the_prompts.top + X].suffix
-/* Default command line prompt. This is overriden in some configs. */
+/* Default command line prompt. This is overridden in some configs. */
#ifndef DEFAULT_PROMPT
#define DEFAULT_PROMPT "(gdb) "
#endif
-/* Generate a function that exports a pointer to a field of the
- current UI. */
+struct ui_file **
+current_ui_gdb_stdout_ptr ()
+{
+ return ¤t_ui->m_gdb_stdout;
+}
-#define gen_ret_current_ui_field_ptr(type, name) \
-type * \
-current_ui_## name ## _ptr (void) \
-{ \
- return ¤t_ui->m_ ## name; \
+struct ui_file **
+current_ui_gdb_stdin_ptr ()
+{
+ return ¤t_ui->m_gdb_stdin;
}
-gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdout)
-gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdin)
-gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stderr)
-gen_ret_current_ui_field_ptr (struct ui_file *, gdb_stdlog)
-gen_ret_current_ui_field_ptr (struct ui_out *, current_uiout)
+struct ui_file **
+current_ui_gdb_stderr_ptr ()
+{
+ return ¤t_ui->m_gdb_stderr;
+}
-int inhibit_gdbinit = 0;
+struct ui_file **
+current_ui_gdb_stdlog_ptr ()
+{
+ return ¤t_ui->m_gdb_stdlog;
+}
+
+struct ui_out **
+current_ui_current_uiout_ptr ()
+{
+ return ¤t_ui->m_current_uiout;
+}
-extern char lang_frame_mismatch_warn[]; /* language.c */
+int inhibit_gdbinit = 0;
/* Flag for whether we want to confirm potentially dangerous
operations. Default is yes. */
-int confirm = 1;
+bool confirm = true;
static void
show_confirm (struct ui_file *file, int from_tty,
while (ui->instream != NULL && !feof (ui->instream))
{
- char *command;
+ const char *command;
/* Get a command-line. This calls the readline package. */
command = command_line_input (NULL, NULL);
&& flang != language_unknown
&& flang != current_language->la_language)
{
- printf_filtered ("%s\n", lang_frame_mismatch_warn);
+ printf_filtered ("%s\n", _(lang_frame_mismatch_warn));
warned = 1;
}
}
/* c->user_commands would be NULL in the case of a python command. */
if (c->theclass == class_user && c->user_commands)
execute_user_command (c, arg);
+ else if (c->theclass == class_user
+ && c->prefixlist && !c->allow_unknown)
+ /* If this is a user defined prefix that does not allow unknown
+ (in other words, C is a prefix command and not a command
+ that can be followed by its args), report the list of
+ subcommands. */
+ {
+ printf_unfiltered
+ ("\"%.*s\" must be followed by the name of a subcommand.\n",
+ (int) strlen (c->prefixname) - 1, c->prefixname);
+ help_list (*c->prefixlist, c->prefixname, all_commands, gdb_stdout);
+ }
else if (c->type == set_cmd)
do_set_command (arg, from_tty, c);
else if (c->type == show_cmd)
/* Variables which control command line editing and history
substitution. These variables are given default values at the end
of this file. */
-static int command_editing_p;
+static bool command_editing_p;
/* NOTE 1999-04-29: This variable will be static again, once we modify
gdb to use the event loop as the default command loop and we merge
event-top.c into this file, top.c. */
-/* static */ int history_expansion_p;
+/* static */ bool history_expansion_p;
-static int write_history_p;
+/* Should we write out the command history on exit? In order to write out
+ the history both this flag must be true, and the history_filename
+ variable must be set to something sensible. */
+static bool write_history_p;
+
+/* Implement 'show history save'. */
static void
show_write_history_p (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- fprintf_filtered (file, _("Saving of the history record on exit is %s.\n"),
- value);
+ if (!write_history_p || !history_filename_empty ())
+ fprintf_filtered (file, _("Saving of the history record on exit is %s.\n"),
+ value);
+ else
+ fprintf_filtered (file, _("Saving of the history is disabled due to "
+ "the value of 'history filename'.\n"));
}
/* The variable associated with the "set/show history size"
value);
}
+/* The name of the file in which GDB history will be written. If this is
+ set to NULL, of the empty string then history will not be written. */
static char *history_filename;
+
+/* Return true if the history_filename is either NULL or the empty string,
+ indicating that we should not try to read, nor write out the history. */
+static bool
+history_filename_empty (void)
+{
+ return (history_filename == nullptr || *history_filename == '\0');
+}
+
+/* Implement 'show history filename'. */
static void
show_history_filename (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- fprintf_filtered (file, _("The filename in which to record "
- "the command history is \"%s\".\n"),
- value);
+ if (!history_filename_empty ())
+ fprintf_filtered (file, _("The filename in which to record "
+ "the command history is \"%ps\".\n"),
+ styled_string (file_name_style.style (), value));
+ else
+ fprintf_filtered (file, _("There is no filename currently set for "
+ "recording the command history in.\n"));
}
/* This is like readline(), but it has some gdb-specific behavior.
saved_errno = errno;
if (ret < 0 && saved_errno != ENOENT)
{
- warning (_("Could not rename %s to %s: %s"),
- history_filename, local_history_filename.c_str (),
+ warning (_("Could not rename %ps to %ps: %s"),
+ styled_string (file_name_style.style (), history_filename),
+ styled_string (file_name_style.style (),
+ local_history_filename.c_str ()),
safe_strerror (saved_errno));
}
else
This routine either uses fancy command line editing or simple input
as the user has requested. */
-char *
+const char *
command_line_input (const char *prompt_arg, const char *annotation_suffix)
{
static struct buffer cmd_line_buffer;
/* Second line is a copyright notice. */
fprintf_filtered (stream,
- "Copyright (C) 2019 Free Software Foundation, Inc.\n");
+ "Copyright (C) 2020 Free Software Foundation, Inc.\n");
/* Following the copyright is a brief statement that the program is
free software, that users are free to copy and change it on
This GDB was configured as follows:\n\
configure --host=%s --target=%s\n\
"), host_name, target_name);
+
fprintf_filtered (stream, _("\
--with-auto-load-dir=%s\n\
--with-auto-load-safe-path=%s\n\
"), AUTO_LOAD_DIR, AUTO_LOAD_SAFE_PATH);
+
#if HAVE_LIBEXPAT
fprintf_filtered (stream, _("\
--with-expat\n\
--without-expat\n\
"));
#endif
+
if (GDB_DATADIR[0])
fprintf_filtered (stream, _("\
--with-gdb-datadir=%s%s\n\
"), GDB_DATADIR, GDB_DATADIR_RELOCATABLE ? " (relocatable)" : "");
+
#ifdef ICONV_BIN
fprintf_filtered (stream, _("\
--with-iconv-bin=%s%s\n\
"), ICONV_BIN, ICONV_BIN_RELOCATABLE ? " (relocatable)" : "");
#endif
+
if (JIT_READER_DIR[0])
fprintf_filtered (stream, _("\
--with-jit-reader-dir=%s%s\n\
"), JIT_READER_DIR, JIT_READER_DIR_RELOCATABLE ? " (relocatable)" : "");
+
#if HAVE_LIBUNWIND_IA64_H
fprintf_filtered (stream, _("\
--with-libunwind-ia64\n\
--without-libunwind-ia64\n\
"));
#endif
+
#if HAVE_LIBLZMA
fprintf_filtered (stream, _("\
--with-lzma\n\
--without-lzma\n\
"));
#endif
+
#if HAVE_LIBBABELTRACE
- fprintf_filtered (stream, _("\
+ fprintf_filtered (stream, _("\
--with-babeltrace\n\
"));
#else
- fprintf_filtered (stream, _("\
+ fprintf_filtered (stream, _("\
--without-babeltrace\n\
"));
#endif
+
#if HAVE_LIBIPT
- fprintf_filtered (stream, _("\
+ fprintf_filtered (stream, _("\
--with-intel-pt\n\
"));
#else
- fprintf_filtered (stream, _("\
+ fprintf_filtered (stream, _("\
--without-intel-pt\n\
"));
#endif
+
#if HAVE_LIBMPFR
- fprintf_filtered (stream, _("\
+ fprintf_filtered (stream, _("\
--with-mpfr\n\
"));
#else
- fprintf_filtered (stream, _("\
+ fprintf_filtered (stream, _("\
--without-mpfr\n\
"));
#endif
+#if HAVE_LIBXXHASH
+ fprintf_filtered (stream, _("\
+ --with-xxhash\n\
+"));
+#else
+ fprintf_filtered (stream, _("\
+ --without-xxhash\n\
+"));
+#endif
#ifdef WITH_PYTHON_PATH
fprintf_filtered (stream, _("\
--with-python=%s%s\n\
--without-python\n\
"));
#endif
+
+#if HAVE_LIBDEBUGINFOD
+ fprintf_filtered (stream, _("\
+ --with-debuginfod\n\
+"));
+#else
+ fprintf_filtered (stream, _("\
+ --without-debuginfod\n\
+"));
+#endif
+
#if HAVE_GUILE
fprintf_filtered (stream, _("\
--with-guile\n\
--without-guile\n\
"));
#endif
+
#if HAVE_SOURCE_HIGHLIGHT
fprintf_filtered (stream, _("\
--enable-source-highlight\n\
--disable-source-highlight\n\
"));
#endif
+
#ifdef RELOC_SRCDIR
fprintf_filtered (stream, _("\
--with-relocated-sources=%s\n\
"), RELOC_SRCDIR);
#endif
+
if (DEBUGDIR[0])
fprintf_filtered (stream, _("\
--with-separate-debug-dir=%s%s\n\
"), DEBUGDIR, DEBUGDIR_RELOCATABLE ? " (relocatable)" : "");
+
if (TARGET_SYSTEM_ROOT[0])
fprintf_filtered (stream, _("\
--with-sysroot=%s%s\n\
"), TARGET_SYSTEM_ROOT, TARGET_SYSTEM_ROOT_RELOCATABLE ? " (relocatable)" : "");
+
if (SYSTEM_GDBINIT[0])
fprintf_filtered (stream, _("\
--with-system-gdbinit=%s%s\n\
"), SYSTEM_GDBINIT, SYSTEM_GDBINIT_RELOCATABLE ? " (relocatable)" : "");
- /* We assume "relocatable" will be printed at least once, thus we always
- print this text. It's a reasonably safe assumption for now. */
- fprintf_filtered (stream, _("\n\
+
+ if (SYSTEM_GDBINIT_DIR[0])
+ fprintf_filtered (stream, _("\
+ --with-system-gdbinit-dir=%s%s\n\
+"), SYSTEM_GDBINIT_DIR, SYSTEM_GDBINIT_DIR_RELOCATABLE ? " (relocatable)" : "");
+
+ /* We assume "relocatable" will be printed at least once, thus we always
+ print this text. It's a reasonably safe assumption for now. */
+ fprintf_filtered (stream, _("\n\
(\"Relocatable\" means the directory can be moved with the GDB installation\n\
tree, and GDB will still find it.)\n\
"));
}
\f
-struct qt_args
-{
- int from_tty;
-};
-
-/* Callback for iterate_over_inferiors. Kills or detaches the given
- inferior, depending on how we originally gained control of it. */
+/* Kills or detaches the given inferior, depending on how we originally
+ gained control of it. */
-static int
-kill_or_detach (struct inferior *inf, void *args)
+static void
+kill_or_detach (inferior *inf, int from_tty)
{
- struct qt_args *qt = (struct qt_args *) args;
-
if (inf->pid == 0)
- return 0;
+ return;
thread_info *thread = any_thread_of_inferior (inf);
if (thread != NULL)
if (target_has_execution)
{
if (inf->attach_flag)
- target_detach (inf, qt->from_tty);
+ target_detach (inf, from_tty);
else
target_kill ();
}
}
-
- return 0;
}
-/* Callback for iterate_over_inferiors. Prints info about what GDB
- will do to each inferior on a "quit". ARG points to a struct
- ui_out where output is to be collected. */
+/* Prints info about what GDB will do to inferior INF on a "quit". OUT is
+ where to collect the output. */
-static int
-print_inferior_quit_action (struct inferior *inf, void *arg)
+static void
+print_inferior_quit_action (inferior *inf, ui_file *out)
{
- struct ui_file *stb = (struct ui_file *) arg;
-
if (inf->pid == 0)
- return 0;
+ return;
if (inf->attach_flag)
- fprintf_filtered (stb,
+ fprintf_filtered (out,
_("\tInferior %d [%s] will be detached.\n"), inf->num,
target_pid_to_str (ptid_t (inf->pid)).c_str ());
else
- fprintf_filtered (stb,
+ fprintf_filtered (out,
_("\tInferior %d [%s] will be killed.\n"), inf->num,
target_pid_to_str (ptid_t (inf->pid)).c_str ());
-
- return 0;
}
/* If necessary, make the user confirm that we should quit. Return
string_file stb;
stb.puts (_("A debugging session is active.\n\n"));
- iterate_over_inferiors (print_inferior_quit_action, &stb);
+
+ for (inferior *inf : all_inferiors ())
+ print_inferior_quit_action (inf, &stb);
+
stb.puts (_("\nQuit anyway? "));
return query ("%s", stb.c_str ());
quit_force (int *exit_arg, int from_tty)
{
int exit_code = 0;
- struct qt_args qt;
undo_terminal_modifications_before_exit ();
else if (return_child_result)
exit_code = return_child_result_value;
- qt.from_tty = from_tty;
-
/* We want to handle any quit errors and exit regardless. */
/* Get out of tfind mode, and kill or detach all inferiors. */
try
{
disconnect_tracing ();
- iterate_over_inferiors (kill_or_detach, &qt);
+ for (inferior *inf : all_inferiors ())
+ kill_or_detach (inf, from_tty);
}
catch (const gdb_exception &ex)
{
/* Give all pushed targets a chance to do minimal cleanup, and pop
them all out. */
- try
- {
- pop_all_targets ();
- }
- catch (const gdb_exception &ex)
+ for (inferior *inf : all_inferiors ())
{
- exception_print (gdb_stderr, ex);
+ switch_to_inferior_no_thread (inf);
+ try
+ {
+ pop_all_targets ();
+ }
+ catch (const gdb_exception &ex)
+ {
+ exception_print (gdb_stderr, ex);
+ }
}
/* Save the history information if it is appropriate to do so. */
cmd_show_list (showhistlist, from_tty, "");
}
-int info_verbose = 0; /* Default verbose msgs off. */
+bool info_verbose = false; /* Default verbose msgs off. */
/* Called by do_set_command. An elaborate joke. */
void
set_readline_history_size (history_size_setshow_var);
tmpenv = getenv ("GDBHISTFILE");
- if (tmpenv)
+ if (tmpenv != nullptr)
history_filename = xstrdup (tmpenv);
- else if (!history_filename)
+ else if (history_filename == nullptr)
{
/* We include the current directory so that if the user changes
directories the file written will be the same as the one
that was read. */
#ifdef __MSDOS__
/* No leading dots in file names are allowed on MSDOS. */
- history_filename = concat (current_directory, "/_gdb_history",
- (char *)NULL);
+ const char *fname = "_gdb_history";
#else
- history_filename = concat (current_directory, "/.gdb_history",
- (char *)NULL);
+ const char *fname = ".gdb_history";
#endif
+
+ gdb::unique_xmalloc_ptr<char> temp (gdb_abspath (fname));
+ history_filename = temp.release ();
}
- read_history (history_filename);
+
+ if (!history_filename_empty ())
+ read_history (history_filename);
}
static void
show_gdb_datadir (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- fprintf_filtered (file, _("GDB's data directory is \"%s\".\n"),
- gdb_datadir.c_str ());
+ fprintf_filtered (file, _("GDB's data directory is \"%ps\".\n"),
+ styled_string (file_name_style.style (),
+ gdb_datadir.c_str ()));
}
+/* Implement 'set history filename'. */
+
static void
set_history_filename (const char *args,
int from_tty, struct cmd_list_element *c)
/* We include the current directory so that if the user changes
directories the file written will be the same as the one
that was read. */
- if (!IS_ABSOLUTE_PATH (history_filename))
- history_filename = reconcat (history_filename, current_directory, "/",
- history_filename, (char *) NULL);
+ if (!history_filename_empty () && !IS_ABSOLUTE_PATH (history_filename))
+ {
+ gdb::unique_xmalloc_ptr<char> temp (gdb_abspath (history_filename));
+
+ xfree (history_filename);
+ history_filename = temp.release ();
+ }
}
static void
show_history_remove_duplicates,
&sethistlist, &showhistlist);
- add_setshow_filename_cmd ("filename", no_class, &history_filename, _("\
+ add_setshow_optional_filename_cmd ("filename", no_class, &history_filename, _("\
Set the filename in which to record the command history."), _("\
Show the filename in which to record the command history."), _("\
(the list of previous commands of which a record is kept)."),
#endif
init_cmd_lists (); /* This needs to be done first. */
- initialize_targets (); /* Setup target_terminal macros for utils.c. */
- initialize_utils (); /* Make errors and warnings possible. */
init_page_info ();