2011-10-12 Pedro Alves <pedro@codesourcery.com>

gdb/
	* linux-nat.c (stop_and_resume_callback): Don't re-resume LWPs if
	the core wanted them stopped, or if they now have a pending event
	to report.
This commit is contained in:
Pedro Alves 2011-10-12 12:11:26 +00:00
parent 9ec7216836
commit 12d9289a51
2 changed files with 67 additions and 13 deletions

View File

@ -1,3 +1,9 @@
2011-10-12 Pedro Alves <pedro@codesourcery.com>
* linux-nat.c (stop_and_resume_callback): Don't re-resume LWPs if
the core wanted them stopped, or if they now have a pending event
to report.
2011-10-11 Sterling Augustine <saugustine@google.com>
* dwarf2read.c: Undo inadvertent changes in previous commit.

View File

@ -3109,14 +3109,17 @@ resumed_callback (struct lwp_info *lp, void *data)
return lp->resumed;
}
/* Stop an active thread, verify it still exists, then resume it. */
/* Stop an active thread, verify it still exists, then resume it. If
the thread ends up with a pending status, then it is not resumed,
and *DATA (really a pointer to int), is set. */
static int
stop_and_resume_callback (struct lwp_info *lp, void *data)
{
int *new_pending_p = data;
if (!lp->stopped)
{
enum resume_kind last_resume_kind = lp->last_resume_kind;
ptid_t ptid = lp->ptid;
stop_callback (lp, NULL);
@ -3124,23 +3127,57 @@ stop_and_resume_callback (struct lwp_info *lp, void *data)
/* Resume if the lwp still exists, and the core wanted it
running. */
if (last_resume_kind != resume_stop)
lp = find_lwp_pid (ptid);
if (lp != NULL)
{
lp = find_lwp_pid (ptid);
if (lp)
resume_lwp (lp, lp->step);
if (lp->last_resume_kind == resume_stop
&& lp->status == 0)
{
/* The core wanted the LWP to stop. Even if it stopped
cleanly (with SIGSTOP), leave the event pending. */
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"SARC: core wanted LWP %ld stopped "
"(leaving SIGSTOP pending)\n",
GET_LWP (lp->ptid));
lp->status = W_STOPCODE (SIGSTOP);
}
if (lp->status == 0)
{
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"SARC: re-resuming LWP %ld\n",
GET_LWP (lp->ptid));
resume_lwp (lp, lp->step);
}
else
{
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"SARC: not re-resuming LWP %ld "
"(has pending)\n",
GET_LWP (lp->ptid));
if (new_pending_p)
*new_pending_p = 1;
}
}
}
return 0;
}
/* Check if we should go on and pass this event to common code.
Return the affected lwp if we are, or NULL otherwise. */
Return the affected lwp if we are, or NULL otherwise. If we stop
all lwps temporarily, we may end up with new pending events in some
other lwp. In that case set *NEW_PENDING_P to true. */
static struct lwp_info *
linux_nat_filter_event (int lwpid, int status, int options)
linux_nat_filter_event (int lwpid, int status, int options, int *new_pending_p)
{
struct lwp_info *lp;
*new_pending_p = 0;
lp = find_lwp_pid (pid_to_ptid (lwpid));
/* Check for stop events reported by a process we didn't already
@ -3240,7 +3277,7 @@ linux_nat_filter_event (int lwpid, int status, int options)
{
lp->stopped = 1;
iterate_over_lwps (pid_to_ptid (GET_PID (lp->ptid)),
stop_and_resume_callback, NULL);
stop_and_resume_callback, new_pending_p);
}
if (debug_linux_nat)
@ -3358,9 +3395,9 @@ linux_nat_wait_1 (struct target_ops *ops,
{
static sigset_t prev_mask;
enum resume_kind last_resume_kind;
struct lwp_info *lp = NULL;
int options = 0;
int status = 0;
struct lwp_info *lp;
int options;
int status;
pid_t pid;
if (debug_linux_nat)
@ -3397,6 +3434,7 @@ linux_nat_wait_1 (struct target_ops *ops,
retry:
lp = NULL;
status = 0;
options = 0;
/* Make sure that of those LWPs we want to get an event from, there
is at least one LWP that has been resumed. If there's none, just
@ -3527,6 +3565,10 @@ retry:
if (lwpid > 0)
{
/* If this is true, then we paused LWPs momentarily, and may
now have pending events to handle. */
int new_pending;
gdb_assert (pid == -1 || lwpid == pid);
if (debug_linux_nat)
@ -3536,7 +3578,7 @@ retry:
(long) lwpid, status_to_str (status));
}
lp = linux_nat_filter_event (lwpid, status, options);
lp = linux_nat_filter_event (lwpid, status, options, &new_pending);
/* STATUS is now no longer valid, use LP->STATUS instead. */
status = 0;
@ -3616,6 +3658,9 @@ retry:
store_waitstatus (&lp->waitstatus, lp->status);
}
if (new_pending)
goto retry;
/* Keep looking. */
lp = NULL;
continue;
@ -3625,6 +3670,9 @@ retry:
break;
else
{
if (new_pending)
goto retry;
if (pid == -1)
{
/* waitpid did return something. Restart over. */