/* Memory-access and commands for "inferior" process, for GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include <signal.h>
#include "regcache.h"
#include "reggroups.h"
#include "block.h"
+#include "solib.h"
#include <ctype.h>
#include "gdb_assert.h"
+#include "observer.h"
+#include "target-descriptions.h"
/* Functions exported for general use, in inferior.h: */
/* File name for default use for standard in/out in the inferior. */
-char *inferior_io_terminal;
+static char *inferior_io_terminal;
/* Pid of our debugged inferior, or 0 if no inferior now.
Since various parts of infrun.c test this to see whether there is a program
/* Environment to use for running inferior,
in format described in environ.h. */
-struct environ *inferior_environ;
+struct gdb_environ *inferior_environ;
\f
/* Accessor routines. */
+void
+set_inferior_io_terminal (const char *terminal_name)
+{
+ if (inferior_io_terminal)
+ xfree (inferior_io_terminal);
+
+ if (!terminal_name)
+ inferior_io_terminal = NULL;
+ else
+ inferior_io_terminal = savestring (terminal_name, strlen (terminal_name));
+}
+
+const char *
+get_inferior_io_terminal (void)
+{
+ return inferior_io_terminal;
+}
+
char *
get_inferior_args (void)
{
/* Notice when `show args' is run. */
static void
-notice_args_read (char *args, int from_tty, struct cmd_list_element *c)
+notice_args_read (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
{
+ deprecated_show_value_hack (file, from_tty, c, value);
/* Might compute the value. */
get_inferior_args ();
}
if (file == 0)
error_no_arg (_("terminal name for running target process"));
- inferior_io_terminal = savestring (file, strlen (file));
+ set_inferior_io_terminal (file);
+}
+
+/* Common actions to take after creating any sort of inferior, by any
+ means (running, attaching, connecting, et cetera). The target
+ should be stopped. */
+
+void
+post_create_inferior (struct target_ops *target, int from_tty)
+{
+ /* If the target hasn't taken care of this already, do it now.
+ Targets which need to access registers during to_open,
+ to_create_inferior, or to_attach should do it earlier; but many
+ don't need to. */
+ target_find_description ();
+
+ if (exec_bfd)
+ {
+ /* Sometimes the platform-specific hook loads initial shared
+ libraries, and sometimes it doesn't. Try to do so first, so
+ that we can add them with the correct value for FROM_TTY. */
+#ifdef SOLIB_ADD
+ SOLIB_ADD (NULL, from_tty, target, auto_solib_add);
+#else
+ solib_add (NULL, from_tty, target, auto_solib_add);
+#endif
+
+ /* 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 ();
+#endif
+
+ /* Enable any breakpoints which were disabled when the
+ underlying shared library was deleted. */
+ re_enable_breakpoints_in_shlibs ();
+ }
+
+ observer_notify_inferior_created (target, from_tty);
}
/* Kill the inferior if already running. This function is designed
}
}
+/* 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. */
+
static void
-run_command (char *args, int from_tty)
+run_command_1 (char *args, int from_tty, int tbreak_at_main)
{
char *exec_file;
kill_if_already_running (from_tty);
clear_breakpoint_hit_counts ();
+ /* Clean up any leftovers from other runs. Some other things from
+ this function should probably be moved into target_pre_inferior. */
+ target_pre_inferior (from_tty);
+
/* Purge old solib objfiles. */
objfile_purge_solibs ();
reopen_exec_file ();
reread_symbols ();
+ /* 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);
/* We keep symbols from add-symbol-file, on the grounds that the
the value now. */
target_create_inferior (exec_file, get_inferior_args (),
environ_vector (inferior_environ), from_tty);
+
+ post_create_inferior (¤t_target, from_tty);
+
+ /* Start the target running. */
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
}
+static void
+run_command (char *args, int from_tty)
+{
+ run_command_1 (args, from_tty, 0);
+}
+
static void
run_no_args_command (char *args, int from_tty)
{
if (!have_minimal_symbols ())
error (_("No symbol table loaded. Use the \"file\" command."));
- /* If the inferior is already running, we want to ask the user if we
- should restart it or not before we insert the temporary breakpoint.
- This makes sure that this command doesn't have any side effect if
- the user changes its mind. */
- kill_if_already_running (from_tty);
-
- /* Insert the temporary breakpoint, and run... */
- tbreak_command (main_name (), 0);
- run_command (args, from_tty);
+ /* Run the program until reaching the main procedure... */
+ run_command_1 (args, from_tty, 1);
}
void
struct ui_stream *stb;
struct value *value;
+ CHECK_TYPEDEF (value_type);
gdb_assert (TYPE_CODE (value_type) != TYPE_CODE_VOID);
/* FIXME: 2003-09-27: When returning from a nested inferior function
{
case RETURN_VALUE_REGISTER_CONVENTION:
case RETURN_VALUE_ABI_RETURNS_ADDRESS:
+ case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
value = allocate_value (value_type);
- CHECK_TYPEDEF (value_type);
gdbarch_return_value (current_gdbarch, value_type, stop_registers,
value_contents_raw (value), NULL);
break;
error (_("The \"finish\" command does not take any arguments."));
if (!target_has_execution)
error (_("The program is not running."));
- if (deprecated_selected_frame == NULL)
- error (_("No selected frame."));
- frame = get_prev_frame (deprecated_selected_frame);
+ frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
if (frame == 0)
error (_("\"finish\" not meaningful in the outermost frame."));
/* Find the function we will return from. */
- function = find_pc_function (get_frame_pc (deprecated_selected_frame));
+ function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
/* Print info on the selected frame, including level number but not
source. */
{
int i;
const int numregs = NUM_REGS + NUM_PSEUDO_REGS;
- char buffer[MAX_REGISTER_SIZE];
+ gdb_byte buffer[MAX_REGISTER_SIZE];
for (i = 0; i < numregs; i++)
{
void
registers_info (char *addr_exp, int fpregs)
{
+ struct frame_info *frame;
int regnum, numregs;
char *end;
if (!target_has_registers)
error (_("The program has no registers now."));
- if (deprecated_selected_frame == NULL)
- error (_("No selected frame."));
+ frame = get_selected_frame (NULL);
if (!addr_exp)
{
gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
- deprecated_selected_frame, -1, fpregs);
+ frame, -1, fpregs);
return;
}
/* A register name? */
{
- int regnum = frame_map_name_to_regnum (deprecated_selected_frame,
+ int regnum = frame_map_name_to_regnum (frame,
start, end - start);
if (regnum >= 0)
{
gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
- deprecated_selected_frame, regnum, fpregs);
+ frame, regnum, fpregs);
continue;
}
}
&& regnum < NUM_REGS + NUM_PSEUDO_REGS)
{
gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
- deprecated_selected_frame, regnum, fpregs);
+ frame, regnum, fpregs);
continue;
}
}
if (gdbarch_register_reggroup_p (current_gdbarch, regnum,
group))
gdbarch_print_registers_info (current_gdbarch,
- gdb_stdout, deprecated_selected_frame,
+ gdb_stdout, frame,
regnum, fpregs);
}
continue;
print_vector_info (struct gdbarch *gdbarch, struct ui_file *file,
struct frame_info *frame, const char *args)
{
- if (!target_has_registers)
- error (_("The program has no registers now."));
- if (deprecated_selected_frame == NULL)
- error (_("No selected frame."));
-
if (gdbarch_print_vector_info_p (gdbarch))
gdbarch_print_vector_info (gdbarch, file, frame, args);
else
static void
vector_info (char *args, int from_tty)
{
- print_vector_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args);
+ if (!target_has_registers)
+ error (_("The program has no registers now."));
+
+ print_vector_info (current_gdbarch, gdb_stdout,
+ get_selected_frame (NULL), args);
}
\f
error (_("Not killed."));
}
+ /* Clean up any leftovers from other runs. Some other things from
+ this function should probably be moved into target_pre_inferior. */
+ target_pre_inferior (from_tty);
+
/* Clear out solib state. Otherwise the solib state of the previous
inferior might have survived and is entirely wrong for the new
- target. This has been observed on Linux using glibc 2.3. How to
- reproduce:
+ target. This has been observed on GNU/Linux using glibc 2.3. How
+ to reproduce:
bash$ ./foo&
[1] 4711
*/
#ifdef CLEAR_SOLIB
CLEAR_SOLIB ();
+#else
+ clear_solib ();
#endif
target_attach (args, from_tty);
reread_symbols ();
}
-#ifdef SOLIB_ADD
- /* Add shared library symbols from the newly attached process, if any. */
- SOLIB_ADD ((char *) 0, from_tty, ¤t_target, auto_solib_add);
- re_enable_breakpoints_in_shlibs ();
-#endif
-
/* Take any necessary post-attaching actions for this platform.
*/
target_post_attach (PIDGET (inferior_ptid));
+ post_create_inferior (¤t_target, from_tty);
+
/* Install inferior's terminal modes. */
target_terminal_inferior ();
print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
struct frame_info *frame, const char *args)
{
- if (!target_has_registers)
- error (_("The program has no registers now."));
- if (deprecated_selected_frame == NULL)
- error (_("No selected frame."));
-
if (gdbarch_print_float_info_p (gdbarch))
gdbarch_print_float_info (gdbarch, file, frame, args);
else
static void
float_info (char *args, int from_tty)
{
+ if (!target_has_registers)
+ error (_("The program has no registers now."));
+
print_float_info (current_gdbarch, gdb_stdout,
- deprecated_selected_frame, args);
+ get_selected_frame (NULL), args);
}
\f
static void
void
_initialize_infcmd (void)
{
- struct cmd_list_element *c;
-
- c = add_com ("tty", class_run, tty_command,
- _("Set terminal for future runs of program being debugged."));
- set_cmd_completer (c, filename_completer);
-
- c = add_set_cmd ("args", class_run, var_string_noescape,
- (char *) &inferior_args,
- "Set argument list to give program being debugged when it is started.\n\
-Follow this command with any number of args, to be passed to the program.",
- &setlist);
- set_cmd_completer (c, filename_completer);
- set_cmd_sfunc (c, notice_args_set);
- c = deprecated_add_show_from_set (c, &showlist);
- set_cmd_sfunc (c, notice_args_read);
+ struct cmd_list_element *c = NULL;
+
+ /* add the filename of the terminal connected to inferior I/O */
+ add_setshow_filename_cmd ("inferior-tty", class_run,
+ &inferior_io_terminal, _("\
+Set terminal for future runs of program being debugged."), _("\
+Show terminal for future runs of program being debugged."), _("\
+Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist);
+ add_com_alias ("tty", "set inferior-tty", class_alias, 0);
+
+ add_setshow_optional_filename_cmd ("args", class_run,
+ &inferior_args, _("\
+Set argument list to give program being debugged when it is started."), _("\
+Show argument list to give program being debugged when it is started."), _("\
+Follow this command with any number of args, to be passed to the program."),
+ notice_args_set,
+ notice_args_read,
+ &setlist, &showlist);
c = add_cmd ("environment", no_class, environment_info, _("\
The environment to give the program, or one variable's value.\n\
(see the \"directory\" command). You can also use the \"file\" command\n\
to specify the program, and to load its symbol table."));
- add_com ("detach", class_run, detach_command, _("\
+ add_prefix_cmd ("detach", class_run, detach_command, _("\
Detach a process or file previously attached.\n\
If a process, it is no longer traced, and it continues its execution. If\n\
-you were debugging a file, the file is closed and gdb no longer accesses it."));
+you were debugging a file, the file is closed and gdb no longer accesses it."),
+ &detachlist, "detach ", 0, &cmdlist);
add_com ("disconnect", class_run, disconnect_command, _("\
Disconnect from a target.\n\