* 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:
Pedro Alves 2008-11-05 20:23:07 +00:00
parent 6dc6b6558b
commit e0ba674611
8 changed files with 107 additions and 5 deletions

View File

@ -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>
* inf-loop.c (inferior_event_handler): On INF_ERROR and

View File

@ -701,8 +701,12 @@ extern void free_command_lines (struct command_line **);
struct continuation;
struct thread_info;
struct inferior;
/* From utils.c */
/* Thread specific continuations. */
extern void add_continuation (struct thread_info *,
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_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). */
extern char *current_directory;

View File

@ -89,6 +89,11 @@ inferior_event_handler (enum inferior_event_type event_type,
was_sync = sync_execution;
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
got interrupted by a breakpoint, still do the pending
continuations. The continuation itself is responsible for

View File

@ -2320,9 +2320,8 @@ attach_command (char *args, int from_tty)
a->args = xstrdup (args);
a->from_tty = from_tty;
a->async_exec = async_exec;
add_continuation (inferior_thread (),
attach_command_continuation, a,
attach_command_continuation_free_args);
add_inferior_continuation (attach_command_continuation, a,
attach_command_continuation_free_args);
discard_cleanups (back_to);
return;
}

View File

@ -45,6 +45,7 @@ current_inferior (void)
static void
free_inferior (struct inferior *inf)
{
discard_all_inferior_continuations (inf);
xfree (inf->private);
xfree (inf);
}

View File

@ -424,6 +424,11 @@ struct inferior
forked. */
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. */
struct private_inferior *private;
};

View File

@ -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
target extended-remote report it instead of a SIGSTOP
(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
&& (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);
ecs->event_thread->stop_signal = TARGET_SIGNAL_0;

View File

@ -505,6 +505,59 @@ add_continuation (struct thread_info *thread,
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
restore_thread_cleanup (void *arg)
{