diff options
Diffstat (limited to 'gdb/infcmd.c')
-rw-r--r-- | gdb/infcmd.c | 114 |
1 files changed, 70 insertions, 44 deletions
diff --git a/gdb/infcmd.c b/gdb/infcmd.c index f499e3e..aa3646b 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -940,7 +940,7 @@ struct step_1_continuation_args proceed(), via step_once(). Basically it is like step_once and step_1_continuation are co-recursive. */ static void -step_1_continuation (void *args) +step_1_continuation (void *args, int err) { struct step_1_continuation_args *a = args; @@ -949,7 +949,8 @@ step_1_continuation (void *args) struct thread_info *tp; tp = inferior_thread (); - if (tp->step_multi && tp->control.stop_step) + if (!err + && tp->step_multi && tp->control.stop_step) { /* There are more steps to make, and we did stop due to ending a stepping range. Do another step. */ @@ -960,8 +961,9 @@ step_1_continuation (void *args) tp->step_multi = 0; } - /* We either stopped for some reason that is not stepping, or there - are no further steps to make. Cleanup. */ + /* We either hit an error, or stopped for some reason that is + not stepping, or there are no further steps to make. + Cleanup. */ if (!a->single_inst || a->skip_subroutines) delete_longjmp_breakpoint (a->thread); } @@ -1246,14 +1248,22 @@ signal_command (char *signum_exp, int from_tty) proceed ((CORE_ADDR) -1, oursig, 0); } +/* Continuation args to be passed to the "until" command + continuation. */ +struct until_next_continuation_args +{ + /* The thread that was current when the command was executed. */ + int thread; +}; + /* A continuation callback for until_next_command. */ static void -until_next_continuation (void *arg) +until_next_continuation (void *arg, int err) { - struct thread_info *tp = arg; + struct until_next_continuation_args *a = arg; - delete_longjmp_breakpoint (tp->num); + delete_longjmp_breakpoint (a->thread); } /* Proceed until we reach a different source line with pc greater than @@ -1316,8 +1326,13 @@ until_next_command (int from_tty) if (target_can_async_p () && is_running (inferior_ptid)) { + struct until_next_continuation_args *cont_args; + discard_cleanups (old_chain); - add_continuation (tp, until_next_continuation, tp, NULL); + 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); @@ -1458,62 +1473,69 @@ print_return_value (struct type *func_type, struct type *value_type) impossible to do all the stuff as part of the finish_command function itself. The only chance we have to complete this command is in fetch_inferior_event, which is called by the event loop as - soon as it detects that the target has stopped. This function is - called via the cmd_continuation pointer. */ + soon as it detects that the target has stopped. */ struct finish_command_continuation_args { + /* The thread that as current when the command was executed. */ + int thread; struct breakpoint *breakpoint; struct symbol *function; }; static void -finish_command_continuation (void *arg) +finish_command_continuation (void *arg, int err) { struct finish_command_continuation_args *a = arg; - struct thread_info *tp = NULL; - bpstat bs = NULL; - - if (!ptid_equal (inferior_ptid, null_ptid) - && target_has_execution - && is_stopped (inferior_ptid)) - { - tp = inferior_thread (); - bs = tp->control.stop_bpstat; - } - if (bpstat_find_breakpoint (bs, a->breakpoint) != NULL - && a->function != NULL) + if (!err) { - struct type *value_type; + struct thread_info *tp = NULL; + bpstat bs = NULL; - value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (a->function)); - if (!value_type) - internal_error (__FILE__, __LINE__, - _("finish_command: function has no target type")); + if (!ptid_equal (inferior_ptid, null_ptid) + && target_has_execution + && is_stopped (inferior_ptid)) + { + tp = inferior_thread (); + bs = tp->control.stop_bpstat; + } - if (TYPE_CODE (value_type) != TYPE_CODE_VOID) + if (bpstat_find_breakpoint (bs, a->breakpoint) != NULL + && a->function != NULL) { - volatile struct gdb_exception ex; + struct type *value_type; + + value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (a->function)); + if (!value_type) + internal_error (__FILE__, __LINE__, + _("finish_command: function has no target type")); - TRY_CATCH (ex, RETURN_MASK_ALL) + if (TYPE_CODE (value_type) != TYPE_CODE_VOID) { - /* print_return_value can throw an exception in some - circumstances. We need to catch this so that we still - delete the breakpoint. */ - print_return_value (SYMBOL_TYPE (a->function), value_type); + volatile struct gdb_exception ex; + + TRY_CATCH (ex, RETURN_MASK_ALL) + { + /* print_return_value can throw an exception in some + circumstances. We need to catch this so that we still + delete the breakpoint. */ + print_return_value (SYMBOL_TYPE (a->function), value_type); + } + if (ex.reason < 0) + exception_print (gdb_stdout, ex); } - if (ex.reason < 0) - exception_print (gdb_stdout, ex); } + + /* We suppress normal call of normal_stop observer and do it + here so that the *stopped notification includes the return + value. */ + if (bs != NULL && tp->control.proceed_to_finish) + observer_notify_normal_stop (bs, 1 /* print frame */); } - /* We suppress normal call of normal_stop observer and do it here so - that the *stopped notification includes the return value. */ - if (bs != NULL && tp->control.proceed_to_finish) - observer_notify_normal_stop (bs, 1 /* print frame */); delete_breakpoint (a->breakpoint); - delete_longjmp_breakpoint (inferior_thread ()->num); + delete_longjmp_breakpoint (a->thread); } static void @@ -1604,6 +1626,7 @@ finish_forward (struct symbol *function, struct frame_info *frame) tp->control.proceed_to_finish = 1; cargs = xmalloc (sizeof (*cargs)); + cargs->thread = thread; cargs->breakpoint = breakpoint; cargs->function = function; add_continuation (tp, finish_command_continuation, cargs, @@ -1612,7 +1635,7 @@ finish_forward (struct symbol *function, struct frame_info *frame) discard_cleanups (old_chain); if (!target_can_async_p ()) - do_all_continuations (); + do_all_continuations (0); } /* "finish": Set a temporary breakpoint at the place the selected @@ -2405,10 +2428,13 @@ struct attach_command_continuation_args }; static void -attach_command_continuation (void *args) +attach_command_continuation (void *args, int err) { struct attach_command_continuation_args *a = args; + if (err) + return; + attach_command_post_wait (a->args, a->from_tty, a->async_exec); } |