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:
parent
9ec7216836
commit
12d9289a51
|
@ -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>
|
2011-10-11 Sterling Augustine <saugustine@google.com>
|
||||||
|
|
||||||
* dwarf2read.c: Undo inadvertent changes in previous commit.
|
* dwarf2read.c: Undo inadvertent changes in previous commit.
|
||||||
|
|
|
@ -3109,14 +3109,17 @@ resumed_callback (struct lwp_info *lp, void *data)
|
||||||
return lp->resumed;
|
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
|
static int
|
||||||
stop_and_resume_callback (struct lwp_info *lp, void *data)
|
stop_and_resume_callback (struct lwp_info *lp, void *data)
|
||||||
{
|
{
|
||||||
|
int *new_pending_p = data;
|
||||||
|
|
||||||
if (!lp->stopped)
|
if (!lp->stopped)
|
||||||
{
|
{
|
||||||
enum resume_kind last_resume_kind = lp->last_resume_kind;
|
|
||||||
ptid_t ptid = lp->ptid;
|
ptid_t ptid = lp->ptid;
|
||||||
|
|
||||||
stop_callback (lp, NULL);
|
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
|
/* Resume if the lwp still exists, and the core wanted it
|
||||||
running. */
|
running. */
|
||||||
if (last_resume_kind != resume_stop)
|
|
||||||
{
|
|
||||||
lp = find_lwp_pid (ptid);
|
lp = find_lwp_pid (ptid);
|
||||||
if (lp)
|
if (lp != NULL)
|
||||||
|
{
|
||||||
|
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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we should go on and pass this event to common code.
|
/* 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 *
|
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;
|
struct lwp_info *lp;
|
||||||
|
|
||||||
|
*new_pending_p = 0;
|
||||||
|
|
||||||
lp = find_lwp_pid (pid_to_ptid (lwpid));
|
lp = find_lwp_pid (pid_to_ptid (lwpid));
|
||||||
|
|
||||||
/* Check for stop events reported by a process we didn't already
|
/* 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;
|
lp->stopped = 1;
|
||||||
iterate_over_lwps (pid_to_ptid (GET_PID (lp->ptid)),
|
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)
|
if (debug_linux_nat)
|
||||||
|
@ -3358,9 +3395,9 @@ linux_nat_wait_1 (struct target_ops *ops,
|
||||||
{
|
{
|
||||||
static sigset_t prev_mask;
|
static sigset_t prev_mask;
|
||||||
enum resume_kind last_resume_kind;
|
enum resume_kind last_resume_kind;
|
||||||
struct lwp_info *lp = NULL;
|
struct lwp_info *lp;
|
||||||
int options = 0;
|
int options;
|
||||||
int status = 0;
|
int status;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
if (debug_linux_nat)
|
if (debug_linux_nat)
|
||||||
|
@ -3397,6 +3434,7 @@ linux_nat_wait_1 (struct target_ops *ops,
|
||||||
retry:
|
retry:
|
||||||
lp = NULL;
|
lp = NULL;
|
||||||
status = 0;
|
status = 0;
|
||||||
|
options = 0;
|
||||||
|
|
||||||
/* Make sure that of those LWPs we want to get an event from, there
|
/* 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
|
is at least one LWP that has been resumed. If there's none, just
|
||||||
|
@ -3527,6 +3565,10 @@ retry:
|
||||||
|
|
||||||
if (lwpid > 0)
|
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);
|
gdb_assert (pid == -1 || lwpid == pid);
|
||||||
|
|
||||||
if (debug_linux_nat)
|
if (debug_linux_nat)
|
||||||
|
@ -3536,7 +3578,7 @@ retry:
|
||||||
(long) lwpid, status_to_str (status));
|
(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 is now no longer valid, use LP->STATUS instead. */
|
||||||
status = 0;
|
status = 0;
|
||||||
|
@ -3616,6 +3658,9 @@ retry:
|
||||||
store_waitstatus (&lp->waitstatus, lp->status);
|
store_waitstatus (&lp->waitstatus, lp->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new_pending)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
/* Keep looking. */
|
/* Keep looking. */
|
||||||
lp = NULL;
|
lp = NULL;
|
||||||
continue;
|
continue;
|
||||||
|
@ -3625,6 +3670,9 @@ retry:
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (new_pending)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
{
|
{
|
||||||
/* waitpid did return something. Restart over. */
|
/* waitpid did return something. Restart over. */
|
||||||
|
|
Loading…
Reference in New Issue