[patch] gdbserver: dead-loop on gdb.multi/watchpoint-multi.exp
Jan Kratochvil
jan.kratochvil@redhat.com
Tue Jan 24 16:56:00 GMT 2012
Hi Pedro,
extracted the pending part of:
Re: [patch 2/2] Fix watchpoints for multi-inferior #2
http://sourceware.org/ml/gdb-patches/2012-01/msg00818.html
The patch is for dead-loop of:
Got an event from pending child 10373 (057f)
Got a pending child 10373
Got an event from pending child 10373 (057f)
Got a pending child 10373
because linux_wait_for_event creates creates status_pending_p and then asks
linux_wait_for_event_1 for the next event which apparently returns the newly
created status_pending_p so linux_wait_for_event stores it back and so on.
gdb.multi/watchpoint-multi.exp patch below is just to test it with FSF GDB
HEAD. That part should not be checked in, Pedro has a WIP patch for running
the whole testsuite in extended-remote mode instead.
Thanks,
Jan
gdb/gdbserver/
2012-01-20 Jan Kratochvil <jan.kratochvil@redhat.com>
* linux-low.c (linux_wait_for_event_1): Rename to ...
(linux_wait_for_event): ... here and merge it with former
linux_wait_for_event - new variable wait_ptid, use it.
(linux_wait_for_event): Remove - merge it to linux_wait_for_event_1.
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -1569,9 +1569,10 @@ ptid_t step_over_bkpt;
the stopped child otherwise. */
static int
-linux_wait_for_event_1 (ptid_t ptid, int *wstat, int options)
+linux_wait_for_event (ptid_t ptid, int *wstat, int options)
{
struct lwp_info *event_child, *requested_child;
+ ptid_t wait_ptid;
event_child = NULL;
requested_child = NULL;
@@ -1620,13 +1621,24 @@ linux_wait_for_event_1 (ptid_t ptid, int *wstat, int options)
return lwpid_of (event_child);
}
+ if (ptid_is_pid (ptid))
+ {
+ /* A request to wait for a specific tgid. This is not possible
+ with waitpid, so instead, we wait for any child, and leave
+ children we're not interested in right now with a pending
+ status to report later. */
+ wait_ptid = minus_one_ptid;
+ }
+ else
+ wait_ptid = ptid;
+
/* We only enter this loop if no process has a pending wait status. Thus
any action taken in response to a wait status inside this loop is
responding as soon as we detect the status, not after any pending
events. */
while (1)
{
- event_child = linux_wait_for_lwp (ptid, wstat, options);
+ event_child = linux_wait_for_lwp (wait_ptid, wstat, options);
if ((options & WNOHANG) && event_child == NULL)
{
@@ -1638,6 +1650,19 @@ linux_wait_for_event_1 (ptid_t ptid, int *wstat, int options)
if (event_child == NULL)
error ("event from unknown child");
+ if (ptid_is_pid (ptid)
+ && ptid_get_pid (ptid) != ptid_get_pid (ptid_of (event_child)))
+ {
+ if (! WIFSTOPPED (*wstat))
+ mark_lwp_dead (event_child, *wstat);
+ else
+ {
+ event_child->status_pending_p = 1;
+ event_child->status_pending = *wstat;
+ }
+ continue;
+ }
+
current_inferior = get_lwp_thread (event_child);
/* Check for thread exit. */
@@ -1730,48 +1755,6 @@ linux_wait_for_event_1 (ptid_t ptid, int *wstat, int options)
return 0;
}
-static int
-linux_wait_for_event (ptid_t ptid, int *wstat, int options)
-{
- ptid_t wait_ptid;
-
- if (ptid_is_pid (ptid))
- {
- /* A request to wait for a specific tgid. This is not possible
- with waitpid, so instead, we wait for any child, and leave
- children we're not interested in right now with a pending
- status to report later. */
- wait_ptid = minus_one_ptid;
- }
- else
- wait_ptid = ptid;
-
- while (1)
- {
- int event_pid;
-
- event_pid = linux_wait_for_event_1 (wait_ptid, wstat, options);
-
- if (event_pid > 0
- && ptid_is_pid (ptid) && ptid_get_pid (ptid) != event_pid)
- {
- struct lwp_info *event_child
- = find_lwp_pid (pid_to_ptid (event_pid));
-
- if (! WIFSTOPPED (*wstat))
- mark_lwp_dead (event_child, *wstat);
- else
- {
- event_child->status_pending_p = 1;
- event_child->status_pending = *wstat;
- }
- }
- else
- return event_pid;
- }
-}
-
-
/* Count the LWP's that have had events. */
static int
--- a/gdb/testsuite/gdb.multi/watchpoint-multi.exp
+++ b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
@@ -12,6 +12,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+load_lib gdbserver-support.exp
set testfile "watchpoint-multi"
@@ -40,6 +41,11 @@ if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executa
clean_restart $executable
+set target_exec [gdbserver_download_current_prog]
+gdbserver_start_extended
+
+gdb_test_no_output "set remote exec-file $target_exec" "set remote exec-file"
+
# Simulate non-stop+target-async which also uses breakpoint always-inserted.
gdb_test_no_output "set breakpoint always-inserted on"
# displaced-stepping is also needed as other GDB sometimes still removes the
More information about the Gdb-patches
mailing list