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.
This commit is contained in:
parent
c2949be03b
commit
fa4cd53f7d
@ -1,3 +1,44 @@
|
||||
2011-05-30 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2011-05-30 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* infcall.c (call_function_by_hand): Rephrase error message.
|
||||
|
||||
@ -9508,7 +9508,7 @@ struct until_break_command_continuation_args
|
||||
care of cleaning up the temporary breakpoints set up by the until
|
||||
command. */
|
||||
static void
|
||||
until_break_command_continuation (void *arg)
|
||||
until_break_command_continuation (void *arg, int err)
|
||||
{
|
||||
struct until_break_command_continuation_args *a = arg;
|
||||
|
||||
|
||||
@ -51,14 +51,14 @@ make_continuation (struct continuation **pmy_chain,
|
||||
}
|
||||
|
||||
static void
|
||||
do_my_continuations_1 (struct continuation **pmy_chain)
|
||||
do_my_continuations_1 (struct continuation **pmy_chain, int err)
|
||||
{
|
||||
struct continuation *ptr;
|
||||
|
||||
while ((ptr = *pmy_chain) != NULL)
|
||||
{
|
||||
*pmy_chain = ptr->next; /* Do this first in case of recursion. */
|
||||
(*ptr->function) (ptr->arg);
|
||||
(*ptr->function) (ptr->arg, err);
|
||||
if (ptr->free_arg)
|
||||
(*ptr->free_arg) (ptr->arg);
|
||||
xfree (ptr);
|
||||
@ -66,7 +66,7 @@ do_my_continuations_1 (struct continuation **pmy_chain)
|
||||
}
|
||||
|
||||
static void
|
||||
do_my_continuations (struct continuation **list)
|
||||
do_my_continuations (struct continuation **list, int err)
|
||||
{
|
||||
struct continuation *continuations;
|
||||
|
||||
@ -82,7 +82,7 @@ do_my_continuations (struct continuation **list)
|
||||
*list = NULL;
|
||||
|
||||
/* Work now on the list we have set aside. */
|
||||
do_my_continuations_1 (&continuations);
|
||||
do_my_continuations_1 (&continuations, err);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -123,10 +123,10 @@ add_inferior_continuation (continuation_ftype *hook, void *args,
|
||||
/* Do all continuations of the current inferior. */
|
||||
|
||||
void
|
||||
do_all_inferior_continuations (void)
|
||||
do_all_inferior_continuations (int err)
|
||||
{
|
||||
struct inferior *inf = current_inferior ();
|
||||
do_my_continuations (&inf->continuations);
|
||||
do_my_continuations (&inf->continuations, err);
|
||||
}
|
||||
|
||||
/* Get rid of all the inferior-wide continuations of INF. */
|
||||
@ -167,7 +167,8 @@ restore_thread_cleanup (void *arg)
|
||||
|
||||
static void
|
||||
do_all_continuations_ptid (ptid_t ptid,
|
||||
struct continuation **continuations_p)
|
||||
struct continuation **continuations_p,
|
||||
int err)
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
ptid_t current_thread;
|
||||
@ -191,7 +192,7 @@ do_all_continuations_ptid (ptid_t ptid,
|
||||
/* Let the continuation see this thread as selected. */
|
||||
switch_to_thread (ptid);
|
||||
|
||||
do_my_continuations (continuations_p);
|
||||
do_my_continuations (continuations_p, err);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
@ -201,24 +202,25 @@ do_all_continuations_ptid (ptid_t ptid,
|
||||
static int
|
||||
do_all_continuations_thread_callback (struct thread_info *thread, void *data)
|
||||
{
|
||||
do_all_continuations_ptid (thread->ptid, &thread->continuations);
|
||||
int err = * (int *) data;
|
||||
do_all_continuations_ptid (thread->ptid, &thread->continuations, err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do all continuations of thread THREAD. */
|
||||
|
||||
void
|
||||
do_all_continuations_thread (struct thread_info *thread)
|
||||
do_all_continuations_thread (struct thread_info *thread, int err)
|
||||
{
|
||||
do_all_continuations_thread_callback (thread, NULL);
|
||||
do_all_continuations_thread_callback (thread, &err);
|
||||
}
|
||||
|
||||
/* Do all continuations of all threads. */
|
||||
|
||||
void
|
||||
do_all_continuations (void)
|
||||
do_all_continuations (int err)
|
||||
{
|
||||
iterate_over_threads (do_all_continuations_thread_callback, NULL);
|
||||
iterate_over_threads (do_all_continuations_thread_callback, &err);
|
||||
}
|
||||
|
||||
/* Callback for iterate over threads. */
|
||||
@ -274,26 +276,28 @@ static int
|
||||
do_all_intermediate_continuations_thread_callback (struct thread_info *thread,
|
||||
void *data)
|
||||
{
|
||||
int err = * (int *) data;
|
||||
|
||||
do_all_continuations_ptid (thread->ptid,
|
||||
&thread->intermediate_continuations);
|
||||
&thread->intermediate_continuations, err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do all intermediate continuations of thread THREAD. */
|
||||
|
||||
void
|
||||
do_all_intermediate_continuations_thread (struct thread_info *thread)
|
||||
do_all_intermediate_continuations_thread (struct thread_info *thread, int err)
|
||||
{
|
||||
do_all_intermediate_continuations_thread_callback (thread, NULL);
|
||||
do_all_intermediate_continuations_thread_callback (thread, &err);
|
||||
}
|
||||
|
||||
/* Do all intermediate continuations of all threads. */
|
||||
|
||||
void
|
||||
do_all_intermediate_continuations (void)
|
||||
do_all_intermediate_continuations (int err)
|
||||
{
|
||||
iterate_over_threads (do_all_intermediate_continuations_thread_callback,
|
||||
NULL);
|
||||
&err);
|
||||
}
|
||||
|
||||
/* Callback for iterate over threads. */
|
||||
|
||||
@ -30,8 +30,16 @@ struct inferior;
|
||||
used by the finish and until commands, and in the remote protocol
|
||||
when opening an extended-remote connection. */
|
||||
|
||||
/* Prototype of the continuation callback functions. */
|
||||
typedef void (continuation_ftype) (void *);
|
||||
/* Prototype of the continuation callback functions. ARG is the
|
||||
continuation argument registered in the corresponding
|
||||
add_*_continuation call. ERR is true when the command should be
|
||||
cancelled instead of finished normally. In that case, the
|
||||
continuation should clean up whatever state had been set up for the
|
||||
command in question (e.g., remove momentary breakpoints). This
|
||||
happens e.g., when an error was thrown while handling a target
|
||||
event, or when the inferior thread the command was being executed
|
||||
on exits. */
|
||||
typedef void (continuation_ftype) (void *arg, int err);
|
||||
|
||||
/* Prototype of the function responsible for releasing the argument
|
||||
passed to the continuation callback functions, either when the
|
||||
@ -43,16 +51,16 @@ typedef void (continuation_free_arg_ftype) (void *);
|
||||
extern void add_continuation (struct thread_info *,
|
||||
continuation_ftype *, void *,
|
||||
continuation_free_arg_ftype *);
|
||||
extern void do_all_continuations (void);
|
||||
extern void do_all_continuations_thread (struct thread_info *);
|
||||
extern void do_all_continuations (int err);
|
||||
extern void do_all_continuations_thread (struct thread_info *, int err);
|
||||
extern void discard_all_continuations (void);
|
||||
extern void discard_all_continuations_thread (struct thread_info *);
|
||||
|
||||
extern void add_intermediate_continuation (struct thread_info *,
|
||||
continuation_ftype *, void *,
|
||||
continuation_free_arg_ftype *);
|
||||
extern void do_all_intermediate_continuations (void);
|
||||
extern void do_all_intermediate_continuations_thread (struct thread_info *);
|
||||
extern void do_all_intermediate_continuations (int err);
|
||||
extern void do_all_intermediate_continuations_thread (struct thread_info *, int err);
|
||||
extern void discard_all_intermediate_continuations (void);
|
||||
extern void discard_all_intermediate_continuations_thread (struct thread_info *);
|
||||
|
||||
@ -61,7 +69,7 @@ extern void discard_all_intermediate_continuations_thread (struct thread_info *)
|
||||
extern void add_inferior_continuation (continuation_ftype *,
|
||||
void *,
|
||||
continuation_free_arg_ftype *);
|
||||
extern void do_all_inferior_continuations (void);
|
||||
extern void do_all_inferior_continuations (int err);
|
||||
extern void discard_all_inferior_continuations (struct inferior *inf);
|
||||
|
||||
#endif
|
||||
|
||||
@ -63,13 +63,12 @@ inferior_event_handler (enum inferior_event_type event_type,
|
||||
/* Use catch errors for now, until the inner layers of
|
||||
fetch_inferior_event (i.e. readchar) can return meaningful
|
||||
error status. If an error occurs while getting an event from
|
||||
the target, just get rid of the target. */
|
||||
the target, just cancel the current command. */
|
||||
if (!catch_errors (fetch_inferior_event_wrapper,
|
||||
client_data, "", RETURN_MASK_ALL))
|
||||
{
|
||||
pop_all_targets_above (file_stratum, 0);
|
||||
discard_all_intermediate_continuations ();
|
||||
discard_all_continuations ();
|
||||
do_all_intermediate_continuations (1);
|
||||
do_all_continuations (1);
|
||||
async_enable_stdin ();
|
||||
display_gdb_prompt (0);
|
||||
}
|
||||
@ -95,7 +94,7 @@ inferior_event_handler (enum inferior_event_type event_type,
|
||||
/* Do all continuations associated with the whole inferior (not
|
||||
a particular thread). */
|
||||
if (!ptid_equal (inferior_ptid, null_ptid))
|
||||
do_all_inferior_continuations ();
|
||||
do_all_inferior_continuations (0);
|
||||
|
||||
/* If we were doing a multi-step (eg: step n, next n), but it
|
||||
got interrupted by a breakpoint, still do the pending
|
||||
@ -107,9 +106,9 @@ inferior_event_handler (enum inferior_event_type event_type,
|
||||
if (non_stop
|
||||
&& target_has_execution
|
||||
&& !ptid_equal (inferior_ptid, null_ptid))
|
||||
do_all_intermediate_continuations_thread (inferior_thread ());
|
||||
do_all_intermediate_continuations_thread (inferior_thread (), 0);
|
||||
else
|
||||
do_all_intermediate_continuations ();
|
||||
do_all_intermediate_continuations (0);
|
||||
|
||||
/* Always finish the previous command before running any
|
||||
breakpoint commands. Any stop cancels the previous command.
|
||||
@ -118,9 +117,9 @@ inferior_event_handler (enum inferior_event_type event_type,
|
||||
if (non_stop
|
||||
&& target_has_execution
|
||||
&& !ptid_equal (inferior_ptid, null_ptid))
|
||||
do_all_continuations_thread (inferior_thread ());
|
||||
do_all_continuations_thread (inferior_thread (), 0);
|
||||
else
|
||||
do_all_continuations ();
|
||||
do_all_continuations (0);
|
||||
|
||||
if (info_verbose
|
||||
&& current_language != expected_language
|
||||
@ -147,9 +146,9 @@ inferior_event_handler (enum inferior_event_type event_type,
|
||||
complete? */
|
||||
|
||||
if (non_stop)
|
||||
do_all_intermediate_continuations_thread (inferior_thread ());
|
||||
do_all_intermediate_continuations_thread (inferior_thread (), 0);
|
||||
else
|
||||
do_all_intermediate_continuations ();
|
||||
do_all_intermediate_continuations (0);
|
||||
break;
|
||||
|
||||
case INF_QUIT_REQ:
|
||||
|
||||
122
gdb/infcmd.c
122
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))
|
||||
if (!err)
|
||||
{
|
||||
tp = inferior_thread ();
|
||||
bs = tp->control.stop_bpstat;
|
||||
}
|
||||
struct thread_info *tp = NULL;
|
||||
bpstat bs = NULL;
|
||||
|
||||
if (bpstat_find_breakpoint (bs, a->breakpoint) != NULL
|
||||
&& a->function != NULL)
|
||||
{
|
||||
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"));
|
||||
|
||||
if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
|
||||
if (!ptid_equal (inferior_ptid, null_ptid)
|
||||
&& target_has_execution
|
||||
&& is_stopped (inferior_ptid))
|
||||
{
|
||||
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);
|
||||
tp = inferior_thread ();
|
||||
bs = tp->control.stop_bpstat;
|
||||
}
|
||||
|
||||
if (bpstat_find_breakpoint (bs, a->breakpoint) != NULL
|
||||
&& a->function != NULL)
|
||||
{
|
||||
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"));
|
||||
|
||||
if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
@ -2393,12 +2393,10 @@ infrun_thread_stop_requested_callback (struct thread_info *info, void *arg)
|
||||
|
||||
normal_stop ();
|
||||
|
||||
/* Finish off the continuations. The continations
|
||||
themselves are responsible for realising the thread
|
||||
didn't finish what it was supposed to do. */
|
||||
/* Finish off the continuations. */
|
||||
tp = inferior_thread ();
|
||||
do_all_intermediate_continuations_thread (tp);
|
||||
do_all_continuations_thread (tp);
|
||||
do_all_intermediate_continuations_thread (tp, 1);
|
||||
do_all_continuations_thread (tp, 1);
|
||||
}
|
||||
|
||||
do_cleanups (old_chain);
|
||||
|
||||
@ -150,7 +150,7 @@ interp_set (struct interp *interp, int top_level)
|
||||
|
||||
if (current_interpreter != NULL)
|
||||
{
|
||||
do_all_continuations ();
|
||||
do_all_continuations (1);
|
||||
ui_out_flush (uiout);
|
||||
if (current_interpreter->procs->suspend_proc
|
||||
&& !current_interpreter->procs->suspend_proc (current_interpreter->
|
||||
|
||||
18
gdb/thread.c
18
gdb/thread.c
@ -125,8 +125,8 @@ clear_thread_inferior_resources (struct thread_info *tp)
|
||||
|
||||
bpstat_clear (&tp->control.stop_bpstat);
|
||||
|
||||
discard_all_intermediate_continuations_thread (tp);
|
||||
discard_all_continuations_thread (tp);
|
||||
do_all_intermediate_continuations_thread (tp, 1);
|
||||
do_all_continuations_thread (tp, 1);
|
||||
|
||||
delete_longjmp_breakpoint (tp->num);
|
||||
}
|
||||
@ -134,8 +134,6 @@ clear_thread_inferior_resources (struct thread_info *tp)
|
||||
static void
|
||||
free_thread (struct thread_info *tp)
|
||||
{
|
||||
clear_thread_inferior_resources (tp);
|
||||
|
||||
if (tp->private)
|
||||
{
|
||||
if (tp->private_dtor)
|
||||
@ -297,15 +295,19 @@ delete_thread_1 (ptid_t ptid, int silent)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Notify thread exit, but only if we haven't already. */
|
||||
if (tp->state_ != THREAD_EXITED)
|
||||
observer_notify_thread_exit (tp, silent);
|
||||
|
||||
/* Tag it as exited. */
|
||||
tp->state_ = THREAD_EXITED;
|
||||
clear_thread_inferior_resources (tp);
|
||||
|
||||
if (tpprev)
|
||||
tpprev->next = tp->next;
|
||||
else
|
||||
thread_list = tp->next;
|
||||
|
||||
/* Notify thread exit, but only if we haven't already. */
|
||||
if (tp->state_ != THREAD_EXITED)
|
||||
observer_notify_thread_exit (tp, silent);
|
||||
|
||||
free_thread (tp);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user