This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] gdbserver: dead-loop on gdb.multi/watchpoint-multi.exp


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]