aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2008-11-05 20:23:07 +0000
committerPedro Alves <palves@redhat.com>2008-11-05 20:23:07 +0000
commite0ba674611b77dce4d02d6b08e90b10255ec3e2d (patch)
tree2e6dd7afb17800c925cd5c543347e28b03416cf0
parent6dc6b6558bf7ede38de5f7b9356d8d98e5960c33 (diff)
downloadgdb-e0ba674611b77dce4d02d6b08e90b10255ec3e2d.zip
gdb-e0ba674611b77dce4d02d6b08e90b10255ec3e2d.tar.gz
gdb-e0ba674611b77dce4d02d6b08e90b10255ec3e2d.tar.bz2
* 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.
-rw-r--r--gdb/ChangeLog18
-rw-r--r--gdb/defs.h12
-rw-r--r--gdb/inf-loop.c5
-rw-r--r--gdb/infcmd.c5
-rw-r--r--gdb/inferior.c1
-rw-r--r--gdb/inferior.h5
-rw-r--r--gdb/infrun.c13
-rw-r--r--gdb/utils.c53
8 files changed, 107 insertions, 5 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ea9c1d8..5e04130 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/defs.h b/gdb/defs.h
index 8d50f8a..b047266 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -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;
diff --git a/gdb/inf-loop.c b/gdb/inf-loop.c
index 2e0f4d2..95355e8 100644
--- a/gdb/inf-loop.c
+++ b/gdb/inf-loop.c
@@ -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
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 50e8fff..b3af31f 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -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;
}
diff --git a/gdb/inferior.c b/gdb/inferior.c
index 4233a51..9fec4cc 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -45,6 +45,7 @@ current_inferior (void)
static void
free_inferior (struct inferior *inf)
{
+ discard_all_inferior_continuations (inf);
xfree (inf->private);
xfree (inf);
}
diff --git a/gdb/inferior.h b/gdb/inferior.h
index cc5bf9f..029dc31 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -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;
};
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 30d914d..1a95466 100644
--- a/gdb/infrun.c
+++ b/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
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;
diff --git a/gdb/utils.c b/gdb/utils.c
index 26d7933..fed2e7e 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -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)
{