2015-03-24 Pedro Alves <palves@redhat.com>
+ * breakpoint.c (until_break_command): Adjust call to proceed.
+ * gdbthread.h (struct thread_control_state) <stepping_command>:
+ New field.
+ * infcall.c (run_inferior_call): Adjust call to proceed.
+ * infcmd.c (run_command_1, proceed_thread_callback, continue_1):
+ Adjust calls to proceed.
+ (set_step_frame): Set the current thread's step_start_function
+ here.
+ (step_once): Adjust calls to proceed.
+ (jump_command, signal_command, until_next_command)
+ (finish_backward, finish_forward, proceed_after_attach_callback)
+ (attach_command_post_wait): Adjust calls to proceed.
+ * infrun.c (proceed_after_vfork_done): Adjust call to proceed.
+ (do_target_resume): New function, factored out from ...
+ (resume): ... here. Remove 'step' parameter. Instead, check
+ currently_stepping to determine whether the thread should be
+ single-stepped.
+ (proceed): Remove 'step' parameter and don't set the thread's
+ step_start_function here. Adjust call to 'resume'.
+ (handle_inferior_event): Adjust calls to 'resume'.
+ (switch_back_to_stepped_thread): Use do_target_resume instead of
+ 'resume'.
+ (keep_going): Adjust calls to 'resume'.
+ * infrun.h (proceed): Remove 'step' parameter.
+ (resume): Likewise.
+ * windows-nat.c (do_initial_windows_stuff): Adjust call to
+ 'resume'.
+ * mi/mi-main.c (proceed_thread): Adjust call to 'proceed'.
+
+2015-03-24 Pedro Alves <palves@redhat.com>
+
* gdbthread.h (struct thread_control_state) <stepping_command>:
New field.
* infcmd.c (step_once): Pass step=1 to clear_proceed_status. Set
stack_frame_id, bp_until);
make_cleanup_delete_breakpoint (breakpoint);
- proceed (-1, GDB_SIGNAL_DEFAULT, 0);
+ proceed (-1, GDB_SIGNAL_DEFAULT);
/* If we are running asynchronously, and proceed call above has
actually managed to start the target, arrange for breakpoints to
{
int was_sync = sync_execution;
- proceed (real_pc, GDB_SIGNAL_0, 0);
+ proceed (real_pc, GDB_SIGNAL_0);
/* Inferior function calls are always synchronous, even if the
target supports asynchronous execution. Do here what
/* 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. */
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);
+ proceed (addr, GDB_SIGNAL_0);
}
\f
}
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))
{
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);
}
}
cargs->function = function;
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;
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);
}
}
}
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;
return resume_ptid;
}
+/* Wrapper for target_resume, that handles infrun-specific
+ bookkeeping. */
+
+static void
+do_target_resume (ptid_t resume_ptid, int step, enum gdb_signal sig)
+{
+ struct thread_info *tp = inferior_thread ();
+
+ /* Install inferior's terminal modes. */
+ target_terminal_inferior ();
+
+ /* Avoid confusing the next resume, if the next stop/resume
+ happens to apply to another thread. */
+ tp->suspend.stop_signal = GDB_SIGNAL_0;
+
+ /* Advise target which signals may be handled silently. If we have
+ removed breakpoints because we are stepping over one (in any
+ thread), we need to receive all signals to avoid accidentally
+ skipping a breakpoint during execution of a signal handler. */
+ if (step_over_info_valid_p ())
+ target_pass_signals (0, NULL);
+ else
+ target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
+
+ target_resume (resume_ptid, step, sig);
+}
+
/* Resume the inferior, but allow a QUIT. This is useful if the user
wants to interrupt some lengthy single-stepping operation
(for child processes, the SIGINT goes to the inferior, and so
SIG is the signal to give the inferior (zero for none). */
void
-resume (int step, enum gdb_signal sig)
+resume (enum gdb_signal sig)
{
struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
struct regcache *regcache = get_current_regcache ();
deciding whether "set scheduler-locking step" applies, it's the
user's intention that counts. */
const int user_step = tp->control.stepping_command;
+ /* This represents what we'll actually request the target to do.
+ This can decay from a step to a continue, if e.g., we need to
+ implement single-stepping with breakpoints (software
+ single-step). */
+ int step = currently_stepping (tp);
tp->stepped_breakpoint = 0;
gdb_assert (pc_in_thread_step_range (pc, tp));
}
- /* Install inferior's terminal modes. */
- target_terminal_inferior ();
-
- /* Avoid confusing the next resume, if the next stop/resume
- happens to apply to another thread. */
- tp->suspend.stop_signal = GDB_SIGNAL_0;
-
- /* Advise target which signals may be handled silently. If we have
- removed breakpoints because we are stepping over one (in any
- thread), we need to receive all signals to avoid accidentally
- skipping a breakpoint during execution of a signal handler. */
- if (step_over_info_valid_p ())
- target_pass_signals (0, NULL);
- else
- target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
-
- target_resume (resume_ptid, step, sig);
-
+ do_target_resume (resume_ptid, step, sig);
discard_cleanups (old_cleanups);
}
\f
You should call clear_proceed_status before calling proceed. */
void
-proceed (CORE_ADDR addr, enum gdb_signal siggnal, int step)
+proceed (CORE_ADDR addr, enum gdb_signal siggnal)
{
struct regcache *regcache;
struct gdbarch *gdbarch;
pc = regcache_read_pc (regcache);
tp = inferior_thread ();
- if (step)
- tp->control.step_start_function = find_pc_function (pc);
-
/* Fill in with reasonable starting values. */
init_thread_stepping_state (tp);
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
- "infrun: proceed (addr=%s, signal=%s, step=%d)\n",
+ "infrun: proceed (addr=%s, signal=%s)\n",
paddress (gdbarch, addr),
- gdb_signal_to_symbol_string (siggnal), step);
+ gdb_signal_to_symbol_string (siggnal));
if (non_stop)
/* In non-stop, each thread is handled individually. The context
tp->prev_pc = regcache_read_pc (get_current_regcache ());
/* Resume inferior. */
- resume (tp->control.trap_expected || step || bpstat_should_step (),
- tp->suspend.stop_signal);
+ resume (tp->suspend.stop_signal);
/* Wait for it to stop (if not standalone)
and in any case decode why it stopped, and act accordingly. */
addresses. Make sure new breakpoints are inserted. */
if (stop_soon == NO_STOP_QUIETLY)
insert_breakpoints ();
- resume (0, GDB_SIGNAL_0);
+ resume (GDB_SIGNAL_0);
prepare_to_wait (ecs);
return;
}
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SPURIOUS\n");
if (!ptid_equal (ecs->ptid, inferior_ptid))
context_switch (ecs->ptid);
- resume (0, GDB_SIGNAL_0);
+ resume (GDB_SIGNAL_0);
prepare_to_wait (ecs);
return;
if (stop_pc != tp->prev_pc)
{
+ ptid_t resume_ptid;
+
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: expected thread advanced also\n");
insert_single_step_breakpoint (get_frame_arch (frame),
get_frame_address_space (frame),
stop_pc);
- ecs->event_thread->control.trap_expected = 1;
- resume (0, GDB_SIGNAL_0);
+ resume_ptid = user_visible_resume_ptid (tp->control.stepping_command);
+ do_target_resume (resume_ptid,
+ currently_stepping (tp), GDB_SIGNAL_0);
prepare_to_wait (ecs);
}
else
are supposed to pass through to the inferior. Simply
continue. */
discard_cleanups (old_cleanups);
- resume (currently_stepping (ecs->event_thread),
- ecs->event_thread->suspend.stop_signal);
+ resume (ecs->event_thread->suspend.stop_signal);
}
else
{
ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
discard_cleanups (old_cleanups);
- resume (currently_stepping (ecs->event_thread),
- ecs->event_thread->suspend.stop_signal);
+ resume (ecs->event_thread->suspend.stop_signal);
}
prepare_to_wait (ecs);
step/stepi command. */
extern void clear_proceed_status (int step);
-extern void proceed (CORE_ADDR, enum gdb_signal, int);
+extern void proceed (CORE_ADDR, enum gdb_signal);
/* The `resume' routine should only be called in special circumstances.
Normally, use `proceed', which handles a lot of bookkeeping. */
-extern void resume (int, enum gdb_signal);
+extern void resume (enum gdb_signal);
/* Return a ptid representing the set of threads that we will proceed,
in the perspective of the user/frontend. */
switch_to_thread (thread->ptid);
clear_proceed_status (0);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
}
static int
wait_for_inferior ();
tp = inferior_thread ();
if (tp->suspend.stop_signal != GDB_SIGNAL_TRAP)
- resume (0, tp->suspend.stop_signal);
+ resume (tp->suspend.stop_signal);
else
break;
}