infrun.c: Split handle_inferior_event further.

After the previous patches, we only ever reach the code after the
initial 'switch (ecs->ws.kind)' switch for TARGET_WAITKIND_STOPPED.
We can now factor out all that to its own function.

Unfortunately, stepped_after_stopped_by_watchpoint needed to move to
the ecs.  I think that indicates a state machine bug -- no event other
than TARGET_WAITKIND_STOPPED indicates a single-step actually
finished.  TARGET_WAITKIND_SYSCALL_XXX, TARGET_WAITKIND_FORK, etc. are
all events that are triggered from the kernel, _within_ a syscall,
IOW, from userspace's perspective, halfway through an instruction
being executed.  This might actually matter for the syscall events, as
syscalls can change memory (and thus trigger watchpoints).

gdb/
2013-11-14  Pedro Alves  <palves@redhat.com>

	* infrun.c (struct execution_control_state)
	<stepped_after_stopped_by_watchpoint>: New field.
	(get_inferior_stop_soon): New function.
	(handle_inferior_event): 'stepped_after_stopped_by_watchpoint' was
	moved to struct execution_control_state -- adjust.  Use
	get_inferior_stop_soon.  Split TARGET_WAITKIND_STOPPED handling to
	new function.
	(handle_signal_stop): New function, factored out from
	handle_inferior_event.
This commit is contained in:
Pedro Alves 2013-11-14 19:43:27 +00:00
parent 47591c29ad
commit 4f5d7f635c
2 changed files with 50 additions and 21 deletions

View File

@ -1,3 +1,15 @@
2013-11-14 Pedro Alves <palves@redhat.com>
* infrun.c (struct execution_control_state)
<stepped_after_stopped_by_watchpoint>: New field.
(get_inferior_stop_soon): New function.
(handle_inferior_event): 'stepped_after_stopped_by_watchpoint' was
moved to struct execution_control_state -- adjust. Use
get_inferior_stop_soon. Split TARGET_WAITKIND_STOPPED handling to
new function.
(handle_signal_stop): New function, factored out from
handle_inferior_event.
2013-11-14 Pedro Alves <palves@redhat.com>
* break-catch-sig.c (signal_catchpoint_explains_signal): Adjust to

View File

@ -2424,6 +2424,11 @@ struct execution_control_state
CORE_ADDR stop_func_end;
const char *stop_func_name;
int wait_some_more;
/* We were in infwait_step_watch_state or
infwait_nonstep_watch_state state, and the thread reported an
event. */
int stepped_after_stopped_by_watchpoint;
};
static void handle_inferior_event (struct execution_control_state *ecs);
@ -2432,6 +2437,7 @@ static void handle_step_into_function (struct gdbarch *gdbarch,
struct execution_control_state *ecs);
static void handle_step_into_function_backward (struct gdbarch *gdbarch,
struct execution_control_state *ecs);
static void handle_signal_stop (struct execution_control_state *ecs);
static void check_exception_resume (struct execution_control_state *,
struct frame_info *);
@ -3132,6 +3138,18 @@ fill_in_stop_func (struct gdbarch *gdbarch,
}
}
/* Return the STOP_SOON field of the inferior pointed at by PTID. */
static enum stop_kind
get_inferior_stop_soon (ptid_t ptid)
{
struct inferior *inf = find_inferior_pid (ptid_get_pid (ptid));
gdb_assert (inf != NULL);
return inf->control.stop_soon;
}
/* Given an execution control state that has been freshly filled in by
an event from the inferior, figure out what it means and take
appropriate action.
@ -3148,12 +3166,7 @@ fill_in_stop_func (struct gdbarch *gdbarch,
static void
handle_inferior_event (struct execution_control_state *ecs)
{
struct frame_info *frame;
struct gdbarch *gdbarch;
int stopped_by_watchpoint;
int stepped_after_stopped_by_watchpoint = 0;
enum stop_kind stop_soon;
int random_signal;
if (ecs->ws.kind == TARGET_WAITKIND_IGNORE)
{
@ -3187,18 +3200,6 @@ handle_inferior_event (struct execution_control_state *ecs)
return;
}
if (ecs->ws.kind != TARGET_WAITKIND_EXITED
&& ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
&& ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED)
{
struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid));
gdb_assert (inf);
stop_soon = inf->control.stop_soon;
}
else
stop_soon = NO_STOP_QUIETLY;
/* Cache the last pid/waitstatus. */
target_last_wait_ptid = ecs->ptid;
target_last_waitstatus = ecs->ws;
@ -3295,7 +3296,7 @@ handle_inferior_event (struct execution_control_state *ecs)
fprintf_unfiltered (gdb_stdlog,
"infrun: infwait_step_watch_state\n");
stepped_after_stopped_by_watchpoint = 1;
ecs->stepped_after_stopped_by_watchpoint = 1;
break;
case infwait_nonstep_watch_state:
@ -3307,7 +3308,7 @@ handle_inferior_event (struct execution_control_state *ecs)
/* FIXME-maybe: is this cleaner than setting a flag? Does it
handle things like signals arriving and other things happening
in combination correctly? */
stepped_after_stopped_by_watchpoint = 1;
ecs->stepped_after_stopped_by_watchpoint = 1;
break;
default:
@ -3330,6 +3331,8 @@ handle_inferior_event (struct execution_control_state *ecs)
the beginning of an attach or remote session; we will query
the full list of libraries once the connection is
established. */
stop_soon = get_inferior_stop_soon (ecs->ptid);
if (stop_soon == NO_STOP_QUIETLY)
{
struct regcache *regcache;
@ -3715,7 +3718,8 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_STOPPED\n");
ecs->event_thread->suspend.stop_signal = ecs->ws.value.sig;
break;
handle_signal_stop (ecs);
return;
case TARGET_WAITKIND_NO_HISTORY:
if (debug_infrun)
@ -3735,6 +3739,18 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
stop_stepping (ecs);
return;
}
}
/* Come here when the program has stopped with a signal. */
static void
handle_signal_stop (struct execution_control_state *ecs)
{
struct frame_info *frame;
struct gdbarch *gdbarch;
int stopped_by_watchpoint;
enum stop_kind stop_soon;
int random_signal;
if (ecs->ws.kind == TARGET_WAITKIND_STOPPED)
{
@ -4022,7 +4038,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
singlestep_breakpoints_inserted_p = 0;
}
if (stepped_after_stopped_by_watchpoint)
if (ecs->stepped_after_stopped_by_watchpoint)
stopped_by_watchpoint = 0;
else
stopped_by_watchpoint = watchpoints_triggered (&ecs->ws);
@ -4167,6 +4183,7 @@ Cannot fill $_exitsignal with the correct signal number.\n"));
/* This is originated from start_remote(), start_inferior() and
shared libraries hook functions. */
stop_soon = get_inferior_stop_soon (ecs->ptid);
if (stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_REMOTE)
{
if (debug_infrun)