From: Vladimir Prus <vladimir@codesourcery.com>
To: gdb-patches@sourceware.org
Subject: Fix a couple of multiexec races
Date: Wed, 13 Jan 2010 15:11:00 -0000 [thread overview]
Message-ID: <201001131811.30403.vladimir@codesourcery.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 2782 bytes --]
The attached patch fixes a couple of glitches preventing (upcoming)
'-exec-run --all' from working.
First, consider this code inside linux_nat_wait_1:
if (lp
&& ptid_is_pid (ptid)
&& ptid_get_pid (lp->ptid) != ptid_get_pid (ptid))
{
if (debug_linux_nat)
fprintf (stderr, "LWP %ld got an event %06x, leaving pending.\n",
ptid_get_lwp (lp->ptid), status);
if (WIFSTOPPED (lp->status))
{
if (WSTOPSIG (lp->status) != SIGSTOP)
{
stop_callback (lp, NULL);
/* Resume in order to collect the sigstop. */
ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
stop_wait_callback (lp, NULL);
}
Because lp->status is naturally not NULL when calling stop_callback, and because
stop_callback has:
gdb_assert (lp->status == 0);
if we ever enter the inner "if", GDB will crash. Offlist, Pedro suggested the inner if be
just removed.
Second change is to address the issue I have reported earlier. I reproduce the original
email below.
I have read the comment inside cancel_breakpoints_callback, but I am not sure
I fully understand it. The situation being handled is when GDB expects an
event in thread A, and thread B hits a breakpoint. For all-stop mode, this
makes sense -- after all we don't support reporting more than one event, and
when user examines event in A he might indeed delete a breakpoint. And if he
does not deletes a breakpoint, 'continue' resumes all threads by default,
so we'll hit breakpoint in B again.
But is this reasonable for non-stop. In non-stop, we get can further stop
events while user examines event in A. Further, 'continue' resumes only
the current thread. So, if we don't report event in B, user does not have
any idea it has to be resumed.
What I observe, specifically, is when I use '-exec-run --all' (a local patch),
one inferior is not resumed. Here's the relevant bit of 'debug lin-lwp' output:
*running,thread-id="2"
&"linux_nat_wait: [process 4659]\n"
&"LLW: waitpid 4656 received Trace/breakpoint trap (stopped)\n"
LWP 4656 got an event 00057f, leaving pending.
&"LLW: waitpid 4659 received Trace/breakpoint trap (stopped)\n"
&"LLW: Candidate event Trace/breakpoint trap (stopped) in process 4659.\n"
&"CB: Push back breakpoint for process 4656\n"
And there's no further mention of this pid in the log; it remains stopped. The
attached patch appears to improve things. Pedro, what do you think?
Note that this patch also comments out the code that tries to stop a thread if
it got != SIGSTOP. As discussed offlist, that code fires assertion inside
stop_callback.
- Volodya
[-- Attachment #2: races.diff --]
[-- Type: text/x-patch, Size: 1532 bytes --]
commit 12fb288b309af44de0b6709d80d172be852368ad
Author: Vladimir Prus <vladimir@codesourcery.com>
Date: Fri Jan 8 17:07:44 2010 +0300
Fix issues preventing '-exec-run --all' from work.
* linux-nat.c (linux_nat_wait_1): When getting event in undesired
inferior, do not try to resume it and get SIGSTOP. In non-stop, do
not try to cancel breakpoints.
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index bf0a5f1..682949d 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -3419,20 +3419,9 @@ retry:
if (WIFSTOPPED (lp->status))
{
- if (WSTOPSIG (lp->status) != SIGSTOP)
- {
- stop_callback (lp, NULL);
-
- /* Resume in order to collect the sigstop. */
- ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
-
- stop_wait_callback (lp, NULL);
- }
- else
- {
- lp->stopped = 1;
- lp->signalled = 0;
- }
+ lp->stopped = 1;
+ if (WSTOPSIG (lp->status) == SIGSTOP)
+ lp->signalled = 0;
}
else if (WIFEXITED (status) || WIFSIGNALED (status))
{
@@ -3621,7 +3610,8 @@ retry:
/* Now that we've selected our final event LWP, cancel any
breakpoints in other LWPs that have hit a GDB breakpoint. See
the comment in cancel_breakpoints_callback to find out why. */
- iterate_over_lwps (minus_one_ptid, cancel_breakpoints_callback, lp);
+ if (!non_stop)
+ iterate_over_lwps (minus_one_ptid, cancel_breakpoints_callback, lp);
if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP)
{
next reply other threads:[~2010-01-13 15:11 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-13 15:11 Vladimir Prus [this message]
2010-01-13 15:50 ` Pedro Alves
2010-02-08 15:54 ` Pedro Alves
2010-02-15 9:11 ` Vladimir Prus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201001131811.30403.vladimir@codesourcery.com \
--to=vladimir@codesourcery.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox