/* Memory-access and commands for "inferior" process, for GDB.
- Copyright (C) 1986-2012 Free Software Foundation, Inc.
+ Copyright (C) 1986-2014 Free Software Foundation, Inc.
This file is part of GDB.
#include "defs.h"
#include "arch-utils.h"
#include <signal.h>
-#include "gdb_string.h"
+#include <string.h>
#include "symtab.h"
#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"
#include "inf-loop.h"
#include "continuations.h"
#include "linespec.h"
-
-/* Functions exported for general use, in inferior.h: */
-
-void all_registers_info (char *, int);
-
-void registers_info (char *, int);
-
-void nexti_command (char *, int);
-
-void stepi_command (char *, int);
-
-void continue_command (char *, int);
-
-void interrupt_target_command (char *args, int from_tty);
+#include "cli/cli-utils.h"
/* Local functions: */
CORE_ADDR stop_pc;
-/* Flag indicating that a command has proceeded the inferior past the
- current breakpoint. */
-
-int breakpoint_proceeded;
-
/* Nonzero if stopped due to completion of a stack dummy routine. */
enum stop_stack_kind stop_stack_dummy;
int stopped_by_random_signal;
+/* See inferior.h. */
+
+int startup_with_shell = 1;
+
\f
/* Accessor routines. */
}
/* 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)
{
char *result;
- if (STARTUP_WITH_SHELL)
+ if (startup_with_shell)
{
#ifdef __MINGW32__
/* This holds all the characters considered special to the
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)
{
/* Create the hooks to handle shared library load and unload
events. */
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
- SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
-#else
solib_create_inferior_hook (from_tty);
-#endif
if (current_program_space->solib_add_generation == solib_add_generation)
{
/* If the solist is global across processes, there's no need to
refetch it here. */
if (!gdbarch_has_global_solist (target_gdbarch ()))
- {
-#ifdef SOLIB_ADD
- SOLIB_ADD (NULL, 0, target, auto_solib_add);
-#else
- solib_add (NULL, 0, target, auto_solib_add);
-#endif
- }
+ solib_add (NULL, 0, target, auto_solib_add);
}
}
}
}
+/* 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] [&] */
-void
+
+static void
continue_command (char *args, int from_tty)
{
int async_exec = 0;
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)
{
/* Likewise, but step only one instruction. */
-void
+static void
stepi_command (char *count_string, int from_tty)
{
step_1 (0, 1, count_string);
}
-void
+static void
nexti_command (char *count_string, int from_tty)
{
step_1 (1, 1, count_string);
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)
{
CORE_ADDR pc;
/* Step at an inlined function behaves like "down". */
- if (!skip_subroutines && !single_inst
+ if (!skip_subroutines
&& inline_skipped_frames (inferior_ptid))
{
ptid_t resume_ptid;
&tp->control.step_range_start,
&tp->control.step_range_end);
+ tp->control.may_range_step = 1;
+
/* If we have no line info, switch to stepi mode. */
if (tp->control.step_range_end == 0 && step_stop_if_no_debug)
- tp->control.step_range_start = tp->control.step_range_end = 1;
+ {
+ tp->control.step_range_start = tp->control.step_range_end = 1;
+ tp->control.may_range_step = 0;
+ }
else if (tp->control.step_range_end == 0)
{
const char *name;
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"));
if (sfn != NULL)
{
fixup_symbol_section (sfn, 0);
- if (section_is_overlay (SYMBOL_OBJ_SECTION (sfn)) &&
- !section_is_mapped (SYMBOL_OBJ_SECTION (sfn)))
+ if (section_is_overlay (SYMBOL_OBJ_SECTION (SYMBOL_OBJFILE (sfn), sfn)) &&
+ !section_is_mapped (SYMBOL_OBJ_SECTION (SYMBOL_OBJFILE (sfn), sfn)))
{
if (!query (_("WARNING!!! Destination is in "
"unmapped overlay! Jump anyway? ")))
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 (!func)
{
- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
+ struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc);
- if (msymbol == NULL)
+ if (msymbol.minsym == NULL)
error (_("Execution is not within a known function."));
- tp->control.step_range_start = SYMBOL_VALUE_ADDRESS (msymbol);
+ tp->control.step_range_start = BMSYMBOL_VALUE_ADDRESS (msymbol);
tp->control.step_range_end = pc;
}
else
tp->control.step_range_start = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
tp->control.step_range_end = sal.end;
}
+ tp->control.may_range_step = 1;
tp->control.step_over_calls = STEP_OVER_ALL;
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);
}
struct regcache *stop_regs = stop_registers;
struct gdbarch *gdbarch;
struct value *value;
- struct ui_out *uiout = current_uiout;
struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
/* If stop_registers were not saved, use the current registers. */
if (!stop_regs)
{
stop_regs = regcache_dup (get_current_regcache ());
- cleanup = make_cleanup_regcache_xfree (stop_regs);
+ make_cleanup_regcache_xfree (stop_regs);
}
gdbarch = get_regcache_arch (stop_regs);
ui_out_field_fmt (uiout, "gdb-result-var", "$%d",
record_latest_value (value));
ui_out_text (uiout, " = ");
- get_raw_print_options (&opts);
+ get_no_prettyformat_print_options (&opts);
value_print (value, stb, &opts);
ui_out_field_stream (uiout, "return-value", stb);
ui_out_text (uiout, "\n");
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."));
if (from_tty)
{
printf_filtered (_("Run till exit from "));
- print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
+ print_stack_frame (get_selected_frame (NULL), 1, LOCATION, 0);
}
proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
else
printf_filtered (_("Run till exit from "));
- print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
+ print_stack_frame (get_selected_frame (NULL), 1, LOCATION, 0);
}
if (execution_direction == EXEC_REVERSE)
struct value *val)
{
struct type *regtype = value_type (val);
+ int print_raw_format;
fputs_filtered (name, file);
print_spaces_filtered (15 - strlen (name), file);
- if (!value_entirely_available (val))
- {
- fprintf_filtered (file, "*value not available*\n");
- return;
- }
+ print_raw_format = (value_entirely_available (val)
+ && !value_optimized_out (val));
/* If virtual format is floating, print it that way, and in raw
hex. */
value_embedded_offset (val), 0,
file, 0, val, &opts, current_language);
- fprintf_filtered (file, "\t(raw 0x");
- for (j = 0; j < TYPE_LENGTH (regtype); j++)
+ if (print_raw_format)
{
- int idx;
-
- if (byte_order == BFD_ENDIAN_BIG)
- idx = j;
- else
- idx = TYPE_LENGTH (regtype) - 1 - j;
- fprintf_filtered (file, "%02x", (unsigned char) valaddr[idx]);
+ fprintf_filtered (file, "\t(raw ");
+ print_hex_chars (file, valaddr, TYPE_LENGTH (regtype), byte_order);
+ fprintf_filtered (file, ")");
}
- fprintf_filtered (file, ")");
}
else
{
file, 0, val, &opts, current_language);
/* If not a vector register, print it also according to its
natural format. */
- if (TYPE_VECTOR (regtype) == 0)
+ if (print_raw_format && TYPE_VECTOR (regtype) == 0)
{
get_user_print_options (&opts);
opts.deref_ref = 1;
for (i = 0; i < numregs; i++)
{
- struct type *regtype;
- struct value *val;
-
/* Decide between printing all regs, non-float / vector regs, or
specific reg. */
if (regnum == -1)
|| *(gdbarch_register_name (gdbarch, i)) == '\0')
continue;
- regtype = register_type (gdbarch, i);
- val = allocate_value (regtype);
-
- /* Get the data in raw format. */
- if (! deprecated_frame_register_read (frame, i, value_contents_raw (val)))
- mark_value_bytes_unavailable (val, 0, TYPE_LENGTH (value_type (val)));
-
default_print_one_register_info (file,
gdbarch_register_name (gdbarch, i),
- val);
+ value_of_register (i, frame));
}
}
char *start;
const char *end;
- /* Keep skipping leading white space. */
- if (isspace ((*addr_exp)))
- {
- addr_exp++;
- continue;
- }
+ /* Skip leading white space. */
+ addr_exp = skip_spaces (addr_exp);
/* Discard any leading ``$''. Check that there is something
resembling a register following it. */
}
}
-void
+static void
all_registers_info (char *addr_exp, int from_tty)
{
registers_info (addr_exp, 1);
if (target_has_stack)
{
printf_filtered (_("In %s,\n"), target_longname);
- print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
+ print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
}
}
bfd_cache_close_all ();
exec_file = (char *) get_exec_file (0);
if (!exec_file)
{
- exec_file = target_pid_to_exec_file (PIDGET (inferior_ptid));
+ exec_file = target_pid_to_exec_file (ptid_get_pid (inferior_ptid));
if (exec_file)
{
/* It's possible we don't have a full path, but rather just a
}
/* Take any necessary post-attaching actions for this platform. */
- target_post_attach (PIDGET (inferior_ptid));
+ target_post_attach (ptid_get_pid (inferior_ptid));
post_create_inferior (¤t_target, from_tty);
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
if (ptid_equal (inferior_ptid, null_ptid))
error (_("The program is not being run."));
- disconnect_tracing (from_tty);
+ query_if_trace_running (from_tty);
+
+ disconnect_tracing ();
target_detach (args, from_tty);
disconnect_command (char *args, int from_tty)
{
dont_repeat (); /* Not for the faint of heart. */
- disconnect_tracing (from_tty);
+ query_if_trace_running (from_tty);
+ disconnect_tracing ();
target_disconnect (args, from_tty);
no_shared_libraries (NULL, from_tty);
init_thread_list ();
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] */
-void
-interrupt_target_command (char *args, int from_tty)
+static void
+interrupt_command (char *args, int from_tty)
{
if (target_can_async_p ())
{
{
struct gdbarch *gdbarch = get_current_arch ();
- if (gdbarch_info_proc_p (gdbarch))
- gdbarch_info_proc (gdbarch, args, what);
- else
- target_info_proc (args, what);
+ if (!target_info_proc (args, what))
+ {
+ if (gdbarch_info_proc_p (gdbarch))
+ gdbarch_info_proc (gdbarch, args, what);
+ else
+ error (_("Not supported on this target."));
+ }
}
/* Implement `info proc' when given without any futher parameters. */
{
static struct cmd_list_element *info_proc_cmdlist;
struct cmd_list_element *c = NULL;
- char *cmd_name;
+ const char *cmd_name;
/* Add the filename of the terminal connected to inferior I/O. */
add_setshow_filename_cmd ("inferior-tty", class_run,
\"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\