From cfc3163382898a537c742bee1bf8240b3c09df35 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 9 Sep 2015 18:23:24 +0100 Subject: [PATCH] Convert the until/advance commands to thread_fsm mechanism gdb/ChangeLog: 2015-09-09 Pedro Alves * 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/ChangeLog | 23 +++++++ gdb/breakpoint.c | 181 +++++++++++++++++++++++++++++++++++-------------------- gdb/infcmd.c | 92 ++++++++++++++++++++++------ 3 files changed, 211 insertions(+), 85 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f6fa8ec..81ba492 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,28 @@ 2015-09-09 Pedro Alves + * 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 + * infcall.c: Include thread_fsm.h. (struct call_return_meta_info): New. (get_call_return_value): New function, factored out from diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 3d2976c..4709de7 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" @@ -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_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 @@ -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,38 +11657,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 = - XNEW (struct until_break_command_continuation_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); } @@ -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; } diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 437d919..98c386a 100644 --- a/gdb/infcmd.c +++ b/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); - 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 -- 2.7.4