Convert the until/advance commands to thread_fsm mechanism

gdb/ChangeLog:
2015-09-09  Pedro Alves  <palves@redhat.com>

	* breakpoint.c: Include "thread-fsm.h".
	(struct until_break_command_continuation_args): Delete.
	(struct until_break_fsm): New.
	(until_break_fsm_ops): New global.
	(new_until_break_fsm, until_break_fsm_should_stop): New functions.
	(until_break_command_continuation): Delete.
	(until_break_fsm_clean_up): New function.
	(until_break_fsm_async_reply_reason): New function.
	(until_break_command): Adjust to create an until_break_fsm instead
	of a continuation.
	(momentary_bkpt_print_it): No longer print MI's async-stop-reason
	here.
	* infcmd.c (struct until_next_fsm): New.
	(until_next_fsm_ops): New global.
	(new_until_next_fsm, until_next_fsm_should_stop): New function.
	(until_next_continuation): Delete.
	(until_next_fsm_clean_up, until_next_fsm_async_reply_reason): New
	functions.
	(until_next_command): Adjust to create a new until_next_fsm
	instead of a continuation.
This commit is contained in:
Pedro Alves
2015-09-09 18:23:24 +01:00
parent 388a708404
commit cfc3163382
3 changed files with 214 additions and 88 deletions

View File

@@ -1,3 +1,26 @@
2015-09-09 Pedro Alves <palves@redhat.com>
* breakpoint.c: Include "thread-fsm.h".
(struct until_break_command_continuation_args): Delete.
(struct until_break_fsm): New.
(until_break_fsm_ops): New global.
(new_until_break_fsm, until_break_fsm_should_stop): New functions.
(until_break_command_continuation): Delete.
(until_break_fsm_clean_up): New function.
(until_break_fsm_async_reply_reason): New function.
(until_break_command): Adjust to create an until_break_fsm instead
of a continuation.
(momentary_bkpt_print_it): No longer print MI's async-stop-reason
here.
* infcmd.c (struct until_next_fsm): New.
(until_next_fsm_ops): New global.
(new_until_next_fsm, until_next_fsm_should_stop): New function.
(until_next_continuation): Delete.
(until_next_fsm_clean_up, until_next_fsm_async_reply_reason): New
functions.
(until_next_command): Adjust to create a new until_next_fsm
instead of a continuation.
2015-09-09 Pedro Alves <palves@redhat.com>
* infcall.c: Include thread_fsm.h.

View File

@@ -68,6 +68,7 @@
#include "interps.h"
#include "format.h"
#include "location.h"
#include "thread-fsm.h"
/* readline include files */
#include "readline/readline.h"
@@ -11465,29 +11466,109 @@ awatch_command (char *arg, int from_tty)
}
/* Helper routines for the until_command routine in infcmd.c. Here
because it uses the mechanisms of breakpoints. */
/* Data for the FSM that manages the until(location)/advance commands
in infcmd.c. Here because it uses the mechanisms of
breakpoints. */
struct until_break_command_continuation_args
struct until_break_fsm
{
struct breakpoint *breakpoint;
struct breakpoint *breakpoint2;
int thread_num;
/* The base class. */
struct thread_fsm thread_fsm;
/* The thread that as current when the command was executed. */
int thread;
/* The breakpoint set at the destination location. */
struct breakpoint *location_breakpoint;
/* Breakpoint set at the return address in the caller frame. May be
NULL. */
struct breakpoint *caller_breakpoint;
};
/* This function is called by fetch_inferior_event via the
cmd_continuation pointer, to complete the until command. It takes
care of cleaning up the temporary breakpoints set up by the until
command. */
static void
until_break_command_continuation (void *arg, int err)
{
struct until_break_command_continuation_args *a = arg;
static void until_break_fsm_clean_up (struct thread_fsm *self);
static int until_break_fsm_should_stop (struct thread_fsm *self);
static enum async_reply_reason
until_break_fsm_async_reply_reason (struct thread_fsm *self);
delete_breakpoint (a->breakpoint);
if (a->breakpoint2)
delete_breakpoint (a->breakpoint2);
delete_longjmp_breakpoint (a->thread_num);
/* until_break_fsm's vtable. */
static struct thread_fsm_ops until_break_fsm_ops =
{
NULL, /* dtor */
until_break_fsm_clean_up,
until_break_fsm_should_stop,
NULL, /* return_value */
until_break_fsm_async_reply_reason,
};
/* Allocate a new until_break_command_fsm. */
static struct until_break_fsm *
new_until_break_fsm (int thread,
struct breakpoint *location_breakpoint,
struct breakpoint *caller_breakpoint)
{
struct until_break_fsm *sm;
sm = XCNEW (struct until_break_fsm);
thread_fsm_ctor (&sm->thread_fsm, &until_break_fsm_ops);
sm->thread = thread;
sm->location_breakpoint = location_breakpoint;
sm->caller_breakpoint = caller_breakpoint;
return sm;
}
/* Implementation of the 'should_stop' FSM method for the
until(location)/advance commands. */
static int
until_break_fsm_should_stop (struct thread_fsm *self)
{
struct until_break_fsm *sm = (struct until_break_fsm *) self;
struct thread_info *tp = inferior_thread ();
if (bpstat_find_breakpoint (tp->control.stop_bpstat,
sm->location_breakpoint) != NULL
|| (sm->caller_breakpoint != NULL
&& bpstat_find_breakpoint (tp->control.stop_bpstat,
sm->caller_breakpoint) != NULL))
thread_fsm_set_finished (self);
return 1;
}
/* Implementation of the 'clean_up' FSM method for the
until(location)/advance commands. */
static void
until_break_fsm_clean_up (struct thread_fsm *self)
{
struct until_break_fsm *sm = (struct until_break_fsm *) self;
/* Clean up our temporary breakpoints. */
if (sm->location_breakpoint != NULL)
{
delete_breakpoint (sm->location_breakpoint);
sm->location_breakpoint = NULL;
}
if (sm->caller_breakpoint != NULL)
{
delete_breakpoint (sm->caller_breakpoint);
sm->caller_breakpoint = NULL;
}
delete_longjmp_breakpoint (sm->thread);
}
/* Implementation of the 'async_reply_reason' FSM method for the
until(location)/advance commands. */
static enum async_reply_reason
until_break_fsm_async_reply_reason (struct thread_fsm *self)
{
return EXEC_ASYNC_LOCATION_REACHED;
}
void
@@ -11499,12 +11580,13 @@ until_break_command (char *arg, int from_tty, int anywhere)
struct gdbarch *frame_gdbarch;
struct frame_id stack_frame_id;
struct frame_id caller_frame_id;
struct breakpoint *breakpoint;
struct breakpoint *breakpoint2 = NULL;
struct breakpoint *location_breakpoint;
struct breakpoint *caller_breakpoint = NULL;
struct cleanup *old_chain, *cleanup;
int thread;
struct thread_info *tp;
struct event_location *location;
struct until_break_fsm *sm;
clear_proceed_status (0);
@@ -11554,14 +11636,16 @@ until_break_command (char *arg, int from_tty, int anywhere)
if (frame_id_p (caller_frame_id))
{
struct symtab_and_line sal2;
struct gdbarch *caller_gdbarch;
sal2 = find_pc_line (frame_unwind_caller_pc (frame), 0);
sal2.pc = frame_unwind_caller_pc (frame);
breakpoint2 = set_momentary_breakpoint (frame_unwind_caller_arch (frame),
sal2,
caller_frame_id,
bp_until);
make_cleanup_delete_breakpoint (breakpoint2);
caller_gdbarch = frame_unwind_caller_arch (frame);
caller_breakpoint = set_momentary_breakpoint (caller_gdbarch,
sal2,
caller_frame_id,
bp_until);
make_cleanup_delete_breakpoint (caller_breakpoint);
set_longjmp_breakpoint (tp, caller_frame_id);
make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
@@ -11573,39 +11657,22 @@ until_break_command (char *arg, int from_tty, int anywhere)
if (anywhere)
/* If the user told us to continue until a specified location,
we don't specify a frame at which we need to stop. */
breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
null_frame_id, bp_until);
location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
null_frame_id, bp_until);
else
/* Otherwise, specify the selected frame, because we want to stop
only at the very same frame. */
breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
stack_frame_id, bp_until);
make_cleanup_delete_breakpoint (breakpoint);
location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal,
stack_frame_id, bp_until);
make_cleanup_delete_breakpoint (location_breakpoint);
sm = new_until_break_fsm (tp->num, location_breakpoint, caller_breakpoint);
tp->thread_fsm = &sm->thread_fsm;
discard_cleanups (old_chain);
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
be deleted when the target stops. Otherwise, we're already
stopped and delete breakpoints via cleanup chain. */
if (is_running (inferior_ptid))
{
struct until_break_command_continuation_args *args =
XNEW (struct until_break_command_continuation_args);
args->breakpoint = breakpoint;
args->breakpoint2 = breakpoint2;
args->thread_num = thread;
discard_cleanups (old_chain);
add_continuation (inferior_thread (),
until_break_command_continuation, args,
xfree);
}
else
do_cleanups (old_chain);
do_cleanups (cleanup);
}
@@ -13195,22 +13262,6 @@ momentary_bkpt_check_status (bpstat bs)
static enum print_stop_action
momentary_bkpt_print_it (bpstat bs)
{
struct ui_out *uiout = current_uiout;
if (ui_out_is_mi_like_p (uiout))
{
struct breakpoint *b = bs->breakpoint_at;
switch (b->type)
{
case bp_until:
ui_out_field_string
(uiout, "reason",
async_reason_lookup (EXEC_ASYNC_LOCATION_REACHED));
break;
}
}
return PRINT_UNKNOWN;
}

View File

@@ -1385,22 +1385,81 @@ queue_signal_command (char *signum_exp, int from_tty)
tp->suspend.stop_signal = oursig;
}
/* Continuation args to be passed to the "until" command
continuation. */
struct until_next_continuation_args
/* Data for the FSM that manages the until (with no argument)
command. */
struct until_next_fsm
{
/* The thread that was current when the command was executed. */
/* The base class. */
struct thread_fsm thread_fsm;
/* The thread that as current when the command was executed. */
int thread;
};
/* A continuation callback for until_next_command. */
static int until_next_fsm_should_stop (struct thread_fsm *self);
static void until_next_fsm_clean_up (struct thread_fsm *self);
static enum async_reply_reason
until_next_fsm_async_reply_reason (struct thread_fsm *self);
/* until_next_fsm's vtable. */
static struct thread_fsm_ops until_next_fsm_ops =
{
NULL, /* dtor */
until_next_fsm_clean_up,
until_next_fsm_should_stop,
NULL, /* return_value */
until_next_fsm_async_reply_reason,
};
/* Allocate a new until_next_fsm. */
static struct until_next_fsm *
new_until_next_fsm (int thread)
{
struct until_next_fsm *sm;
sm = XCNEW (struct until_next_fsm);
thread_fsm_ctor (&sm->thread_fsm, &until_next_fsm_ops);
sm->thread = thread;
return sm;
}
/* Implementation of the 'should_stop' FSM method for the until (with
no arg) command. */
static int
until_next_fsm_should_stop (struct thread_fsm *self)
{
struct thread_info *tp = inferior_thread ();
if (tp->control.stop_step)
thread_fsm_set_finished (self);
return 1;
}
/* Implementation of the 'clean_up' FSM method for the until (with no
arg) command. */
static void
until_next_continuation (void *arg, int err)
until_next_fsm_clean_up (struct thread_fsm *self)
{
struct until_next_continuation_args *a = arg;
struct until_next_fsm *sm = (struct until_next_fsm *) self;
delete_longjmp_breakpoint (a->thread);
delete_longjmp_breakpoint (sm->thread);
}
/* Implementation of the 'async_reply_reason' FSM method for the until
(with no arg) command. */
static enum async_reply_reason
until_next_fsm_async_reply_reason (struct thread_fsm *self)
{
return EXEC_ASYNC_END_STEPPING_RANGE;
}
/* Proceed until we reach a different source line with pc greater than
@@ -1421,6 +1480,7 @@ until_next_command (int from_tty)
struct thread_info *tp = inferior_thread ();
int thread = tp->num;
struct cleanup *old_chain;
struct until_next_fsm *sm;
clear_proceed_status (0);
set_step_frame ();
@@ -1460,20 +1520,12 @@ until_next_command (int from_tty)
set_longjmp_breakpoint (tp, get_frame_id (frame));
old_chain = make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
sm = new_until_next_fsm (tp->num);
tp->thread_fsm = &sm->thread_fsm;
discard_cleanups (old_chain);
proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
if (is_running (inferior_ptid))
{
struct until_next_continuation_args *cont_args;
discard_cleanups (old_chain);
cont_args = XNEW (struct until_next_continuation_args);
cont_args->thread = inferior_thread ()->num;
add_continuation (tp, until_next_continuation, cont_args, xfree);
}
else
do_cleanups (old_chain);
}
static void