aboutsummaryrefslogtreecommitdiff
path: root/gdb/infcmd.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2011-05-30 18:04:32 +0000
committerPedro Alves <palves@redhat.com>2011-05-30 18:04:32 +0000
commitfa4cd53f7d2a4d6981bc4e09d5233f0df2c7f1cd (patch)
treefbf033c82d112b48b3a47155cf5223e737eb3a88 /gdb/infcmd.c
parentc2949be03bf333bd3de59dc3260762d3201f6b79 (diff)
downloadgdb-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.c114
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);
}