/* Memory-access and commands for "inferior" process, for GDB.
- Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1986-2012 Free Software Foundation, Inc.
This file is part of GDB.
#include "tracepoint.h"
#include "inf-loop.h"
#include "continuations.h"
+#include "linespec.h"
/* Functions exported for general use, in inferior.h: */
return 0;
}
-void
+static void
ensure_valid_thread (void)
{
if (ptid_equal (inferior_ptid, null_ptid)
is likely to mix up recorded and live target data. So simply
disallow those commands. */
-void
+static void
ensure_not_tfind_mode (void)
{
if (get_traceframe_number () >= 0)
tp->control.step_range_start = tp->control.step_range_end = 1;
else if (tp->control.step_range_end == 0)
{
- char *name;
+ const char *name;
if (find_pc_partial_function (pc, &name,
&tp->control.step_range_start,
if (!arg)
error_no_arg (_("starting address"));
- sals = decode_line_spec_1 (arg, 1);
+ sals = decode_line_spec_1 (arg, DECODE_LINE_FUNFIRSTLINE);
if (sals.nelts != 1)
{
error (_("Unreasonable jump request"));
until_break_command (arg, from_tty, 1);
}
\f
-/* Print the result of a function at the end of a 'finish' command. */
+/* Return the value of the result of a function at the end of a 'finish'
+ command/BP. */
-static void
-print_return_value (struct type *func_type, struct type *value_type)
+struct value *
+get_return_value (struct type *func_type, struct type *value_type)
{
- struct gdbarch *gdbarch = get_regcache_arch (stop_registers);
- struct cleanup *old_chain;
- struct ui_stream *stb;
+ 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);
+ }
+
+ gdbarch = get_regcache_arch (stop_regs);
CHECK_TYPEDEF (value_type);
gdb_assert (TYPE_CODE (value_type) != TYPE_CODE_VOID);
case RETURN_VALUE_ABI_RETURNS_ADDRESS:
case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
value = allocate_value (value_type);
- gdbarch_return_value (gdbarch, func_type, value_type, stop_registers,
+ gdbarch_return_value (gdbarch, func_type, value_type, stop_regs,
value_contents_raw (value), NULL);
break;
case RETURN_VALUE_STRUCT_CONVENTION:
internal_error (__FILE__, __LINE__, _("bad switch"));
}
+ do_cleanups (cleanup);
+
+ return value;
+}
+
+/* Print the result of a function at the end of a 'finish' command. */
+
+static void
+print_return_value (struct type *func_type, struct type *value_type)
+{
+ struct value *value = get_return_value (func_type, value_type);
+ struct ui_out *uiout = current_uiout;
+
if (value)
{
struct value_print_options opts;
+ struct ui_file *stb;
+ struct cleanup *old_chain;
/* Print it. */
- stb = ui_out_stream_new (uiout);
- old_chain = make_cleanup_ui_out_stream_delete (stb);
+ stb = mem_fileopen ();
+ old_chain = make_cleanup_ui_file_delete (stb);
ui_out_text (uiout, "Value returned is ");
ui_out_field_fmt (uiout, "gdb-result-var", "$%d",
record_latest_value (value));
ui_out_text (uiout, " = ");
get_raw_print_options (&opts);
- value_print (value, stb->stream, &opts);
+ value_print (value, stb, &opts);
ui_out_field_stream (uiout, "return-value", stb);
ui_out_text (uiout, "\n");
do_cleanups (old_chain);
static void
finish_forward (struct symbol *function, struct frame_info *frame)
{
+ struct frame_id frame_id = get_frame_id (frame);
struct gdbarch *gdbarch = get_frame_arch (frame);
struct symtab_and_line sal;
struct thread_info *tp = inferior_thread ();
get_stack_frame_id (frame),
bp_finish);
+ /* set_momentary_breakpoint invalidates FRAME. */
+ frame = NULL;
+
old_chain = make_cleanup_delete_breakpoint (breakpoint);
- set_longjmp_breakpoint (tp, get_frame_id (frame));
+ set_longjmp_breakpoint (tp, frame_id);
make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
/* We want stop_registers, please... */
struct value_print_options opts;
struct value *val = value_of_user_reg (regnum, frame);
- printf_filtered ("%s: ", start);
+ printf_filtered ("%.*s: ", (int) (end - start), start);
get_formatted_print_options (&opts, 'x');
val_print_scalar_formatted (check_typedef (value_type (val)),
value_contents_for_printing (val),
help_list (unsetlist, "unset ", -1, gdb_stdout);
}
+/* Implement `info proc' family of commands. */
+
+static void
+info_proc_cmd_1 (char *args, enum info_proc_what what, int from_tty)
+{
+ struct gdbarch *gdbarch = get_current_arch ();
+
+ if (gdbarch_info_proc_p (gdbarch))
+ gdbarch_info_proc (gdbarch, args, what);
+ else
+ target_info_proc (args, what);
+}
+
+/* Implement `info proc' when given without any futher parameters. */
+
+static void
+info_proc_cmd (char *args, int from_tty)
+{
+ info_proc_cmd_1 (args, IP_MINIMAL, from_tty);
+}
+
+/* Implement `info proc mappings'. */
+
+static void
+info_proc_cmd_mappings (char *args, int from_tty)
+{
+ info_proc_cmd_1 (args, IP_MAPPINGS, from_tty);
+}
+
+/* Implement `info proc stat'. */
+
+static void
+info_proc_cmd_stat (char *args, int from_tty)
+{
+ info_proc_cmd_1 (args, IP_STAT, from_tty);
+}
+
+/* Implement `info proc status'. */
+
+static void
+info_proc_cmd_status (char *args, int from_tty)
+{
+ info_proc_cmd_1 (args, IP_STATUS, from_tty);
+}
+
+/* Implement `info proc cwd'. */
+
+static void
+info_proc_cmd_cwd (char *args, int from_tty)
+{
+ info_proc_cmd_1 (args, IP_CWD, from_tty);
+}
+
+/* Implement `info proc cmdline'. */
+
+static void
+info_proc_cmd_cmdline (char *args, int from_tty)
+{
+ info_proc_cmd_1 (args, IP_CMDLINE, from_tty);
+}
+
+/* Implement `info proc exe'. */
+
+static void
+info_proc_cmd_exe (char *args, int from_tty)
+{
+ info_proc_cmd_1 (args, IP_EXE, from_tty);
+}
+
+/* Implement `info proc all'. */
+
+static void
+info_proc_cmd_all (char *args, int from_tty)
+{
+ info_proc_cmd_1 (args, IP_ALL, from_tty);
+}
+
void
_initialize_infcmd (void)
{
+ static struct cmd_list_element *info_proc_cmdlist;
struct cmd_list_element *c = NULL;
/* Add the filename of the terminal connected to inferior I/O. */
add_info ("vector", vector_info,
_("Print the status of the vector unit\n"));
+
+ add_prefix_cmd ("proc", class_info, info_proc_cmd,
+ _("\
+Show /proc process information about any running process.\n\
+Specify any process id, or use the program being debugged by default."),
+ &info_proc_cmdlist, "info proc ",
+ 1/*allow-unknown*/, &infolist);
+
+ add_cmd ("mappings", class_info, info_proc_cmd_mappings, _("\
+List of mapped memory regions."),
+ &info_proc_cmdlist);
+
+ add_cmd ("stat", class_info, info_proc_cmd_stat, _("\
+List process info from /proc/PID/stat."),
+ &info_proc_cmdlist);
+
+ add_cmd ("status", class_info, info_proc_cmd_status, _("\
+List process info from /proc/PID/status."),
+ &info_proc_cmdlist);
+
+ add_cmd ("cwd", class_info, info_proc_cmd_cwd, _("\
+List current working directory of the process."),
+ &info_proc_cmdlist);
+
+ add_cmd ("cmdline", class_info, info_proc_cmd_cmdline, _("\
+List command line arguments of the process."),
+ &info_proc_cmdlist);
+
+ add_cmd ("exe", class_info, info_proc_cmd_exe, _("\
+List absolute filename for executable of the process."),
+ &info_proc_cmdlist);
+
+ add_cmd ("all", class_info, info_proc_cmd_all, _("\
+List all available /proc info."),
+ &info_proc_cmdlist);
}