mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-28 18:10:46 +00:00
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:
@@ -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.
|
||||
|
||||
187
gdb/breakpoint.c
187
gdb/breakpoint.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
92
gdb/infcmd.c
92
gdb/infcmd.c
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user