From: Pedro Alves <palves@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 4/7] Convert the until/advance commands to thread_fsm mechanism
Date: Wed, 12 Aug 2015 17:02:00 -0000 [thread overview]
Message-ID: <1439398917-22761-5-git-send-email-palves@redhat.com> (raw)
In-Reply-To: <1439398917-22761-1-git-send-email-palves@redhat.com>
gdb/ChangeLog:
2015-08-12 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.
---
gdb/breakpoint.c | 181 +++++++++++++++++++++++++++++++++++--------------------
gdb/infcmd.c | 92 ++++++++++++++++++++++------
2 files changed, 188 insertions(+), 85 deletions(-)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index ef04bde..eb15e58 100644
--- a/gdb/breakpoint.c
+++ b/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"
@@ -11467,29 +11468,109 @@ awatch_command (char *arg, int from_tty)
}
\f
-/* 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_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);
+
+/* 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_command_continuation (void *arg, int err)
+until_break_fsm_clean_up (struct thread_fsm *self)
{
- struct until_break_command_continuation_args *a = arg;
+ struct until_break_fsm *sm = (struct until_break_fsm *) self;
- delete_breakpoint (a->breakpoint);
- if (a->breakpoint2)
- delete_breakpoint (a->breakpoint2);
- delete_longjmp_breakpoint (a->thread_num);
+ /* 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
@@ -11501,12 +11582,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);
@@ -11556,14 +11638,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);
@@ -11575,38 +11659,21 @@ 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);
- proceed (-1, GDB_SIGNAL_DEFAULT);
+ sm = new_until_break_fsm (tp->num, location_breakpoint, caller_breakpoint);
+ tp->thread_fsm = &sm->thread_fsm;
- /* 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;
- args = xmalloc (sizeof (*args));
-
- args->breakpoint = breakpoint;
- args->breakpoint2 = breakpoint2;
- args->thread_num = thread;
+ discard_cleanups (old_chain);
- discard_cleanups (old_chain);
- add_continuation (inferior_thread (),
- until_break_command_continuation, args,
- xfree);
- }
- else
- do_cleanups (old_chain);
+ proceed (-1, GDB_SIGNAL_DEFAULT);
do_cleanups (cleanup);
}
@@ -13198,22 +13265,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;
}
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 67b5df0..e5d01ff 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1388,22 +1388,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
@@ -1424,6 +1483,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 ();
@@ -1463,20 +1523,12 @@ until_next_command (int from_tty)
set_longjmp_breakpoint (tp, get_frame_id (frame));
old_chain = make_cleanup (delete_longjmp_breakpoint_cleanup, &thread);
- proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
-
- if (is_running (inferior_ptid))
- {
- struct until_next_continuation_args *cont_args;
+ sm = new_until_next_fsm (tp->num);
+ tp->thread_fsm = &sm->thread_fsm;
+ discard_cleanups (old_chain);
- discard_cleanups (old_chain);
- cont_args = XNEW (struct until_next_continuation_args);
- cont_args->thread = inferior_thread ()->num;
+ proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
- add_continuation (tp, until_next_continuation, cont_args, xfree);
- }
- else
- do_cleanups (old_chain);
}
static void
--
1.9.3
next prev parent reply other threads:[~2015-08-12 17:02 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-12 17:02 [PATCH 0/7] Replace continuations with an extendable "class" Pedro Alves
2015-08-12 17:02 ` [PATCH 3/7] Convert infcalls to thread_fsm mechanism Pedro Alves
2015-08-12 17:02 ` [PATCH 2/7] Replace "struct continuation" mechanism by something more extensible Pedro Alves
2015-08-18 12:50 ` Yao Qi
2015-08-19 14:55 ` Pedro Alves
2015-08-12 17:02 ` Pedro Alves [this message]
2015-08-12 17:02 ` [PATCH 1/7] Merge async and sync code paths some more Pedro Alves
2015-08-12 19:48 ` Simon Marchi
2015-08-17 17:54 ` Pedro Alves
2015-08-17 19:28 ` Simon Marchi
2015-08-18 10:48 ` Yao Qi
2015-08-19 14:11 ` Pedro Alves
2015-08-27 13:26 ` Yao Qi
2015-10-16 0:35 ` Joel Brobecker
2015-10-16 12:24 ` Pedro Alves
2015-10-16 16:22 ` Joel Brobecker
2015-10-16 16:37 ` Pedro Alves
2015-10-16 17:05 ` Joel Brobecker
2015-10-22 16:18 ` Pedro Alves
2015-08-12 17:11 ` [PATCH 7/7] Delete enum inferior_event_handler::INF_TIMER Pedro Alves
2015-08-18 11:22 ` Yao Qi
2015-08-12 17:11 ` [PATCH 5/7] Garbage collect dummy_frame_ctx_saver Pedro Alves
2015-08-12 17:11 ` [PATCH 6/7] Garbage collect thread continuations Pedro Alves
2015-08-18 12:52 ` [PATCH 0/7] Replace continuations with an extendable "class" Yao Qi
2015-08-19 14:56 ` Pedro Alves
2015-09-09 17:33 ` Pedro Alves
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1439398917-22761-5-git-send-email-palves@redhat.com \
--to=palves@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox