#include "gdbtypes.h"
#include "frame.h"
#include "inferior.h"
+#include "infrun.h"
#include "environ.h"
#include "value.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "target.h"
#include "language.h"
-#include "symfile.h"
#include "objfiles.h"
#include "completer.h"
#include "ui-out.h"
}
/* Notice when `set args' is run. */
+
static void
set_args_command (char *args, int from_tty, struct cmd_list_element *c)
{
}
/* Notice when `show args' is run. */
+
static void
show_args_command (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
\f
/* Compute command-line string given argument vector. This does the
same shell processing as fork_inferior. */
+
char *
construct_inferior_arguments (int argc, char **argv)
{
background execution) has been added as *the last* of the arguments ARGS
of a command. If it has, it removes it and returns 1. Otherwise it
does nothing and returns 0. */
+
static int
strip_bg_char (char **args)
{
}
}
+/* See inferior.h. */
+
+void
+prepare_execution_command (struct target_ops *target, int background)
+{
+ /* If we get a request for running in the bg but the target
+ doesn't support it, error out. */
+ if (background && !target->to_can_async_p (target))
+ error (_("Asynchronous execution not supported on this target."));
+
+ /* If we don't get a request of running in the bg, then we need
+ to simulate synchronous (fg) execution. */
+ if (!background && target->to_can_async_p (target))
+ {
+ /* Simulate synchronous execution. Note no cleanup is necessary
+ for this. stdin is re-enabled whenever an error reaches the
+ top level. */
+ async_disable_stdin ();
+ }
+}
+
/* Implement the "run" command. If TBREAK_AT_MAIN is set, then insert
a temporary breakpoint at the begining of the main program before
running the program. */
struct cleanup *old_chain;
ptid_t ptid;
struct ui_out *uiout = current_uiout;
+ struct target_ops *run_target;
+ int async_exec = 0;
dont_repeat ();
reopen_exec_file ();
reread_symbols ();
+ if (args != NULL)
+ async_exec = strip_bg_char (&args);
+
+ /* Do validation and preparation before possibly changing anything
+ in the inferior. */
+
+ run_target = find_run_target ();
+
+ prepare_execution_command (run_target, async_exec);
+
+ if (non_stop && !run_target->to_supports_non_stop (run_target))
+ error (_("The target does not support running in non-stop mode."));
+
+ /* Done. Can now set breakpoints, change inferior args, etc. */
+
/* Insert the temporary breakpoint if a location was specified. */
if (tbreak_at_main)
tbreak_command (main_name (), 0);
exec_file = (char *) get_exec_file (0);
- if (non_stop && !target_supports_non_stop ())
- error (_("The target does not support running in non-stop mode."));
-
/* We keep symbols from add-symbol-file, on the grounds that the
user might want to add some symbols before running the program
(right?). But sometimes (dynamic loading where the user manually
the user has to manually nuke all symbols between runs if they
want them to go away (PR 2207). This is probably reasonable. */
- if (!args)
- {
- if (target_can_async_p ())
- async_disable_stdin ();
- }
- else
- {
- int async_exec = strip_bg_char (&args);
-
- /* If we get a request for running in the bg but the target
- doesn't support it, error out. */
- if (async_exec && !target_can_async_p ())
- error (_("Asynchronous execution not supported on this target."));
-
- /* If we don't get a request of running in the bg, then we need
- to simulate synchronous (fg) execution. */
- if (!async_exec && target_can_async_p ())
- {
- /* Simulate synchronous execution. */
- async_disable_stdin ();
- }
-
- /* If there were other args, beside '&', process them. */
- if (args)
- set_inferior_args (args);
- }
+ /* If there were other args, beside '&', process them. */
+ if (args != NULL)
+ set_inferior_args (args);
if (from_tty)
{
/* We call get_inferior_args() because we might need to compute
the value now. */
- target_create_inferior (exec_file, get_inferior_args (),
- environ_vector (current_inferior ()->environment),
- from_tty);
+ run_target->to_create_inferior (run_target, exec_file, get_inferior_args (),
+ environ_vector (current_inferior ()->environment),
+ from_tty);
+ /* to_create_inferior should push the target, so after this point we
+ shouldn't refer to run_target again. */
+ run_target = NULL;
/* We're starting off a new process. When we get out of here, in
non-stop mode, finish the state of all threads of that process,
}
/* continue [-a] [proceed-count] [&] */
+
static void
continue_command (char *args, int from_tty)
{
if (args != NULL)
async_exec = strip_bg_char (&args);
- /* If we must run in the background, but the target can't do it,
- error out. */
- if (async_exec && !target_can_async_p ())
- error (_("Asynchronous execution not supported on this target."));
-
- /* If we are not asked to run in the bg, then prepare to run in the
- foreground, synchronously. */
- if (!async_exec && target_can_async_p ())
- {
- /* Simulate synchronous execution. */
- async_disable_stdin ();
- }
+ prepare_execution_command (¤t_target, async_exec);
if (args != NULL)
{
if (count_string)
async_exec = strip_bg_char (&count_string);
- /* If we get a request for running in the bg but the target
- doesn't support it, error out. */
- if (async_exec && !target_can_async_p ())
- error (_("Asynchronous execution not supported on this target."));
-
- /* If we don't get a request of running in the bg, then we need
- to simulate synchronous (fg) execution. */
- if (!async_exec && target_can_async_p ())
- {
- /* Simulate synchronous execution. */
- async_disable_stdin ();
- }
+ prepare_execution_command (¤t_target, async_exec);
count = count_string ? parse_and_eval_long (count_string) : 1;
to the user. If count is > 1, we will need to do one more call to
proceed(), via step_once(). Basically it is like step_once and
step_1_continuation are co-recursive. */
+
static void
step_1_continuation (void *args, int err)
{
if (arg != NULL)
async_exec = strip_bg_char (&arg);
- /* If we must run in the background, but the target can't do it,
- error out. */
- if (async_exec && !target_can_async_p ())
- error (_("Asynchronous execution not supported on this target."));
+ prepare_execution_command (¤t_target, async_exec);
if (!arg)
error_no_arg (_("starting address"));
printf_filtered (".\n");
}
- /* If we are not asked to run in the bg, then prepare to run in the
- foreground, synchronously. */
- if (!async_exec && target_can_async_p ())
- {
- /* Simulate synchronous execution. */
- async_disable_stdin ();
- }
-
clear_proceed_status ();
proceed (addr, GDB_SIGNAL_0, 0);
}
\f
/* Go to line or address in current procedure. */
+
static void
go_command (char *line_no, int from_tty)
{
if (signum_exp != NULL)
async_exec = strip_bg_char (&signum_exp);
- /* If we must run in the background, but the target can't do it,
- error out. */
- if (async_exec && !target_can_async_p ())
- error (_("Asynchronous execution not supported on this target."));
-
- /* If we are not asked to run in the bg, then prepare to run in the
- foreground, synchronously. */
- if (!async_exec && target_can_async_p ())
- {
- /* Simulate synchronous execution. */
- async_disable_stdin ();
- }
+ prepare_execution_command (¤t_target, async_exec);
if (!signum_exp)
error_no_arg (_("signal number"));
if (msymbol.minsym == NULL)
error (_("Execution is not within a known function."));
- tp->control.step_range_start = SYMBOL_VALUE_ADDRESS (msymbol.minsym);
+ tp->control.step_range_start = BMSYMBOL_VALUE_ADDRESS (msymbol);
tp->control.step_range_end = pc;
}
else
if (arg != NULL)
async_exec = strip_bg_char (&arg);
- /* If we must run in the background, but the target can't do it,
- error out. */
- if (async_exec && !target_can_async_p ())
- error (_("Asynchronous execution not supported on this target."));
-
- /* If we are not asked to run in the bg, then prepare to run in the
- foreground, synchronously. */
- if (!async_exec && target_can_async_p ())
- {
- /* Simulate synchronous execution. */
- async_disable_stdin ();
- }
+ prepare_execution_command (¤t_target, async_exec);
if (arg)
until_break_command (arg, from_tty, 0);
if (arg != NULL)
async_exec = strip_bg_char (&arg);
- /* If we must run in the background, but the target can't do it,
- error out. */
- if (async_exec && !target_can_async_p ())
- error (_("Asynchronous execution not supported on this target."));
-
- /* If we are not asked to run in the bg, then prepare to run in the
- foreground, synchronously. */
- if (!async_exec && target_can_async_p ())
- {
- /* Simulate synchronous execution. */
- async_disable_stdin ();
- }
+ prepare_execution_command (¤t_target, async_exec);
until_break_command (arg, from_tty, 1);
}
if (arg != NULL)
async_exec = strip_bg_char (&arg);
- /* If we must run in the background, but the target can't do it,
- error out. */
- if (async_exec && !target_can_async_p ())
- error (_("Asynchronous execution not supported on this target."));
-
- /* If we are not asked to run in the bg, then prepare to run in the
- foreground, synchronously. */
- if (!async_exec && target_can_async_p ())
- {
- /* Simulate synchronous execution. */
- async_disable_stdin ();
- }
+ prepare_execution_command (¤t_target, async_exec);
if (arg)
error (_("The \"finish\" command does not take any arguments."));
attach_command (char *args, int from_tty)
{
int async_exec = 0;
- struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+ struct target_ops *attach_target;
dont_repeat (); /* Not for the faint of heart */
this function should probably be moved into target_pre_inferior. */
target_pre_inferior (from_tty);
- if (non_stop && !target_supports_non_stop ())
- error (_("Cannot attach to this target in non-stop mode"));
+ if (args != NULL)
+ async_exec = strip_bg_char (&args);
- if (args)
- {
- async_exec = strip_bg_char (&args);
+ attach_target = find_attach_target ();
- /* If we get a request for running in the bg but the target
- doesn't support it, error out. */
- if (async_exec && !target_can_async_p ())
- error (_("Asynchronous execution not supported on this target."));
- }
+ prepare_execution_command (attach_target, async_exec);
- /* If we don't get a request of running in the bg, then we need
- to simulate synchronous (fg) execution. */
- if (!async_exec && target_can_async_p ())
- {
- /* Simulate synchronous execution. */
- async_disable_stdin ();
- make_cleanup ((make_cleanup_ftype *)async_enable_stdin, NULL);
- }
+ if (non_stop && !attach_target->to_supports_non_stop (attach_target))
+ error (_("Cannot attach to this target in non-stop mode"));
- target_attach (args, from_tty);
+ attach_target->to_attach (attach_target, args, from_tty);
+ /* to_attach should push the target, so after this point we
+ shouldn't refer to attach_target again. */
+ attach_target = NULL;
/* Set up the "saved terminal modes" of the inferior
based on what modes we are starting it with. */
a->async_exec = async_exec;
add_inferior_continuation (attach_command_continuation, a,
attach_command_continuation_free_args);
- discard_cleanups (back_to);
return;
}
}
attach_command_post_wait (args, from_tty, async_exec);
- discard_cleanups (back_to);
}
/* We had just found out that the target was already attached to an
set_stop_requested (ptid, 1);
}
-/* Stop the execution of the target while running in async mode, in
+/* interrupt [-a]
+ Stop the execution of the target while running in async mode, in
the backgound. In all-stop, stop the whole process. In non-stop
mode, stop the current thread only by default, or stop all threads
if the `-a' switch is used. */
-/* interrupt [-a] */
static void
-interrupt_target_command (char *args, int from_tty)
+interrupt_command (char *args, int from_tty)
{
if (target_can_async_p ())
{
\"run\" command."));
set_cmd_completer (c, filename_completer);
- add_com ("interrupt", class_run, interrupt_target_command,
+ add_com ("interrupt", class_run, interrupt_command,
_("Interrupt the execution of the debugged program.\n\
If non-stop mode is enabled, interrupt only the current thread,\n\
otherwise all the threads in the program are stopped. To \n\