#include "continuations.h"
#include "linespec.h"
#include "cli/cli-utils.h"
+#include "infcall.h"
/* Local functions: */
static void nofp_registers_info (char *, int);
-static void print_return_value (struct value *function,
- struct type *value_type);
-
static void until_next_command (int);
static void until_command (char *, int);
static void run_command (char *, int);
-static void run_no_args_command (char *args, int from_tty);
-
-static void go_command (char *line_no, int from_tty);
-
void _initialize_infcmd (void);
#define ERROR_NO_INFERIOR \
/* Start the target running. Do not use -1 continuation as it would skip
breakpoint right at the entry point. */
- proceed (regcache_read_pc (get_current_regcache ()), GDB_SIGNAL_0, 0);
+ proceed (regcache_read_pc (get_current_regcache ()), GDB_SIGNAL_0);
/* Since there was no error, there's no need to finish the thread
states here. */
run_command_1 (args, from_tty, 0);
}
-static void
-run_no_args_command (char *args, int from_tty)
-{
- set_inferior_args ("");
-}
-\f
-
/* Start the execution of the program up until the beginning of the main
program. */
switch_to_thread (thread->ptid);
clear_proceed_status (0);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
return 0;
}
ensure_valid_thread ();
ensure_not_running ();
clear_proceed_status (0);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
}
}
set_step_frame (void)
{
struct symtab_and_line sal;
+ CORE_ADDR pc;
+ struct frame_info *frame = get_current_frame ();
+ struct thread_info *tp = inferior_thread ();
- find_frame_sal (get_current_frame (), &sal);
- set_step_info (get_current_frame (), sal);
+ find_frame_sal (frame, &sal);
+ set_step_info (frame, sal);
+ pc = get_frame_pc (frame);
+ tp->control.step_start_function = find_pc_function (pc);
}
/* Step until outside of current statement. */
tp->step_multi = (count > 1);
tp->control.stepping_command = 1;
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
/* For async targets, register a continuation to do any
additional steps. For sync targets, the caller will handle
}
clear_proceed_status (0);
- 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 (line_no == (char *) NULL || !*line_no)
- printf_filtered (_("Usage: go <location>\n"));
- else
- {
- tbreak_command (line_no, from_tty);
- jump_command (line_no, from_tty);
- }
+ proceed (addr, GDB_SIGNAL_0);
}
\f
-
/* Continue program giving it specified signal. */
static void
oursig = gdb_signal_from_command (num);
}
+ do_cleanups (args_chain);
+
/* Look for threads other than the current that this command ends up
resuming too (due to schedlock off), and warn if they'll get a
signal delivered. "signal 0" is used to suppress a previous
}
clear_proceed_status (0);
- proceed ((CORE_ADDR) -1, oursig, 0);
+ proceed ((CORE_ADDR) -1, oursig);
}
/* Queue a signal to be delivered to the current thread. */
set_longjmp_breakpoint (tp, get_frame_id (frame));
old_chain = make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
if (target_can_async_p () && is_running (inferior_ptid))
{
}
\f
/* Return the value of the result of a function at the end of a 'finish'
- command/BP. */
+ command/BP. DTOR_DATA (if not NULL) can represent inferior registers
+ right after an inferior call has finished. */
struct value *
-get_return_value (struct value *function, struct type *value_type)
+get_return_value (struct value *function, struct type *value_type,
+ struct dummy_frame_context_saver *ctx_saver)
{
- struct regcache *stop_regs = stop_registers;
+ struct regcache *stop_regs = NULL;
struct gdbarch *gdbarch;
struct value *value;
struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
- /* If stop_registers were not saved, use the current registers. */
- if (!stop_regs)
+ /* If registers were not saved, use the current registers. */
+ if (ctx_saver != NULL)
+ stop_regs = dummy_frame_context_saver_get_regs (ctx_saver);
+ else
{
stop_regs = regcache_dup (get_current_regcache ());
make_cleanup_regcache_xfree (stop_regs);
gdbarch = get_regcache_arch (stop_regs);
- CHECK_TYPEDEF (value_type);
+ value_type = check_typedef (value_type);
gdb_assert (TYPE_CODE (value_type) != TYPE_CODE_VOID);
/* FIXME: 2003-09-27: When returning from a nested inferior function
return value;
}
-/* Print the result of a function at the end of a 'finish' command. */
+/* Print the result of a function at the end of a 'finish' command.
+ DTOR_DATA (if not NULL) can represent inferior registers right after
+ an inferior call has finished. */
static void
-print_return_value (struct value *function, struct type *value_type)
+print_return_value (struct value *function, struct type *value_type,
+ struct dummy_frame_context_saver *ctx_saver)
{
- struct value *value = get_return_value (function, value_type);
+ struct value *value = get_return_value (function, value_type, ctx_saver);
struct ui_out *uiout = current_uiout;
if (value)
int thread;
struct breakpoint *breakpoint;
struct symbol *function;
+
+ /* Inferior registers stored right before dummy_frame has been freed
+ after an inferior call. It can be NULL if no inferior call was
+ involved, GDB will then use current inferior registers. */
+ struct dummy_frame_context_saver *ctx_saver;
};
static void
/* print_return_value can throw an exception in some
circumstances. We need to catch this so that we still
delete the breakpoint. */
- print_return_value (func, value_type);
+ print_return_value (func, value_type, a->ctx_saver);
}
CATCH (ex, RETURN_MASK_ALL)
{
static void
finish_command_continuation_free_arg (void *arg)
{
- xfree (arg);
+ struct finish_command_continuation_args *cargs = arg;
+
+ if (cargs->ctx_saver != NULL)
+ dummy_frame_context_saver_drop (cargs->ctx_saver);
+ xfree (cargs);
}
/* finish_backward -- helper function for finish_command. */
insert_step_resume_breakpoint_at_sal (gdbarch,
sr_sal, null_frame_id);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
}
else
{
/* We're almost there -- we just need to back up by one more
single-step. */
tp->control.step_range_start = tp->control.step_range_end = 1;
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
}
}
struct symtab_and_line sal;
struct thread_info *tp = inferior_thread ();
struct breakpoint *breakpoint;
- struct cleanup *old_chain;
+ struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
struct finish_command_continuation_args *cargs;
int thread = tp->num;
+ struct dummy_frame_context_saver *saver = NULL;
sal = find_pc_line (get_frame_pc (frame), 0);
sal.pc = get_frame_pc (frame);
+ if (get_frame_type (frame) == DUMMY_FRAME)
+ {
+ saver = dummy_frame_context_saver_setup (get_stack_frame_id (frame),
+ inferior_ptid);
+ make_cleanup (dummy_frame_context_saver_cleanup, saver);
+ }
+
breakpoint = set_momentary_breakpoint (gdbarch, sal,
get_stack_frame_id (frame),
bp_finish);
/* set_momentary_breakpoint invalidates FRAME. */
frame = NULL;
- old_chain = make_cleanup_delete_breakpoint (breakpoint);
+ make_cleanup_delete_breakpoint (breakpoint);
set_longjmp_breakpoint (tp, frame_id);
make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
- /* We want stop_registers, please... */
+ /* We want to print return value, please... */
tp->control.proceed_to_finish = 1;
cargs = xmalloc (sizeof (*cargs));
cargs->thread = thread;
cargs->breakpoint = breakpoint;
cargs->function = function;
+ cargs->ctx_saver = saver;
add_continuation (tp, finish_command_continuation, cargs,
finish_command_continuation_free_arg);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
discard_cleanups (old_chain);
if (!target_can_async_p ())
print_stack_frame (get_selected_frame (NULL), 1, LOCATION, 0);
}
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 1);
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
return;
}
{
switch_to_thread (thread->ptid);
clear_proceed_status (0);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
}
return 0;
static void
attach_command_post_wait (char *args, int from_tty, int async_exec)
{
- char *exec_file;
- char *full_exec_path = NULL;
struct inferior *inferior;
inferior = current_inferior ();
/* If no exec file is yet known, try to determine it from the
process itself. */
- exec_file = (char *) get_exec_file (0);
- if (!exec_file)
- {
- 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
- filename. Some targets, such as HP-UX, don't provide the
- full path, sigh.
-
- Attempt to qualify the filename against the source path.
- (If that fails, we'll just fall back on the original
- filename. Not much more we can do...) */
-
- if (!source_full_path_of (exec_file, &full_exec_path))
- full_exec_path = xstrdup (exec_file);
-
- exec_file_attach (full_exec_path, from_tty);
- symbol_file_add_main (full_exec_path, from_tty);
- }
- }
+ if (get_exec_file (0) == NULL)
+ exec_file_locate_attach (ptid_get_pid (inferior_ptid), from_tty);
else
{
reopen_exec_file ();
if (inferior_thread ()->suspend.stop_signal == GDB_SIGNAL_0)
{
clear_proceed_status (0);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
}
}
}
selected thread is stopped, others may still be executing.
Be sure to explicitly stop all threads of the process. This
should have no effect on already stopped threads. */
- if (non_stop)
+ if (target_is_non_stop_p ())
target_stop (pid_to_ptid (inferior->pid));
/* Tell the user/frontend where we're stopped. */
shouldn't refer to attach_target again. */
attach_target = NULL;
- /* Done with ARGS. */
- do_cleanups (args_chain);
-
/* Set up the "saved terminal modes" of the inferior
based on what modes we are starting it with. */
target_terminal_init ();
init_wait_for_inferior ();
clear_proceed_status (0);
- if (non_stop)
+ if (target_is_non_stop_p ())
{
/* If we find that the current thread isn't stopped, explicitly
do so now, because we're going to install breakpoints and
a->async_exec = async_exec;
add_inferior_continuation (attach_command_continuation, a,
attach_command_continuation_free_args);
+
+ /* Done with ARGS. */
+ do_cleanups (args_chain);
+
return;
}
wait_for_inferior ();
}
+ /* Done with ARGS. */
+ do_cleanups (args_chain);
+
attach_command_post_wait (args, from_tty, async_exec);
}
ptid = minus_one_ptid;
else
ptid = inferior_ptid;
- target_stop (ptid);
+ target_interrupt (ptid);
/* Tag the thread as having been explicitly requested to stop, so
other parts of gdb know not to resume this thread automatically,
this command does not enter the subroutine, but instead steps over\n\
the call, in effect treating it as a single source line."));
add_com_alias ("n", "next", class_run, 1);
- if (xdb_commands)
- add_com_alias ("S", "next", class_run, 1);
add_com ("step", class_run, step_command, _("\
Step program until it reaches a different source line.\n\
set_cmd_completer (c, location_completer);
add_com_alias ("j", "jump", class_run, 1);
- if (xdb_commands)
- {
- c = add_com ("go", class_run, go_command, _("\
-Usage: go <location>\n\
-Continue program being debugged, stopping at specified line or \n\
-address.\n\
-Give as argument either LINENUM or *ADDR, where ADDR is an \n\
-expression for an address to start at.\n\
-This command is a combination of tbreak and jump."));
- set_cmd_completer (c, location_completer);
- }
-
- if (xdb_commands)
- add_com_alias ("g", "go", class_run, 1);
-
add_com ("continue", class_run, continue_command, _("\
Continue program being debugged, after signal or breakpoint.\n\
Usage: continue [N]\n\
use \"set args\" without arguments."));
set_cmd_completer (c, filename_completer);
add_com_alias ("r", "run", class_run, 1);
- if (xdb_commands)
- add_com ("R", class_run, run_no_args_command,
- _("Start debugged program with no arguments."));
c = add_com ("start", class_run, start_command, _("\
Run the debugged program until the beginning of the main procedure.\n\
add_info_alias ("r", "registers", 1);
set_cmd_completer (c, reg_or_group_completer);
- if (xdb_commands)
- {
- c = add_com ("lr", class_info, nofp_registers_info, _("\
-List of integer registers and their contents, for selected stack frame.\n\
-Register name as argument means describe only that register."));
- set_cmd_completer (c, reg_or_group_completer);
- }
-
c = add_info ("all-registers", all_registers_info, _("\
List of all registers and their contents, for selected stack frame.\n\
Register name as argument means describe only that register."));