This is the mail archive of the
mailing list for the GDB project.
- From: Vladimir Prus <vladimir at codesourcery dot com>
- To: gdb at sources dot redhat dot com, Pedro Alves <pedro at codesourcery dot com>
- Date: Fri, 8 Jan 2010 14:32:02 +0300
- Subject: cancel_breakpoints_callback
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:
&"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
@@ -3418,6 +3418,7 @@ retry:
if (WIFSTOPPED (lp->status))
if (WSTOPSIG (lp->status) != SIGSTOP)
stop_callback (lp, NULL);
@@ -3428,10 +3429,14 @@ retry:
stop_wait_callback (lp, NULL);
lp->stopped = 1;
- lp->signalled = 0;
+ if (WSTOPSIG (lp->status) == SIGSTOP)
+ lp->signalled = 0;
+ gdb_assert (status_callback (lp, NULL));
else if (WIFEXITED (status) || WIFSIGNALED (status))
@@ -3620,7 +3625,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)