while waiting for target events. */
ptid_t (*deprecated_target_wait_hook) (ptid_t ptid,
- struct target_waitstatus * status);
+ struct target_waitstatus *status,
+ int options);
/* Used by UI as a wrapper around command execution. May do various things
like enabling/disabling buttons, etc... */
}
#endif
-/* Execute the line P as a command.
- Pass FROM_TTY as second argument to the defining function. */
+void
+prepare_execute_command (void)
+{
+ free_all_values ();
-/* Execute command P, in the current user context. */
+ /* With multiple threads running while the one we're examining is stopped,
+ the dcache can get stale without us being able to detect it.
+ For the duration of the command, though, use the dcache to help
+ things like backtrace. */
+ if (non_stop)
+ target_dcache_invalidate ();
+}
+
+/* Execute the line P as a command, in the current user context.
+ Pass FROM_TTY as second argument to the defining function. */
void
execute_command (char *p, int from_tty)
#endif
}
}
-
- free_all_values ();
+
+ prepare_execute_command ();
/* Force cleanup of any alloca areas if using C alloca instead of
a builtin alloca. */
c = lookup_cmd (&p, cmdlist, "", 0, 1);
- /* If the selected thread has terminated, we allow only a
- limited set of commands. */
- if (target_can_async_p ()
- && is_exited (inferior_ptid)
- && !get_cmd_no_selected_thread_ok (c))
- error (_("\
-Cannot execute this command without a live selected thread. See `help thread'."));
-
/* Pass null arg rather than an empty one. */
arg = *p ? p : 0;
/* FIXME: This should be cacheing the frame and only running when
the frame changes. */
- if (target_has_stack && is_stopped (inferior_ptid))
+ if (has_stack_frames ())
{
flang = get_frame_language ();
if (!warned
set_prompt (char *s)
{
/* ??rehrauer: I don't know why this fails, since it looks as though
- assignments to prompt are wrapped in calls to savestring...
+ assignments to prompt are wrapped in calls to xstrdup...
if (prompt != NULL)
xfree (prompt);
*/
- PROMPT (0) = savestring (s, strlen (s));
+ PROMPT (0) = xstrdup (s);
}
\f
-/* If necessary, make the user confirm that we should quit. Return
- non-zero if we should quit, zero if we shouldn't. */
+struct qt_args
+{
+ char *args;
+ int from_tty;
+};
-int
-quit_confirm (void)
+/* Callback for iterate_over_inferiors. 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)
{
- if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
+ struct qt_args *qt = args;
+ struct thread_info *thread;
+
+ thread = any_thread_of_process (inf->pid);
+ if (thread != NULL)
{
- char *s;
- struct inferior *inf = current_inferior ();
-
- /* This is something of a hack. But there's no reliable way to
- see if a GUI is running. The `use_windows' variable doesn't
- cut it. */
- if (deprecated_init_ui_hook)
- s = "A debugging session is active.\nDo you still want to close the debugger?";
- else if (inf->attach_flag)
- s = "The program is running. Quit anyway (and detach it)? ";
- else
- s = "The program is running. Quit anyway (and kill it)? ";
+ switch_to_thread (thread->ptid);
- if (!query ("%s", s))
- return 0;
+ /* Leave core files alone. */
+ if (target_has_execution)
+ {
+ if (inf->attach_flag)
+ target_detach (qt->args, qt->from_tty);
+ else
+ target_kill ();
+ }
}
- return 1;
+ return 0;
}
-struct qt_args
-{
- char *args;
- int from_tty;
-};
-
-/* Callback for iterate_over_threads. Finds any thread of inferior
- given by ARG (really an int*). */
+/* 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. */
static int
-any_thread_of (struct thread_info *thread, void *arg)
+print_inferior_quit_action (struct inferior *inf, void *arg)
{
- int pid = * (int *)arg;
+ struct ui_file *stb = arg;
- if (PIDGET (thread->ptid) == pid)
- return 1;
+ if (inf->attach_flag)
+ fprintf_filtered (stb,
+ _("\tInferior %d [%s] will be detached.\n"), inf->num,
+ target_pid_to_str (pid_to_ptid (inf->pid)));
+ else
+ fprintf_filtered (stb,
+ _("\tInferior %d [%s] will be killed.\n"), inf->num,
+ target_pid_to_str (pid_to_ptid (inf->pid)));
return 0;
}
-/* Callback for iterate_over_inferiors. Kills or detaches the given
- inferior, depending on how we originally gained control of it. */
+/* If necessary, make the user confirm that we should quit. Return
+ non-zero if we should quit, zero if we shouldn't. */
-static int
-kill_or_detach (struct inferior *inf, void *args)
+int
+quit_confirm (void)
{
- struct qt_args *qt = args;
- struct thread_info *thread;
+ struct ui_file *stb;
+ struct cleanup *old_chain;
+ char *str;
+ int qr;
+
+ /* Don't even ask if we're only debugging a core file inferior. */
+ if (!have_live_inferiors ())
+ return 1;
+
+ /* Build the query string as a single string. */
+ stb = mem_fileopen ();
+ old_chain = make_cleanup_ui_file_delete (stb);
- thread = iterate_over_threads (any_thread_of, &inf->pid);
- if (thread)
+ /* This is something of a hack. But there's no reliable way to see
+ if a GUI is running. The `use_windows' variable doesn't cut
+ it. */
+ if (deprecated_init_ui_hook)
+ fprintf_filtered (stb, _("A debugging session is active.\n"
+ "Do you still want to close the debugger?"));
+ else
{
- switch_to_thread (thread->ptid);
- if (inf->attach_flag)
- target_detach (qt->args, qt->from_tty);
- else
- target_kill ();
+ fprintf_filtered (stb, _("A debugging session is active.\n\n"));
+ iterate_over_inferiors (print_inferior_quit_action, stb);
+ fprintf_filtered (stb, _("\nQuit anyway? "));
}
- return 0;
+ str = ui_file_xstrdup (stb, NULL);
+ make_cleanup (xfree, str);
+
+ qr = query ("%s", str);
+ do_cleanups (old_chain);
+ return qr;
}
/* Helper routine for quit_force that requires error handling. */
exit (exit_code);
}
+/* If OFF, the debugger will run in non-interactive mode, which means
+ that it will automatically select the default answer to all the
+ queries made to the user. If ON, gdb will wait for the user to
+ answer all queries. If AUTO, gdb will determine whether to run
+ in interactive mode or not depending on whether stdin is a terminal
+ or not. */
+static enum auto_boolean interactive_mode = AUTO_BOOLEAN_AUTO;
+
+/* Implement the "show interactive-mode" option. */
+
+static void
+show_interactive_mode (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
+{
+ if (interactive_mode == AUTO_BOOLEAN_AUTO)
+ fprintf_filtered (file, "\
+Debugger's interactive mode is %s (currently %s).\n",
+ value, input_from_terminal_p () ? "on" : "off");
+ else
+ fprintf_filtered (file, "Debugger's interactive mode is %s.\n", value);
+}
+
/* Returns whether GDB is running on a terminal and input is
currently coming from that terminal. */
int
input_from_terminal_p (void)
{
+ if (interactive_mode != AUTO_BOOLEAN_AUTO)
+ return interactive_mode == AUTO_BOOLEAN_TRUE;
+
if (gdb_has_a_terminal () && instream == stdin)
return 1;
tmpenv = getenv ("GDBHISTFILE");
if (tmpenv)
- history_filename = savestring (tmpenv, strlen (tmpenv));
+ history_filename = xstrdup (tmpenv);
else if (!history_filename)
{
/* We include the current directory so that if the user changes
whatever the DEFAULT_PROMPT is. */
the_prompts.top = 0;
PREFIX (0) = "";
- PROMPT (0) = savestring (DEFAULT_PROMPT, strlen (DEFAULT_PROMPT));
+ PROMPT (0) = xstrdup (DEFAULT_PROMPT);
SUFFIX (0) = "";
/* Set things up for annotation_level > 1, if the user ever decides
to use it. */
async_annotation_suffix = "prompt";
/* Set the variable associated with the setshow prompt command. */
- new_async_prompt = savestring (PROMPT (0), strlen (PROMPT (0)));
+ new_async_prompt = xstrdup (PROMPT (0));
/* If gdb was started with --annotate=2, this is equivalent to the
user entering the command 'set annotate 2' at the gdb prompt, so
write_history_p = 0;
/* Setup important stuff for command line editing. */
+ rl_completion_word_break_hook = gdb_completion_word_break_characters;
rl_completion_entry_function = readline_line_completion_function;
rl_completer_word_break_characters = default_word_break_characters ();
rl_completer_quote_characters = get_gdb_completer_quote_characters ();
NULL,
show_exec_done_display_p,
&setlist, &showlist);
+
+ add_setshow_auto_boolean_cmd ("interactive-mode", class_support,
+ &interactive_mode, _("\
+Set whether GDB should run in interactive mode or not"), _("\
+Show whether GDB runs in interactive mode"), _("\
+If on, run in interactive mode and wait for the user to answer\n\
+all queries. If off, run in non-interactive mode and automatically\n\
+assume the default answer to all queries. If auto (the default),\n\
+determine which mode to use based on the standard input settings"),
+ NULL,
+ show_interactive_mode,
+ &setlist, &showlist);
+
+ add_setshow_filename_cmd ("data-directory", class_maintenance,
+ &gdb_datadir, _("Set GDB's data directory."),
+ _("Show GDB's data directory."),
+ _("\
+When set, GDB uses the specified path to search for data files."),
+ NULL, NULL,
+ &setlist,
+ &showlist);
}
void