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.
This commit is contained in:
Pedro Alves 2012-05-11 13:34:34 +00:00
parent 99700d6feb
commit bde24c0a34
2 changed files with 43 additions and 8 deletions

View file

@ -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> 2012-04-29 Yao Qi <yao@codesourcery.com>
* server.h: Move some code to ... * server.h: Move some code to ...

View file

@ -172,8 +172,20 @@ pull_pid_from_list (struct simple_pid_list **listp, int pid, int *statusp)
return 0; return 0;
} }
/* FIXME this is a bit of a hack, and could be removed. */ enum stopping_threads_kind
int stopping_threads; {
/* 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? */ /* FIXME make into a target method? */
int using_threads = 1; int using_threads = 1;
@ -461,12 +473,17 @@ handle_extended_wait (struct lwp_info *event_child, int wstat)
before calling linux_resume_one_lwp. */ before calling linux_resume_one_lwp. */
new_lwp->stopped = 1; 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 /* Normally we will get the pending SIGSTOP. But in some cases
we might get another signal delivered to the group first. we might get another signal delivered to the group first.
If we do get another signal, be sure not to lose it. */ If we do get another signal, be sure not to lose it. */
if (WSTOPSIG (status) == SIGSTOP) if (WSTOPSIG (status) == SIGSTOP)
{ {
if (stopping_threads) if (stopping_threads != NOT_STOPPING_THREADS)
new_lwp->stop_pc = get_stop_pc (new_lwp); new_lwp->stop_pc = get_stop_pc (new_lwp);
else else
linux_resume_one_lwp (new_lwp, 0, 0, NULL); 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; 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->stop_pc = get_stop_pc (new_lwp);
new_lwp->status_pending_p = 1; 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); requested_child = find_lwp_pid (ptid);
if (!stopping_threads if (stopping_threads == NOT_STOPPING_THREADS
&& requested_child->status_pending_p && requested_child->status_pending_p
&& requested_child->collecting_fast_tracepoint) && 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; event_child->stop_expected = 0;
should_stop = (current_inferior->last_resume_kind == resume_stop should_stop = (current_inferior->last_resume_kind == resume_stop
|| stopping_threads); || stopping_threads != NOT_STOPPING_THREADS);
if (!should_stop) if (!should_stop)
{ {
@ -3072,14 +3089,19 @@ lwp_running (struct inferior_list_entry *entry, void *data)
static void static void
stop_all_lwps (int suspend, struct lwp_info *except) 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) if (suspend)
find_inferior (&all_lwps, suspend_and_send_sigstop_callback, except); find_inferior (&all_lwps, suspend_and_send_sigstop_callback, except);
else else
find_inferior (&all_lwps, send_sigstop_callback, except); find_inferior (&all_lwps, send_sigstop_callback, except);
for_each_inferior (&all_lwps, wait_for_sigstop); for_each_inferior (&all_lwps, wait_for_sigstop);
stopping_threads = 0; stopping_threads = NOT_STOPPING_THREADS;
} }
/* Resume execution of the inferior process. /* Resume execution of the inferior process.