aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2012-05-11 13:34:34 +0000
committerPedro Alves <palves@redhat.com>2012-05-11 13:34:34 +0000
commitbde24c0a34fd79fb9ee6c7a355a46917cd866d26 (patch)
tree8e28037d0930c5676dd345da19fc4ca6b0f615d3
parent99700d6febe92cfcd0ce5b62cad8472020e6c248 (diff)
downloadgdb-bde24c0a34fd79fb9ee6c7a355a46917cd866d26.zip
gdb-bde24c0a34fd79fb9ee6c7a355a46917cd866d26.tar.gz
gdb-bde24c0a34fd79fb9ee6c7a355a46917cd866d26.tar.bz2
2012-05-11 Yao Qi <yao@codesourcery.com>
Pedro Alves <palves@redhat.com> * linux-low.c (enum stopping_threads_kind): New. (stopping_threads): Change type to `enum stopping_threads_kind'. (handle_extended_wait): If stopping and suspending threads, leave the new_lwp suspended too. (linux_wait_for_event): Adjust. (stop_all_lwps): Set `stopping_threads' to STOPPING_AND_SUSPENDING_THREADS or STOPPING_THREADS depending on whether we're suspending threads or just stopping them. Assert no recursion happens.
-rw-r--r--gdb/gdbserver/ChangeLog13
-rw-r--r--gdb/gdbserver/linux-low.c38
2 files changed, 43 insertions, 8 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 7b79cd1..59c500a 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,16 @@
+2012-05-11 Yao Qi <yao@codesourcery.com>
+ Pedro Alves <palves@redhat.com>
+
+ * linux-low.c (enum stopping_threads_kind): New.
+ (stopping_threads): Change type to `enum stopping_threads_kind'.
+ (handle_extended_wait): If stopping and suspending threads, leave
+ the new_lwp suspended too.
+ (linux_wait_for_event): Adjust.
+ (stop_all_lwps): Set `stopping_threads' to
+ STOPPING_AND_SUSPENDING_THREADS or STOPPING_THREADS depending on
+ whether we're suspending threads or just stopping them. Assert no
+ recursion happens.
+
2012-04-29 Yao Qi <yao@codesourcery.com>
* server.h: Move some code to ...
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index bbb0693..143a2ed 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -172,8 +172,20 @@ pull_pid_from_list (struct simple_pid_list **listp, int pid, int *statusp)
return 0;
}
-/* FIXME this is a bit of a hack, and could be removed. */
-int stopping_threads;
+enum stopping_threads_kind
+ {
+ /* Not stopping threads presently. */
+ NOT_STOPPING_THREADS,
+
+ /* Stopping threads. */
+ STOPPING_THREADS,
+
+ /* Stopping and suspending threads. */
+ STOPPING_AND_SUSPENDING_THREADS
+ };
+
+/* This is set while stop_all_lwps is in effect. */
+enum stopping_threads_kind stopping_threads = NOT_STOPPING_THREADS;
/* FIXME make into a target method? */
int using_threads = 1;
@@ -461,12 +473,17 @@ handle_extended_wait (struct lwp_info *event_child, int wstat)
before calling linux_resume_one_lwp. */
new_lwp->stopped = 1;
+ /* If we're suspending all threads, leave this one suspended
+ too. */
+ if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
+ new_lwp->suspended = 1;
+
/* Normally we will get the pending SIGSTOP. But in some cases
we might get another signal delivered to the group first.
If we do get another signal, be sure not to lose it. */
if (WSTOPSIG (status) == SIGSTOP)
{
- if (stopping_threads)
+ if (stopping_threads != NOT_STOPPING_THREADS)
new_lwp->stop_pc = get_stop_pc (new_lwp);
else
linux_resume_one_lwp (new_lwp, 0, 0, NULL);
@@ -475,7 +492,7 @@ handle_extended_wait (struct lwp_info *event_child, int wstat)
{
new_lwp->stop_expected = 1;
- if (stopping_threads)
+ if (stopping_threads != NOT_STOPPING_THREADS)
{
new_lwp->stop_pc = get_stop_pc (new_lwp);
new_lwp->status_pending_p = 1;
@@ -1815,7 +1832,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
{
requested_child = find_lwp_pid (ptid);
- if (!stopping_threads
+ if (stopping_threads == NOT_STOPPING_THREADS
&& requested_child->status_pending_p
&& requested_child->collecting_fast_tracepoint)
{
@@ -1963,7 +1980,7 @@ linux_wait_for_event (ptid_t ptid, int *wstat, int options)
event_child->stop_expected = 0;
should_stop = (current_inferior->last_resume_kind == resume_stop
- || stopping_threads);
+ || stopping_threads != NOT_STOPPING_THREADS);
if (!should_stop)
{
@@ -3072,14 +3089,19 @@ lwp_running (struct inferior_list_entry *entry, void *data)
static void
stop_all_lwps (int suspend, struct lwp_info *except)
{
- stopping_threads = 1;
+ /* Should not be called recursively. */
+ gdb_assert (stopping_threads == NOT_STOPPING_THREADS);
+
+ stopping_threads = (suspend
+ ? STOPPING_AND_SUSPENDING_THREADS
+ : STOPPING_THREADS);
if (suspend)
find_inferior (&all_lwps, suspend_and_send_sigstop_callback, except);
else
find_inferior (&all_lwps, send_sigstop_callback, except);
for_each_inferior (&all_lwps, wait_for_sigstop);
- stopping_threads = 0;
+ stopping_threads = NOT_STOPPING_THREADS;
}
/* Resume execution of the inferior process.