* defs.h (add_inferior_continuation)
(do_all_inferior_continuations) (discard_all_inferior_continuations): Declare. * utils.c (add_inferior_continuation) (do_all_inferior_continuations) (discard_all_inferior_continuations): New. * inferior.h (struct inferior) <continuations>: New field. * inferior.c (free_inferior): Discard all the inferior continuations. * inf-loop.c (inferior_event_handler): Do all current inferior continuations. * infcmd.c (attach_command): Register an inferior continuation instead of a thread continuation. * infrun.c (handle_inferior_event): If stop_soon is STOP_QUIETLY_NO_SIGSTOP, also expect a TARGET_SIGNAL_0.
This commit is contained in:
parent
6dc6b6558b
commit
e0ba674611
8 changed files with 107 additions and 5 deletions
|
@ -1,3 +1,21 @@
|
||||||
|
2008-11-05 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
|
* defs.h (add_inferior_continuation)
|
||||||
|
(do_all_inferior_continuations)
|
||||||
|
(discard_all_inferior_continuations): Declare.
|
||||||
|
* utils.c (add_inferior_continuation)
|
||||||
|
(do_all_inferior_continuations)
|
||||||
|
(discard_all_inferior_continuations): New.
|
||||||
|
* inferior.h (struct inferior) <continuations>: New field.
|
||||||
|
* inferior.c (free_inferior): Discard all the inferior
|
||||||
|
continuations.
|
||||||
|
* inf-loop.c (inferior_event_handler): Do all current inferior
|
||||||
|
continuations.
|
||||||
|
* infcmd.c (attach_command): Register an inferior continuation
|
||||||
|
instead of a thread continuation.
|
||||||
|
* infrun.c (handle_inferior_event): If stop_soon is
|
||||||
|
STOP_QUIETLY_NO_SIGSTOP, also expect a TARGET_SIGNAL_0.
|
||||||
|
|
||||||
2008-11-04 Pedro Alves <pedro@codesourcery.com>
|
2008-11-04 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* inf-loop.c (inferior_event_handler): On INF_ERROR and
|
* inf-loop.c (inferior_event_handler): On INF_ERROR and
|
||||||
|
|
12
gdb/defs.h
12
gdb/defs.h
|
@ -701,8 +701,12 @@ extern void free_command_lines (struct command_line **);
|
||||||
|
|
||||||
struct continuation;
|
struct continuation;
|
||||||
struct thread_info;
|
struct thread_info;
|
||||||
|
struct inferior;
|
||||||
|
|
||||||
/* From utils.c */
|
/* From utils.c */
|
||||||
|
|
||||||
|
/* Thread specific continuations. */
|
||||||
|
|
||||||
extern void add_continuation (struct thread_info *,
|
extern void add_continuation (struct thread_info *,
|
||||||
void (*)(void *), void *,
|
void (*)(void *), void *,
|
||||||
void (*)(void *));
|
void (*)(void *));
|
||||||
|
@ -719,6 +723,14 @@ extern void do_all_intermediate_continuations_thread (struct thread_info *);
|
||||||
extern void discard_all_intermediate_continuations (void);
|
extern void discard_all_intermediate_continuations (void);
|
||||||
extern void discard_all_intermediate_continuations_thread (struct thread_info *);
|
extern void discard_all_intermediate_continuations_thread (struct thread_info *);
|
||||||
|
|
||||||
|
/* Inferior specific (any thread) continuations. */
|
||||||
|
|
||||||
|
extern void add_inferior_continuation (void (*) (void *),
|
||||||
|
void *,
|
||||||
|
void (*) (void *));
|
||||||
|
extern void do_all_inferior_continuations (void);
|
||||||
|
extern void discard_all_inferior_continuations (struct inferior *inf);
|
||||||
|
|
||||||
/* String containing the current directory (what getwd would return). */
|
/* String containing the current directory (what getwd would return). */
|
||||||
|
|
||||||
extern char *current_directory;
|
extern char *current_directory;
|
||||||
|
|
|
@ -89,6 +89,11 @@ inferior_event_handler (enum inferior_event_type event_type,
|
||||||
was_sync = sync_execution;
|
was_sync = sync_execution;
|
||||||
async_enable_stdin ();
|
async_enable_stdin ();
|
||||||
|
|
||||||
|
/* Do all continuations associated with the whole inferior (not
|
||||||
|
a particular thread). */
|
||||||
|
if (!ptid_equal (inferior_ptid, null_ptid))
|
||||||
|
do_all_inferior_continuations ();
|
||||||
|
|
||||||
/* If we were doing a multi-step (eg: step n, next n), but it
|
/* If we were doing a multi-step (eg: step n, next n), but it
|
||||||
got interrupted by a breakpoint, still do the pending
|
got interrupted by a breakpoint, still do the pending
|
||||||
continuations. The continuation itself is responsible for
|
continuations. The continuation itself is responsible for
|
||||||
|
|
|
@ -2320,9 +2320,8 @@ attach_command (char *args, int from_tty)
|
||||||
a->args = xstrdup (args);
|
a->args = xstrdup (args);
|
||||||
a->from_tty = from_tty;
|
a->from_tty = from_tty;
|
||||||
a->async_exec = async_exec;
|
a->async_exec = async_exec;
|
||||||
add_continuation (inferior_thread (),
|
add_inferior_continuation (attach_command_continuation, a,
|
||||||
attach_command_continuation, a,
|
attach_command_continuation_free_args);
|
||||||
attach_command_continuation_free_args);
|
|
||||||
discard_cleanups (back_to);
|
discard_cleanups (back_to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ current_inferior (void)
|
||||||
static void
|
static void
|
||||||
free_inferior (struct inferior *inf)
|
free_inferior (struct inferior *inf)
|
||||||
{
|
{
|
||||||
|
discard_all_inferior_continuations (inf);
|
||||||
xfree (inf->private);
|
xfree (inf->private);
|
||||||
xfree (inf);
|
xfree (inf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -424,6 +424,11 @@ struct inferior
|
||||||
forked. */
|
forked. */
|
||||||
int attach_flag;
|
int attach_flag;
|
||||||
|
|
||||||
|
/* What is left to do for an execution command after any thread of
|
||||||
|
this inferior stops. For continuations associated with a
|
||||||
|
specific thread, see `struct thread_info'. */
|
||||||
|
struct continuation *continuations;
|
||||||
|
|
||||||
/* Private data used by the target vector implementation. */
|
/* Private data used by the target vector implementation. */
|
||||||
struct private_inferior *private;
|
struct private_inferior *private;
|
||||||
};
|
};
|
||||||
|
|
13
gdb/infrun.c
13
gdb/infrun.c
|
@ -2834,10 +2834,19 @@ targets should add new threads to the thread list themselves in non-stop mode.")
|
||||||
SIGTRAP. Some systems (e.g. Windows), and stubs supporting
|
SIGTRAP. Some systems (e.g. Windows), and stubs supporting
|
||||||
target extended-remote report it instead of a SIGSTOP
|
target extended-remote report it instead of a SIGSTOP
|
||||||
(e.g. gdbserver). We already rely on SIGTRAP being our
|
(e.g. gdbserver). We already rely on SIGTRAP being our
|
||||||
signal, so this is no exception. */
|
signal, so this is no exception.
|
||||||
|
|
||||||
|
Also consider that the attach is complete when we see a
|
||||||
|
TARGET_SIGNAL_0. In non-stop mode, GDB will explicitly tell
|
||||||
|
the target to stop all threads of the inferior, in case the
|
||||||
|
low level attach operation doesn't stop them implicitly. If
|
||||||
|
they weren't stopped implicitly, then the stub will report a
|
||||||
|
TARGET_SIGNAL_0, meaning: stopped for no particular reason
|
||||||
|
other than GDB's request. */
|
||||||
if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
|
if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
|
||||||
&& (ecs->event_thread->stop_signal == TARGET_SIGNAL_STOP
|
&& (ecs->event_thread->stop_signal == TARGET_SIGNAL_STOP
|
||||||
|| ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP))
|
|| ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
|
||||||
|
|| ecs->event_thread->stop_signal == TARGET_SIGNAL_0))
|
||||||
{
|
{
|
||||||
stop_stepping (ecs);
|
stop_stepping (ecs);
|
||||||
ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
|
ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
|
||||||
|
|
53
gdb/utils.c
53
gdb/utils.c
|
@ -505,6 +505,59 @@ add_continuation (struct thread_info *thread,
|
||||||
thread->continuations = (struct continuation *) as_cleanup;
|
thread->continuations = (struct continuation *) as_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add a continuation to the continuation list of INFERIOR. The new
|
||||||
|
continuation will be added at the front. */
|
||||||
|
|
||||||
|
void
|
||||||
|
add_inferior_continuation (void (*continuation_hook) (void *), void *args,
|
||||||
|
void (*continuation_free_args) (void *))
|
||||||
|
{
|
||||||
|
struct inferior *inf = current_inferior ();
|
||||||
|
struct cleanup *as_cleanup = &inf->continuations->base;
|
||||||
|
make_cleanup_ftype *continuation_hook_fn = continuation_hook;
|
||||||
|
|
||||||
|
make_my_cleanup2 (&as_cleanup,
|
||||||
|
continuation_hook_fn,
|
||||||
|
args,
|
||||||
|
continuation_free_args);
|
||||||
|
|
||||||
|
inf->continuations = (struct continuation *) as_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do all continuations of the current inferior. */
|
||||||
|
|
||||||
|
void
|
||||||
|
do_all_inferior_continuations (void)
|
||||||
|
{
|
||||||
|
struct cleanup *old_chain;
|
||||||
|
struct cleanup *as_cleanup;
|
||||||
|
struct inferior *inf = current_inferior ();
|
||||||
|
|
||||||
|
if (inf->continuations == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Copy the list header into another pointer, and set the global
|
||||||
|
list header to null, so that the global list can change as a side
|
||||||
|
effect of invoking the continuations and the processing of the
|
||||||
|
preexisting continuations will not be affected. */
|
||||||
|
|
||||||
|
as_cleanup = &inf->continuations->base;
|
||||||
|
inf->continuations = NULL;
|
||||||
|
|
||||||
|
/* Work now on the list we have set aside. */
|
||||||
|
do_my_cleanups (&as_cleanup, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get rid of all the inferior-wide continuations of INF. */
|
||||||
|
|
||||||
|
void
|
||||||
|
discard_all_inferior_continuations (struct inferior *inf)
|
||||||
|
{
|
||||||
|
struct cleanup *continuation_ptr = &inf->continuations->base;
|
||||||
|
discard_my_cleanups (&continuation_ptr, NULL);
|
||||||
|
inf->continuations = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
restore_thread_cleanup (void *arg)
|
restore_thread_cleanup (void *arg)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue