diff options
author | Pedro Alves <palves@redhat.com> | 2011-05-30 18:04:32 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2011-05-30 18:04:32 +0000 |
commit | fa4cd53f7d2a4d6981bc4e09d5233f0df2c7f1cd (patch) | |
tree | fbf033c82d112b48b3a47155cf5223e737eb3a88 /gdb/infcmd.c | |
parent | c2949be03bf333bd3de59dc3260762d3201f6b79 (diff) | |
download | gdb-fa4cd53f7d2a4d6981bc4e09d5233f0df2c7f1cd.zip gdb-fa4cd53f7d2a4d6981bc4e09d5233f0df2c7f1cd.tar.gz gdb-fa4cd53f7d2a4d6981bc4e09d5233f0df2c7f1cd.tar.bz2 |
2011-05-30 Pedro Alves <pedro@codesourcery.com>
gdb/
* continuations.h (continuation_ftype): Add `err' parameter.
Document parameters.
(do_all_continuations, do_all_continuations_thread)
(do_all_intermediate_continuations)
(do_all_intermediate_continuations_thread)
(do_all_inferior_continuations): Add `err' parameter.
* continuations.c (do_my_continuations_1, do_my_continuations)
(do_all_inferior_continuations, do_all_continuations_ptid)
(do_all_continuations_thread_callback)
(do_all_continuations_thread, do_all_continuations)
(do_all_intermediate_continuations_thread_callback)
(do_all_intermediate_continuations_thread)
(do_all_intermediate_continuations): Add `err' parameter, and pass
it down all the way to the continuations proper.
* inf-loop.c (inferior_event_handler): If fetching an inferior
event throws an error, don't pop the target, and still call the
continuations, but with `err' set. Adjust all other continuation
calls.
* breakpoint.c (until_break_command_continuation): Add `err'
parameter.
* infcmd.c (step_1_continuation): Add `err' parameter. Don't
issue another step if `err' is set.
(struct until_next_continuation_args): New.
(until_next_continuation): Add `err' parameter. Adjust.
(until_next_command): Adjust.
(struct finish_command_continuation_args): Add `thread' field.
(finish_command_continuation): Add `err' parameter. Handle it.
(finish_forward): Adjust.
(attach_command_continuation): Add `err' parameter. Handle it.
* infrun.c (infrun_thread_stop_requested_callback): Adjust to
cancel the continuations.
* interps.c (interp_set): Adjust to cancel the continuations.
* thread.c (clear_thread_inferior_resources): Adjust to cancel the
continuations rather than discarding.
(free_thread): Don't clear thread inferior resources here.
(delete_thread_1): Do it here instead. And do it before removing
the thread from the threads list. Tag the thread as exited before
clearing thread inferior resources.
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); } |