keiths / rpms / gdb

Forked from rpms/gdb 20 days ago
Clone
Jan Kratochvil 1bcf9b6
http://sourceware.org/ml/gdb-patches/2010-09/msg00360.html
Jan Kratochvil 1bcf9b6
Subject: [patch 3/4]#3 linux-nat: Do not respawn signals
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
Hi,
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
linux-nat.c is fixed to never respawn signals; possibly keeping SIGSTOP
Jan Kratochvil 1bcf9b6
pending, as is done in current in FSF gdbserver and as suggested by Pedro:
Jan Kratochvil 1bcf9b6
	http://sourceware.org/ml/gdb-patches/2010-08/msg00544.html
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
The last linux-nat.c removed patch chunk comes from the initial implementation
Jan Kratochvil 1bcf9b6
by Mark Kettenis:
Jan Kratochvil 1bcf9b6
	[PATCH] New Linux threads support
Jan Kratochvil 1bcf9b6
	http://sourceware.org/ml/gdb-patches/2000-09/msg00020.html
Jan Kratochvil 1bcf9b6
	92280a75e017683bf8e4f339f4f85640b0700509
Jan Kratochvil 1bcf9b6
It gets in part reimplemented into the new stop_wait_callback <if (lp->step)>
Jan Kratochvil 1bcf9b6
part and partially just not needed as currently GDB never drops the signals as
Jan Kratochvil 1bcf9b6
it does not PTRACE_CONT the thread; signal is kept for processing:
Jan Kratochvil 1bcf9b6
	"RC: Not resuming sibling %s (has pending)\n"
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
In stop_wait_callback I believe breakpoints cancellation is not needed here,
Jan Kratochvil 1bcf9b6
it would be done later.
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
The testcase sigstep-threads.exp was written to catch a regression-like
Jan Kratochvil 1bcf9b6
appearance then the new <if (lp->step)> part of stop_wait_callback gets
Jan Kratochvil 1bcf9b6
removed.  Still the tecase fails even with FSF HEAD:
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
32        var++;                /* step-1 */
Jan Kratochvil 1bcf9b6
(gdb) step
Jan Kratochvil 1bcf9b6
Program received signal SIGUSR1, User defined signal 1.
Jan Kratochvil 1bcf9b6
Program received signal SIGUSR1, User defined signal 1.
Jan Kratochvil 1bcf9b6
31      {                       /* step-0 */
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
There is no reason why it shouldn't stop on line 33, between line 32 and line
Jan Kratochvil 1bcf9b6
33 no signal would occur.  Stepping of the current thread should not be
Jan Kratochvil 1bcf9b6
affected by whatever happens in the other threads as select_event_lwp has:
Jan Kratochvil 1bcf9b6
  /* Give preference to any LWP that is being single-stepped.  */
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
There is a problem that with FSF HEAD GDB does PTRACE_SINGLESTEP for thread A,
Jan Kratochvil 1bcf9b6
PTRACE_CONT for thread B (because of set scheduler-locking off), thread B hits
Jan Kratochvil 1bcf9b6
SIGUSR1, so GDB tkills thread A with SIGSTOP and it can receive SIGSTOP for
Jan Kratochvil 1bcf9b6
thread A before the SIGTRAP for completed PTRACE_SINGLESTEP.  At that moment
Jan Kratochvil 1bcf9b6
select_event_lwp. forgets it was stepping thread A because there is no pending
Jan Kratochvil 1bcf9b6
SIGTRAP event.  currently_stepping still remembers thread A was stepping so it
Jan Kratochvil 1bcf9b6
will later stop but as thread A was PTRACE_CONT-ed in the meantime it is too
Jan Kratochvil 1bcf9b6
late.
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
There is the new <if (lp->step)> part of stop_wait_callback to always track
Jan Kratochvil 1bcf9b6
thread A is stepping.  Due to different scheduling without this part the
Jan Kratochvil 1bcf9b6
changed GDB would very rarely stop in this testcase otherwise, making it look
Jan Kratochvil 1bcf9b6
as a regression.
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
I have some another patch I may post separately as if multiple signals happen
Jan Kratochvil 1bcf9b6
besides SIGTRAP GDB still may switch from thread A away (as not considering it
Jan Kratochvil 1bcf9b6
stepping) to thread B for SIGUSR and accidentally PTRACE_CONT thread A.
Jan Kratochvil 1bcf9b6
But I do not find this as a prerequisite for this patchset.
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
Thanks,
Jan Kratochvil 1bcf9b6
Jan
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
gdb/
Jan Kratochvil 1bcf9b6
2010-09-20  Jan Kratochvil  <jan.kratochvil@redhat.com>
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
	* linux-nat.c (stop_wait_callback): New gdb_assert.  Remove signals
Jan Kratochvil 1bcf9b6
	respawning; keep TP with SIGNALLED.  New debugging message "SWC:
Jan Kratochvil 1bcf9b6
	Delayed SIGSTOP caught for %s.".  Catch next signal if SIGSTOP has
Jan Kratochvil 1bcf9b6
	been caught and LP->STEP is set.
Jan Kratochvil 1bcf9b6
	(linux_nat_wait_1) <lp && lp->signalled>: Remove.
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
gdb/testsuite/
Jan Kratochvil 1bcf9b6
2010-09-20  Jan Kratochvil  <jan.kratochvil@redhat.com>
Jan Kratochvil 1bcf9b6
Jan Kratochvil 1bcf9b6
	* gdb.threads/siginfo-threads.exp: New file.
Jan Kratochvil 1bcf9b6
	* gdb.threads/siginfo-threads.c: New file.
Jan Kratochvil 1bcf9b6
	* gdb.threads/sigstep-threads.exp: New file.
Jan Kratochvil 1bcf9b6
	* gdb.threads/sigstep-threads.c: New file.
Jan Kratochvil 1bcf9b6
Jan Kratochvil b0e03f5
Index: gdb-7.2.50.20110117/gdb/linux-nat.c
Jan Kratochvil 1bcf9b6
===================================================================
Jan Kratochvil b0e03f5
--- gdb-7.2.50.20110117.orig/gdb/linux-nat.c	2011-01-17 15:53:14.000000000 +0100
Jan Kratochvil b0e03f5
+++ gdb-7.2.50.20110117/gdb/linux-nat.c	2011-01-17 16:05:57.000000000 +0100
Jan Kratochvil b0e03f5
@@ -2803,6 +2803,8 @@ stop_wait_callback (struct lwp_info *lp,
Jan Kratochvil 1bcf9b6
     {
Jan Kratochvil 1bcf9b6
       int status;
Jan Kratochvil 1bcf9b6
 
Jan Kratochvil 1bcf9b6
+      gdb_assert (lp->resumed);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
       status = wait_lwp (lp);
Jan Kratochvil 1bcf9b6
       if (status == 0)
Jan Kratochvil 1bcf9b6
 	return 0;
Jan Kratochvil b0e03f5
@@ -2828,110 +2830,61 @@ stop_wait_callback (struct lwp_info *lp,
Jan Kratochvil 1bcf9b6
 
Jan Kratochvil 1bcf9b6
       if (WSTOPSIG (status) != SIGSTOP)
Jan Kratochvil 1bcf9b6
 	{
Jan Kratochvil e00e5ea
-	  if (linux_nat_status_is_event (status))
Jan Kratochvil 1bcf9b6
-	    {
Jan Kratochvil 1bcf9b6
-	      /* If a LWP other than the LWP that we're reporting an
Jan Kratochvil 1bcf9b6
-	         event for has hit a GDB breakpoint (as opposed to
Jan Kratochvil 1bcf9b6
-	         some random trap signal), then just arrange for it to
Jan Kratochvil 1bcf9b6
-	         hit it again later.  We don't keep the SIGTRAP status
Jan Kratochvil 1bcf9b6
-	         and don't forward the SIGTRAP signal to the LWP.  We
Jan Kratochvil 1bcf9b6
-	         will handle the current event, eventually we will
Jan Kratochvil 1bcf9b6
-	         resume all LWPs, and this one will get its breakpoint
Jan Kratochvil 1bcf9b6
-	         trap again.
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil 1bcf9b6
-	         If we do not do this, then we run the risk that the
Jan Kratochvil 1bcf9b6
-	         user will delete or disable the breakpoint, but the
Jan Kratochvil 1bcf9b6
-	         thread will have already tripped on it.  */
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil 1bcf9b6
-	      /* Save the trap's siginfo in case we need it later.  */
Jan Kratochvil 1bcf9b6
-	      save_siginfo (lp);
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil 1bcf9b6
-	      save_sigtrap (lp);
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil b0e03f5
-	      /* Now resume this LWP and get the SIGSTOP event.  */
Jan Kratochvil 1bcf9b6
-	      errno = 0;
Jan Kratochvil 1bcf9b6
-	      ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
Jan Kratochvil 1bcf9b6
-	      if (debug_linux_nat)
Jan Kratochvil 1bcf9b6
-		{
Jan Kratochvil 1bcf9b6
-		  fprintf_unfiltered (gdb_stdlog,
Jan Kratochvil 1bcf9b6
-				      "PTRACE_CONT %s, 0, 0 (%s)\n",
Jan Kratochvil 1bcf9b6
-				      target_pid_to_str (lp->ptid),
Jan Kratochvil 1bcf9b6
-				      errno ? safe_strerror (errno) : "OK");
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil 1bcf9b6
-		  fprintf_unfiltered (gdb_stdlog,
Jan Kratochvil 1bcf9b6
-				      "SWC: Candidate SIGTRAP event in %s\n",
Jan Kratochvil 1bcf9b6
-				      target_pid_to_str (lp->ptid));
Jan Kratochvil 1bcf9b6
-		}
Jan Kratochvil 1bcf9b6
-	      /* Hold this event/waitstatus while we check to see if
Jan Kratochvil b0e03f5
-		 there are any more (we still want to get that SIGSTOP).  */
Jan Kratochvil 1bcf9b6
-	      stop_wait_callback (lp, NULL);
Jan Kratochvil 1bcf9b6
+	  /* The thread was stopped with a signal other than SIGSTOP.  */
Jan Kratochvil 1bcf9b6
 
Jan Kratochvil 1bcf9b6
-	      /* Hold the SIGTRAP for handling by linux_nat_wait.  If
Jan Kratochvil 1bcf9b6
-		 there's another event, throw it back into the
Jan Kratochvil b0e03f5
-		 queue.  */
Jan Kratochvil 1bcf9b6
-	      if (lp->status)
Jan Kratochvil 1bcf9b6
-		{
Jan Kratochvil 1bcf9b6
-		  if (debug_linux_nat)
Jan Kratochvil 1bcf9b6
-		    fprintf_unfiltered (gdb_stdlog,
Jan Kratochvil 1bcf9b6
-					"SWC: kill %s, %s\n",
Jan Kratochvil 1bcf9b6
-					target_pid_to_str (lp->ptid),
Jan Kratochvil 1bcf9b6
-					status_to_str ((int) status));
Jan Kratochvil 1bcf9b6
-		  kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (lp->status));
Jan Kratochvil 1bcf9b6
-		}
Jan Kratochvil 1bcf9b6
+	  /* Save the trap's siginfo in case we need it later.  */
Jan Kratochvil 1bcf9b6
+	  save_siginfo (lp);
Jan Kratochvil 1bcf9b6
 
Jan Kratochvil b0e03f5
-	      /* Save the sigtrap event.  */
Jan Kratochvil 1bcf9b6
-	      lp->status = status;
Jan Kratochvil 1bcf9b6
-	      return 0;
Jan Kratochvil 1bcf9b6
-	    }
Jan Kratochvil 1bcf9b6
-	  else
Jan Kratochvil 1bcf9b6
-	    {
Jan Kratochvil 1bcf9b6
-	      /* The thread was stopped with a signal other than
Jan Kratochvil b0e03f5
-	         SIGSTOP, and didn't accidentally trip a breakpoint.  */
Jan Kratochvil 1bcf9b6
+	  save_sigtrap (lp);
Jan Kratochvil 1bcf9b6
 
Jan Kratochvil 1bcf9b6
-	      if (debug_linux_nat)
Jan Kratochvil 1bcf9b6
-		{
Jan Kratochvil 1bcf9b6
-		  fprintf_unfiltered (gdb_stdlog,
Jan Kratochvil 1bcf9b6
-				      "SWC: Pending event %s in %s\n",
Jan Kratochvil 1bcf9b6
-				      status_to_str ((int) status),
Jan Kratochvil 1bcf9b6
-				      target_pid_to_str (lp->ptid));
Jan Kratochvil 1bcf9b6
-		}
Jan Kratochvil b0e03f5
-	      /* Now resume this LWP and get the SIGSTOP event.  */
Jan Kratochvil 1bcf9b6
-	      errno = 0;
Jan Kratochvil 1bcf9b6
-	      ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
Jan Kratochvil 1bcf9b6
-	      if (debug_linux_nat)
Jan Kratochvil 1bcf9b6
-		fprintf_unfiltered (gdb_stdlog,
Jan Kratochvil 1bcf9b6
-				    "SWC: PTRACE_CONT %s, 0, 0 (%s)\n",
Jan Kratochvil 1bcf9b6
-				    target_pid_to_str (lp->ptid),
Jan Kratochvil 1bcf9b6
-				    errno ? safe_strerror (errno) : "OK");
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil 1bcf9b6
-	      /* Hold this event/waitstatus while we check to see if
Jan Kratochvil b0e03f5
-	         there are any more (we still want to get that SIGSTOP).  */
Jan Kratochvil 1bcf9b6
-	      stop_wait_callback (lp, NULL);
Jan Kratochvil 1bcf9b6
+	  if (debug_linux_nat)
Jan Kratochvil 1bcf9b6
+	    fprintf_unfiltered (gdb_stdlog,
Jan Kratochvil 1bcf9b6
+				"SWC: Pending event %s in %s\n",
Jan Kratochvil 1bcf9b6
+				status_to_str ((int) status),
Jan Kratochvil 1bcf9b6
+				target_pid_to_str (lp->ptid));
Jan Kratochvil 1bcf9b6
 
Jan Kratochvil 1bcf9b6
-	      /* If the lp->status field is still empty, use it to
Jan Kratochvil 1bcf9b6
-		 hold this event.  If not, then this event must be
Jan Kratochvil 1bcf9b6
-		 returned to the event queue of the LWP.  */
Jan Kratochvil 1bcf9b6
-	      if (lp->status)
Jan Kratochvil 1bcf9b6
-		{
Jan Kratochvil 1bcf9b6
-		  if (debug_linux_nat)
Jan Kratochvil 1bcf9b6
-		    {
Jan Kratochvil 1bcf9b6
-		      fprintf_unfiltered (gdb_stdlog,
Jan Kratochvil 1bcf9b6
-					  "SWC: kill %s, %s\n",
Jan Kratochvil 1bcf9b6
-					  target_pid_to_str (lp->ptid),
Jan Kratochvil 1bcf9b6
-					  status_to_str ((int) status));
Jan Kratochvil 1bcf9b6
-		    }
Jan Kratochvil 1bcf9b6
-		  kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (status));
Jan Kratochvil 1bcf9b6
-		}
Jan Kratochvil 1bcf9b6
-	      else
Jan Kratochvil 1bcf9b6
-		lp->status = status;
Jan Kratochvil 1bcf9b6
-	      return 0;
Jan Kratochvil 1bcf9b6
-	    }
Jan Kratochvil b0e03f5
+	  /* Save the sigtrap event.  */
Jan Kratochvil 1bcf9b6
+	  lp->status = status;
Jan Kratochvil 1bcf9b6
+	  gdb_assert (! lp->stopped);
Jan Kratochvil 1bcf9b6
+	  gdb_assert (lp->signalled);
Jan Kratochvil 1bcf9b6
+	  lp->stopped = 1;
Jan Kratochvil 1bcf9b6
 	}
Jan Kratochvil 1bcf9b6
       else
Jan Kratochvil 1bcf9b6
 	{
Jan Kratochvil 1bcf9b6
 	  /* We caught the SIGSTOP that we intended to catch, so
Jan Kratochvil 1bcf9b6
 	     there's no SIGSTOP pending.  */
Jan Kratochvil 1bcf9b6
-	  lp->stopped = 1;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+	  if (debug_linux_nat)
Jan Kratochvil 1bcf9b6
+	    fprintf_unfiltered (gdb_stdlog,
Jan Kratochvil 1bcf9b6
+				"SWC: Delayed SIGSTOP caught for %s.\n",
Jan Kratochvil 1bcf9b6
+				target_pid_to_str (lp->ptid));
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+	  if (lp->step)
Jan Kratochvil 1bcf9b6
+	    {
Jan Kratochvil 1bcf9b6
+	      /* LP->STATUS is 0 here.  That means SIGTRAP from
Jan Kratochvil 1bcf9b6
+		 PTRACE_SINGLESTEP still has to be delivered for this inferior
Jan Kratochvil 1bcf9b6
+		 stop.  Catching the SIGTRAP event is important to prevent
Jan Kratochvil 1bcf9b6
+		 starvation in select_event_lwp.  */
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+	      registers_changed ();
Jan Kratochvil 1bcf9b6
+	      linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
Jan Kratochvil 1bcf9b6
+				    1, TARGET_SIGNAL_0);
Jan Kratochvil 1bcf9b6
+	      if (debug_linux_nat)
Jan Kratochvil 1bcf9b6
+		fprintf_unfiltered (gdb_stdlog,
Jan Kratochvil 1bcf9b6
+				    "SWC: %s %s, 0, 0 (discard SIGSTOP)\n",
Jan Kratochvil 1bcf9b6
+				    "PTRACE_SINGLESTEP",
Jan Kratochvil 1bcf9b6
+				    target_pid_to_str (lp->ptid));
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+	      lp->stopped = 0;
Jan Kratochvil 1bcf9b6
+	      gdb_assert (lp->resumed);
Jan Kratochvil 1bcf9b6
+	      stop_wait_callback (lp, NULL);
Jan Kratochvil 1bcf9b6
+	      gdb_assert (lp->stopped);
Jan Kratochvil 1bcf9b6
+	    }
Jan Kratochvil 1bcf9b6
+	  else
Jan Kratochvil 1bcf9b6
+	    lp->stopped = 1;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+	  /* Reset SIGNALLED only after the stop_wait_callback call above as
Jan Kratochvil 1bcf9b6
+	     it does gdb_assert on SIGNALLED.  */
Jan Kratochvil 1bcf9b6
 	  lp->signalled = 0;
Jan Kratochvil 1bcf9b6
 	}
Jan Kratochvil 1bcf9b6
     }
Jan Kratochvil b0e03f5
@@ -3514,52 +3467,6 @@ retry:
Jan Kratochvil 1bcf9b6
 	lp = NULL;
Jan Kratochvil 1bcf9b6
     }
Jan Kratochvil 1bcf9b6
 
Jan Kratochvil 1bcf9b6
-  if (lp && lp->signalled)
Jan Kratochvil 1bcf9b6
-    {
Jan Kratochvil 1bcf9b6
-      /* A pending SIGSTOP may interfere with the normal stream of
Jan Kratochvil 1bcf9b6
-         events.  In a typical case where interference is a problem,
Jan Kratochvil 1bcf9b6
-         we have a SIGSTOP signal pending for LWP A while
Jan Kratochvil 1bcf9b6
-         single-stepping it, encounter an event in LWP B, and take the
Jan Kratochvil 1bcf9b6
-         pending SIGSTOP while trying to stop LWP A.  After processing
Jan Kratochvil 1bcf9b6
-         the event in LWP B, LWP A is continued, and we'll never see
Jan Kratochvil 1bcf9b6
-         the SIGTRAP associated with the last time we were
Jan Kratochvil 1bcf9b6
-         single-stepping LWP A.  */
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil 1bcf9b6
-      /* Resume the thread.  It should halt immediately returning the
Jan Kratochvil 1bcf9b6
-         pending SIGSTOP.  */
Jan Kratochvil 1bcf9b6
-      registers_changed ();
Jan Kratochvil 1bcf9b6
-      linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
Jan Kratochvil 1bcf9b6
-			    lp->step, TARGET_SIGNAL_0);
Jan Kratochvil 1bcf9b6
-      if (debug_linux_nat)
Jan Kratochvil 1bcf9b6
-	fprintf_unfiltered (gdb_stdlog,
Jan Kratochvil 1bcf9b6
-			    "LLW: %s %s, 0, 0 (expect SIGSTOP)\n",
Jan Kratochvil 1bcf9b6
-			    lp->step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
Jan Kratochvil 1bcf9b6
-			    target_pid_to_str (lp->ptid));
Jan Kratochvil 1bcf9b6
-      lp->stopped = 0;
Jan Kratochvil 1bcf9b6
-      gdb_assert (lp->resumed);
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil 1bcf9b6
-      /* Catch the pending SIGSTOP.  */
Jan Kratochvil 1bcf9b6
-      status = lp->status;
Jan Kratochvil 1bcf9b6
-      lp->status = 0;
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil 1bcf9b6
-      stop_wait_callback (lp, NULL);
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil 1bcf9b6
-      /* If the lp->status field isn't empty, we caught another signal
Jan Kratochvil 1bcf9b6
-	 while flushing the SIGSTOP.  Return it back to the event
Jan Kratochvil 1bcf9b6
-	 queue of the LWP, as we already have an event to handle.  */
Jan Kratochvil 1bcf9b6
-      if (lp->status)
Jan Kratochvil 1bcf9b6
-	{
Jan Kratochvil 1bcf9b6
-	  if (debug_linux_nat)
Jan Kratochvil 1bcf9b6
-	    fprintf_unfiltered (gdb_stdlog,
Jan Kratochvil 1bcf9b6
-				"LLW: kill %s, %s\n",
Jan Kratochvil 1bcf9b6
-				target_pid_to_str (lp->ptid),
Jan Kratochvil 1bcf9b6
-				status_to_str (lp->status));
Jan Kratochvil 1bcf9b6
-	  kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (lp->status));
Jan Kratochvil 1bcf9b6
-	}
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil 1bcf9b6
-      lp->status = status;
Jan Kratochvil 1bcf9b6
-    }
Jan Kratochvil 1bcf9b6
-
Jan Kratochvil 1bcf9b6
   if (!target_can_async_p ())
Jan Kratochvil 1bcf9b6
     {
Jan Kratochvil 1bcf9b6
       /* Causes SIGINT to be passed on to the attached process.  */
Jan Kratochvil b0e03f5
Index: gdb-7.2.50.20110117/gdb/testsuite/gdb.threads/siginfo-threads.c
Jan Kratochvil 1bcf9b6
===================================================================
Jan Kratochvil 1bcf9b6
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
Jan Kratochvil b0e03f5
+++ gdb-7.2.50.20110117/gdb/testsuite/gdb.threads/siginfo-threads.c	2011-01-17 16:02:40.000000000 +0100
Jan Kratochvil 1bcf9b6
@@ -0,0 +1,447 @@
Jan Kratochvil 1bcf9b6
+/* This testcase is part of GDB, the GNU debugger.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+   Copyright 2010 Free Software Foundation, Inc.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+   This program is free software; you can redistribute it and/or modify
Jan Kratochvil 1bcf9b6
+   it under the terms of the GNU General Public License as published by
Jan Kratochvil 1bcf9b6
+   the Free Software Foundation; either version 3 of the License, or
Jan Kratochvil 1bcf9b6
+   (at your option) any later version.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+   This program is distributed in the hope that it will be useful,
Jan Kratochvil 1bcf9b6
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
Jan Kratochvil 1bcf9b6
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Jan Kratochvil 1bcf9b6
+   GNU General Public License for more details.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+   You should have received a copy of the GNU General Public License
Jan Kratochvil 1bcf9b6
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+#define _GNU_SOURCE
Jan Kratochvil 1bcf9b6
+#include <pthread.h>
Jan Kratochvil 1bcf9b6
+#include <stdio.h>
Jan Kratochvil 1bcf9b6
+#include <limits.h>
Jan Kratochvil 1bcf9b6
+#include <errno.h>
Jan Kratochvil 1bcf9b6
+#include <stdlib.h>
Jan Kratochvil 1bcf9b6
+#include <string.h>
Jan Kratochvil 1bcf9b6
+#include <assert.h>
Jan Kratochvil 1bcf9b6
+#include <sys/types.h>
Jan Kratochvil 1bcf9b6
+#include <signal.h>
Jan Kratochvil 1bcf9b6
+#include <unistd.h>
Jan Kratochvil 1bcf9b6
+#include <asm/unistd.h>
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+#define gettid() syscall (__NR_gettid)
Jan Kratochvil 1bcf9b6
+#define tgkill(tgid, tid, sig) syscall (__NR_tgkill, tgid, tid, sig)
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+/* Terminate always in the main task, it can lock up with SIGSTOPped GDB
Jan Kratochvil 1bcf9b6
+   otherwise.  */
Jan Kratochvil 1bcf9b6
+#define TIMEOUT (gettid () == getpid() ? 10 : 15)
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static pid_t thread1_tid;
Jan Kratochvil 1bcf9b6
+static pthread_cond_t thread1_tid_cond = PTHREAD_COND_INITIALIZER;
Jan Kratochvil 1bcf9b6
+static pthread_mutex_t thread1_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
Jan Kratochvil 1bcf9b6
+static int thread1_sigusr1_hit;
Jan Kratochvil 1bcf9b6
+static int thread1_sigusr2_hit;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static pid_t thread2_tid;
Jan Kratochvil 1bcf9b6
+static pthread_cond_t thread2_tid_cond = PTHREAD_COND_INITIALIZER;
Jan Kratochvil 1bcf9b6
+static pthread_mutex_t thread2_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
Jan Kratochvil 1bcf9b6
+static int thread2_sigusr1_hit;
Jan Kratochvil 1bcf9b6
+static int thread2_sigusr2_hit;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static pthread_mutex_t terminate_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+/* Do not use alarm as it would create a ptrace event which would hang up us if
Jan Kratochvil 1bcf9b6
+   we are being traced by GDB which we stopped ourselves.  */
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static void timed_mutex_lock (pthread_mutex_t *mutex)
Jan Kratochvil 1bcf9b6
+{
Jan Kratochvil 1bcf9b6
+  int i;
Jan Kratochvil 1bcf9b6
+  struct timespec start, now;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  i = clock_gettime (CLOCK_MONOTONIC, &start;;
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  do
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      i = pthread_mutex_trylock (mutex);
Jan Kratochvil 1bcf9b6
+      if (i == 0)
Jan Kratochvil 1bcf9b6
+	return;
Jan Kratochvil 1bcf9b6
+      assert (i == EBUSY);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      i = clock_gettime (CLOCK_MONOTONIC, &now;;
Jan Kratochvil 1bcf9b6
+      assert (i == 0);
Jan Kratochvil 1bcf9b6
+      assert (now.tv_sec >= start.tv_sec);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+  while (now.tv_sec - start.tv_sec < TIMEOUT);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  fprintf (stderr, "Timed out waiting for internal lock!\n");
Jan Kratochvil 1bcf9b6
+  exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static void
Jan Kratochvil 1bcf9b6
+handler (int signo, siginfo_t *siginfo, void *exception)
Jan Kratochvil 1bcf9b6
+{
Jan Kratochvil 1bcf9b6
+  int *varp;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  assert (siginfo->si_signo == signo);
Jan Kratochvil 1bcf9b6
+  assert (siginfo->si_code == SI_TKILL);
Jan Kratochvil 1bcf9b6
+  assert (siginfo->si_pid == getpid ());
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  if (gettid () == thread1_tid)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      if (signo == SIGUSR1)
Jan Kratochvil 1bcf9b6
+	varp = &thread1_sigusr1_hit;
Jan Kratochvil 1bcf9b6
+      else if (signo == SIGUSR2)
Jan Kratochvil 1bcf9b6
+	varp = &thread1_sigusr2_hit;
Jan Kratochvil 1bcf9b6
+      else
Jan Kratochvil 1bcf9b6
+	assert (0);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+  else if (gettid () == thread2_tid)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      if (signo == SIGUSR1)
Jan Kratochvil 1bcf9b6
+	varp = &thread2_sigusr1_hit;
Jan Kratochvil 1bcf9b6
+      else if (signo == SIGUSR2)
Jan Kratochvil 1bcf9b6
+	varp = &thread2_sigusr2_hit;
Jan Kratochvil 1bcf9b6
+      else
Jan Kratochvil 1bcf9b6
+	assert (0);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+  else
Jan Kratochvil 1bcf9b6
+    assert (0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  if (*varp)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      fprintf (stderr, "Signal %d for TID %lu has been already hit!\n", signo,
Jan Kratochvil 1bcf9b6
+	       (unsigned long) gettid ());
Jan Kratochvil 1bcf9b6
+      exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+  *varp = 1;
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static void *
Jan Kratochvil 1bcf9b6
+thread1_func (void *unused)
Jan Kratochvil 1bcf9b6
+{
Jan Kratochvil 1bcf9b6
+  int i;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  timed_mutex_lock (&thread1_tid_mutex);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  /* THREAD1_TID_MUTEX must be already locked to avoid race.  */
Jan Kratochvil 1bcf9b6
+  thread1_tid = gettid ();
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  i = pthread_cond_signal (&thread1_tid_cond);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+  i = pthread_mutex_unlock (&thread1_tid_mutex);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  /* Be sure the "t (tracing stop)" test can proceed for both threads.  */
Jan Kratochvil 1bcf9b6
+  timed_mutex_lock (&terminate_mutex);
Jan Kratochvil 1bcf9b6
+  i = pthread_mutex_unlock (&terminate_mutex);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  if (! thread1_sigusr1_hit)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      fprintf (stderr, "Thread 1 signal SIGUSR1 not hit!\n");
Jan Kratochvil 1bcf9b6
+      exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+  if (! thread1_sigusr2_hit)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      fprintf (stderr, "Thread 1 signal SIGUSR2 not hit!\n");
Jan Kratochvil 1bcf9b6
+      exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  return NULL;
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static void *
Jan Kratochvil 1bcf9b6
+thread2_func (void *unused)
Jan Kratochvil 1bcf9b6
+{
Jan Kratochvil 1bcf9b6
+  int i;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  timed_mutex_lock (&thread2_tid_mutex);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  /* THREAD2_TID_MUTEX must be already locked to avoid race.  */
Jan Kratochvil 1bcf9b6
+  thread2_tid = gettid ();
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  i = pthread_cond_signal (&thread2_tid_cond);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+  i = pthread_mutex_unlock (&thread2_tid_mutex);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  /* Be sure the "t (tracing stop)" test can proceed for both threads.  */
Jan Kratochvil 1bcf9b6
+  timed_mutex_lock (&terminate_mutex);
Jan Kratochvil 1bcf9b6
+  i = pthread_mutex_unlock (&terminate_mutex);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  if (! thread2_sigusr1_hit)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      fprintf (stderr, "Thread 2 signal SIGUSR1 not hit!\n");
Jan Kratochvil 1bcf9b6
+      exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+  if (! thread2_sigusr2_hit)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      fprintf (stderr, "Thread 2 signal SIGUSR2 not hit!\n");
Jan Kratochvil 1bcf9b6
+      exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  return NULL;
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static const char *
Jan Kratochvil 1bcf9b6
+proc_string (const char *filename, const char *line)
Jan Kratochvil 1bcf9b6
+{
Jan Kratochvil 1bcf9b6
+  FILE *f;
Jan Kratochvil 1bcf9b6
+  static char buf[LINE_MAX];
Jan Kratochvil 1bcf9b6
+  size_t line_len = strlen (line);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  f = fopen (filename, "r");
Jan Kratochvil 1bcf9b6
+  if (f == NULL)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      fprintf (stderr, "fopen (\"%s\") for \"%s\": %s\n", filename, line,
Jan Kratochvil 1bcf9b6
+	       strerror (errno));
Jan Kratochvil 1bcf9b6
+      exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+  while (errno = 0, fgets (buf, sizeof (buf), f))
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      char *s;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      s = strchr (buf, '\n');
Jan Kratochvil 1bcf9b6
+      assert (s != NULL);
Jan Kratochvil 1bcf9b6
+      *s = 0;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      if (strncmp (buf, line, line_len) != 0)
Jan Kratochvil 1bcf9b6
+	continue;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      if (fclose (f))
Jan Kratochvil 1bcf9b6
+	{
Jan Kratochvil 1bcf9b6
+	  fprintf (stderr, "fclose (\"%s\") for \"%s\": %s\n", filename, line,
Jan Kratochvil 1bcf9b6
+		   strerror (errno));
Jan Kratochvil 1bcf9b6
+	  exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      return &buf[line_len];
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+  if (errno != 0)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      fprintf (stderr, "fgets (\"%s\": %s\n", filename, strerror (errno));
Jan Kratochvil 1bcf9b6
+      exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+  fprintf (stderr, "\"%s\": No line \"%s\" found.\n", filename, line);
Jan Kratochvil 1bcf9b6
+  exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static unsigned long
Jan Kratochvil 1bcf9b6
+proc_ulong (const char *filename, const char *line)
Jan Kratochvil 1bcf9b6
+{
Jan Kratochvil 1bcf9b6
+  const char *s = proc_string (filename, line);
Jan Kratochvil 1bcf9b6
+  long retval;
Jan Kratochvil 1bcf9b6
+  char *end;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  errno = 0;
Jan Kratochvil 1bcf9b6
+  retval = strtol (s, &end, 10);
Jan Kratochvil 1bcf9b6
+  if (retval < 0 || retval >= LONG_MAX || (end && *end))
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      fprintf (stderr, "\"%s\":\"%s\": %ld, %s\n", filename, line, retval,
Jan Kratochvil 1bcf9b6
+	       strerror (errno));
Jan Kratochvil 1bcf9b6
+      exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+  return retval;
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static void
Jan Kratochvil 1bcf9b6
+state_wait (pid_t process, const char *wanted)
Jan Kratochvil 1bcf9b6
+{
Jan Kratochvil 1bcf9b6
+  char *filename;
Jan Kratochvil 1bcf9b6
+  int i;
Jan Kratochvil 1bcf9b6
+  struct timespec start, now;
Jan Kratochvil 1bcf9b6
+  const char *state;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  i = asprintf (&filename, "/proc/%lu/status", (unsigned long) process);
Jan Kratochvil 1bcf9b6
+  assert (i > 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  i = clock_gettime (CLOCK_MONOTONIC, &start;;
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  do
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      state = proc_string (filename, "State:\t");
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      /* torvalds/linux-2.6.git 464763cf1c6df632dccc8f2f4c7e50163154a2c0
Jan Kratochvil 1bcf9b6
+	 has changed "T (tracing stop)" to "t (tracing stop)".  Make the GDB
Jan Kratochvil 1bcf9b6
+	 testcase backward compatible with older Linux kernels.  */
Jan Kratochvil 1bcf9b6
+      if (strcmp (state, "T (tracing stop)") == 0)
Jan Kratochvil 1bcf9b6
+	state = "t (tracing stop)";
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      if (strcmp (state, wanted) == 0)
Jan Kratochvil 1bcf9b6
+	{
Jan Kratochvil 1bcf9b6
+	  free (filename);
Jan Kratochvil 1bcf9b6
+	  return;
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      if (sched_yield ())
Jan Kratochvil 1bcf9b6
+	{
Jan Kratochvil 1bcf9b6
+	  perror ("sched_yield()");
Jan Kratochvil 1bcf9b6
+	  exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      i = clock_gettime (CLOCK_MONOTONIC, &now;;
Jan Kratochvil 1bcf9b6
+      assert (i == 0);
Jan Kratochvil 1bcf9b6
+      assert (now.tv_sec >= start.tv_sec);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+  while (now.tv_sec - start.tv_sec < TIMEOUT);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  fprintf (stderr, "Timed out waiting for PID %lu \"%s\" (now it is \"%s\")!\n",
Jan Kratochvil 1bcf9b6
+	   (unsigned long) process, wanted, state);
Jan Kratochvil 1bcf9b6
+  exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static volatile pid_t tracer = 0;
Jan Kratochvil 1bcf9b6
+static pthread_t thread1, thread2;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static void
Jan Kratochvil 1bcf9b6
+cleanup (void)
Jan Kratochvil 1bcf9b6
+{
Jan Kratochvil 1bcf9b6
+  printf ("Resuming GDB PID %lu.\n", (unsigned long) tracer);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  if (tracer)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      int i;
Jan Kratochvil 1bcf9b6
+      int tracer_save = tracer;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      tracer = 0;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      i = kill (tracer_save, SIGCONT);
Jan Kratochvil 1bcf9b6
+      assert (i == 0);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+int
Jan Kratochvil 1bcf9b6
+main (int argc, char **argv)
Jan Kratochvil 1bcf9b6
+{
Jan Kratochvil 1bcf9b6
+  int i;
Jan Kratochvil 1bcf9b6
+  int standalone = 0;
Jan Kratochvil 1bcf9b6
+  struct sigaction act;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  if (argc == 2 && strcmp (argv[1], "-s") == 0)
Jan Kratochvil 1bcf9b6
+    standalone = 1;
Jan Kratochvil 1bcf9b6
+  else
Jan Kratochvil 1bcf9b6
+    assert (argc == 1);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  setbuf (stdout, NULL);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  timed_mutex_lock (&thread1_tid_mutex);
Jan Kratochvil 1bcf9b6
+  timed_mutex_lock (&thread2_tid_mutex);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  timed_mutex_lock (&terminate_mutex);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  errno = 0;
Jan Kratochvil 1bcf9b6
+  memset (&act, 0, sizeof (act));
Jan Kratochvil 1bcf9b6
+  act.sa_sigaction = handler;
Jan Kratochvil 1bcf9b6
+  act.sa_flags = SA_RESTART | SA_SIGINFO;
Jan Kratochvil 1bcf9b6
+  i = sigemptyset (&act.sa_mask);
Jan Kratochvil 1bcf9b6
+  assert_perror (errno);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+  i = sigaction (SIGUSR1, &act, NULL);
Jan Kratochvil 1bcf9b6
+  assert_perror (errno);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+  i = sigaction (SIGUSR2, &act, NULL);
Jan Kratochvil 1bcf9b6
+  assert_perror (errno);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  i = pthread_create (&thread1, NULL, thread1_func, NULL);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  i = pthread_create (&thread2, NULL, thread2_func, NULL);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  if (!standalone)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      tracer = proc_ulong ("/proc/self/status", "TracerPid:\t");
Jan Kratochvil 1bcf9b6
+      if (tracer == 0)
Jan Kratochvil 1bcf9b6
+	{
Jan Kratochvil 1bcf9b6
+	  fprintf (stderr, "The testcase must be run by GDB!\n");
Jan Kratochvil 1bcf9b6
+	  exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+      if (tracer != getppid ())
Jan Kratochvil 1bcf9b6
+	{
Jan Kratochvil 1bcf9b6
+	  fprintf (stderr, "The testcase parent must be our GDB tracer!\n");
Jan Kratochvil 1bcf9b6
+	  exit (EXIT_FAILURE);
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  /* SIGCONT our debugger in the case of our crash as we would deadlock
Jan Kratochvil 1bcf9b6
+     otherwise.  */
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  atexit (cleanup);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  printf ("Stopping GDB PID %lu.\n", (unsigned long) tracer);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  if (tracer)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      i = kill (tracer, SIGSTOP);
Jan Kratochvil 1bcf9b6
+      assert (i == 0);
Jan Kratochvil 1bcf9b6
+      state_wait (tracer, "T (stopped)");
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  /* Threads are now waiting at timed_mutex_lock (thread1_tid_mutex) and so
Jan Kratochvil 1bcf9b6
+     they could not trigger the signals before GDB gets unstopped later.
Jan Kratochvil 1bcf9b6
+     Threads get resumed at pthread_cond_wait below.  Use `while' loops for
Jan Kratochvil 1bcf9b6
+     protection against spurious pthread_cond_wait wakeups.  */
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  printf ("Waiting till the threads initialize their TIDs.\n");
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  while (thread1_tid == 0)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      i = pthread_cond_wait (&thread1_tid_cond, &thread1_tid_mutex);
Jan Kratochvil 1bcf9b6
+      assert (i == 0);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  while (thread2_tid == 0)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      i = pthread_cond_wait (&thread2_tid_cond, &thread2_tid_mutex);
Jan Kratochvil 1bcf9b6
+      assert (i == 0);
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  printf ("Thread 1 TID = %lu, thread 2 TID = %lu, PID = %lu.\n",
Jan Kratochvil 1bcf9b6
+	  (unsigned long) thread1_tid, (unsigned long) thread2_tid,
Jan Kratochvil 1bcf9b6
+	  (unsigned long) getpid ());
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  errno = 0;
Jan Kratochvil 1bcf9b6
+  i = tgkill (getpid (), thread1_tid, SIGUSR1);
Jan Kratochvil 1bcf9b6
+  assert_perror (errno);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+  i = tgkill (getpid (), thread1_tid, SIGUSR2);
Jan Kratochvil 1bcf9b6
+  assert_perror (errno);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+  i = tgkill (getpid (), thread2_tid, SIGUSR1);
Jan Kratochvil 1bcf9b6
+  assert_perror (errno);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+  i = tgkill (getpid (), thread2_tid, SIGUSR2);
Jan Kratochvil 1bcf9b6
+  assert_perror (errno);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  printf ("Waiting till the threads get trapped by the signals.\n");
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  if (tracer)
Jan Kratochvil 1bcf9b6
+    {
Jan Kratochvil 1bcf9b6
+      /* s390x-unknown-linux-gnu will fail with "R (running)".  */
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      state_wait (thread1_tid, "t (tracing stop)");
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+      state_wait (thread2_tid, "t (tracing stop)");
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  cleanup ();
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  printf ("Joining the threads.\n");
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  i = pthread_mutex_unlock (&terminate_mutex);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  i = pthread_join (thread1, NULL);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  i = pthread_join (thread2, NULL);
Jan Kratochvil 1bcf9b6
+  assert (i == 0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  printf ("Exiting.\n");	/* break-at-exit */
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  return EXIT_SUCCESS;
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil b0e03f5
Index: gdb-7.2.50.20110117/gdb/testsuite/gdb.threads/siginfo-threads.exp
Jan Kratochvil 1bcf9b6
===================================================================
Jan Kratochvil 1bcf9b6
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
Jan Kratochvil b0e03f5
+++ gdb-7.2.50.20110117/gdb/testsuite/gdb.threads/siginfo-threads.exp	2011-01-17 16:02:40.000000000 +0100
Jan Kratochvil 1bcf9b6
@@ -0,0 +1,94 @@
Jan Kratochvil 1bcf9b6
+# Copyright 2010 Free Software Foundation, Inc.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+# This program is free software; you can redistribute it and/or modify
Jan Kratochvil 1bcf9b6
+# it under the terms of the GNU General Public License as published by
Jan Kratochvil 1bcf9b6
+# the Free Software Foundation; either version 3 of the License, or
Jan Kratochvil 1bcf9b6
+# (at your option) any later version.
Jan Kratochvil 1bcf9b6
+#
Jan Kratochvil 1bcf9b6
+# This program is distributed in the hope that it will be useful,
Jan Kratochvil 1bcf9b6
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
Jan Kratochvil 1bcf9b6
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Jan Kratochvil 1bcf9b6
+# GNU General Public License for more details.
Jan Kratochvil 1bcf9b6
+#
Jan Kratochvil 1bcf9b6
+# You should have received a copy of the GNU General Public License
Jan Kratochvil 1bcf9b6
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+set testfile "siginfo-threads"
Jan Kratochvil 1bcf9b6
+set srcfile ${testfile}.c
Jan Kratochvil 1bcf9b6
+set binfile ${objdir}/${subdir}/${testfile}
Jan Kratochvil 1bcf9b6
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" ${binfile} executable [list debug additional_flags=-lrt]] != "" } {
Jan Kratochvil 1bcf9b6
+    return -1
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+clean_restart $testfile
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+if ![runto_main] {
Jan Kratochvil 1bcf9b6
+    return -1
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+# `nostop noprint pass' could in some cases report false PASS due to the
Jan Kratochvil 1bcf9b6
+# (preempt 'handle') code path.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+gdb_test "handle SIGUSR1 stop print pass" "Signal\[ \t\]+Stop\[ \t\]+Print\[ \t\]+Pass to program\[ \t\]+Description\r\nSIGUSR1\[ \t\]+Yes\[ \t\]+Yes\[ \t\]+Yes\[ \t\].*"
Jan Kratochvil 1bcf9b6
+gdb_test "handle SIGUSR2 stop print pass" "Signal\[ \t\]+Stop\[ \t\]+Print\[ \t\]+Pass to program\[ \t\]+Description\r\nSIGUSR2\[ \t\]+Yes\[ \t\]+Yes\[ \t\]+Yes\[ \t\].*"
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+gdb_breakpoint [gdb_get_line_number "break-at-exit"]
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+set test "get pid"
Jan Kratochvil 1bcf9b6
+gdb_test_multiple "p getpid ()" $test {
Jan Kratochvil 1bcf9b6
+    -re " = (\[0-9\]+)\r\n$gdb_prompt $" {
Jan Kratochvil 1bcf9b6
+	set pid $expect_out(1,string)
Jan Kratochvil 1bcf9b6
+	pass $test
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+for {set sigcount 0} {$sigcount < 4} {incr sigcount} {
Jan Kratochvil 1bcf9b6
+    set test "catch signal $sigcount"
Jan Kratochvil 1bcf9b6
+    set sigusr ""
Jan Kratochvil 1bcf9b6
+    gdb_test_multiple "continue" $test {
Jan Kratochvil 1bcf9b6
+	-re "Program received signal SIGUSR(\[12\]), User defined signal \[12\]\\.\r\n.*\r\n$gdb_prompt $" {
Jan Kratochvil 1bcf9b6
+	    set sigusr $expect_out(1,string)
Jan Kratochvil 1bcf9b6
+	    pass $test
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+    if {$sigusr == ""} {
Jan Kratochvil 1bcf9b6
+	return -1
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+    set test "signal $sigcount si_signo"
Jan Kratochvil 1bcf9b6
+    if {$sigusr == 1} {
Jan Kratochvil 1bcf9b6
+	set signo 10
Jan Kratochvil 1bcf9b6
+    } else {
Jan Kratochvil 1bcf9b6
+	set signo 12
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+    gdb_test_multiple {p $_siginfo.si_signo} $test {
Jan Kratochvil 1bcf9b6
+	-re " = $signo\r\n$gdb_prompt $" {
Jan Kratochvil 1bcf9b6
+	    pass $test
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+	-re "Attempt to extract a component of a value that is not a structure\\.\r\n$gdb_prompt $" {
Jan Kratochvil 1bcf9b6
+	    unsupported $test
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+    set test "signal $sigcount si_code is SI_TKILL"
Jan Kratochvil 1bcf9b6
+    gdb_test_multiple {p $_siginfo.si_code} $test {
Jan Kratochvil 1bcf9b6
+	-re " = -6\r\n$gdb_prompt $" {
Jan Kratochvil 1bcf9b6
+	    pass $test
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+	-re "Attempt to extract a component of a value that is not a structure\\.\r\n$gdb_prompt $" {
Jan Kratochvil 1bcf9b6
+	    unsupported $test
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+    set test "signal $sigcount si_pid"
Jan Kratochvil 1bcf9b6
+    gdb_test_multiple {p $_siginfo._sifields._kill.si_pid} $test {
Jan Kratochvil 1bcf9b6
+	-re " = $pid\r\n$gdb_prompt $" {
Jan Kratochvil 1bcf9b6
+	    pass $test
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+	-re "Attempt to extract a component of a value that is not a structure\\.\r\n$gdb_prompt $" {
Jan Kratochvil 1bcf9b6
+	    unsupported $test
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+gdb_continue_to_breakpoint break-at-exit ".*break-at-exit.*"
Jan Kratochvil b0e03f5
Index: gdb-7.2.50.20110117/gdb/testsuite/gdb.threads/sigstep-threads.c
Jan Kratochvil 1bcf9b6
===================================================================
Jan Kratochvil 1bcf9b6
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
Jan Kratochvil b0e03f5
+++ gdb-7.2.50.20110117/gdb/testsuite/gdb.threads/sigstep-threads.c	2011-01-17 16:02:40.000000000 +0100
Jan Kratochvil 1bcf9b6
@@ -0,0 +1,54 @@
Jan Kratochvil 1bcf9b6
+/* This testcase is part of GDB, the GNU debugger.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+   Copyright 2010 Free Software Foundation, Inc.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+   This program is free software; you can redistribute it and/or modify
Jan Kratochvil 1bcf9b6
+   it under the terms of the GNU General Public License as published by
Jan Kratochvil 1bcf9b6
+   the Free Software Foundation; either version 3 of the License, or
Jan Kratochvil 1bcf9b6
+   (at your option) any later version.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+   This program is distributed in the hope that it will be useful,
Jan Kratochvil 1bcf9b6
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
Jan Kratochvil 1bcf9b6
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Jan Kratochvil 1bcf9b6
+   GNU General Public License for more details.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+   You should have received a copy of the GNU General Public License
Jan Kratochvil 1bcf9b6
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+#include <pthread.h>
Jan Kratochvil 1bcf9b6
+#include <assert.h>
Jan Kratochvil 1bcf9b6
+#include <signal.h>
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+#include <asm/unistd.h>
Jan Kratochvil 1bcf9b6
+#include <unistd.h>
Jan Kratochvil 1bcf9b6
+#define tgkill(tgid, tid, sig) syscall (__NR_tgkill, (tgid), (tid), (sig))
Jan Kratochvil 1bcf9b6
+#define gettid() syscall (__NR_gettid)
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static volatile int var;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static void
Jan Kratochvil 1bcf9b6
+handler (int signo)	/* step-0 */
Jan Kratochvil 1bcf9b6
+{			/* step-0 */
Jan Kratochvil 1bcf9b6
+  var++;		/* step-1 */
Jan Kratochvil 1bcf9b6
+  tgkill (getpid (), gettid (), SIGUSR1);	/* step-2 */
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+static void *
Jan Kratochvil 1bcf9b6
+start (void *arg)
Jan Kratochvil 1bcf9b6
+{
Jan Kratochvil 1bcf9b6
+  signal (SIGUSR1, handler);
Jan Kratochvil 1bcf9b6
+  tgkill (getpid (), gettid (), SIGUSR1);
Jan Kratochvil 1bcf9b6
+  assert (0);
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  return NULL;
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+int
Jan Kratochvil 1bcf9b6
+main (void)
Jan Kratochvil 1bcf9b6
+{
Jan Kratochvil 1bcf9b6
+  pthread_t thread;
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+  pthread_create (&thread, NULL, start, NULL);
Jan Kratochvil 1bcf9b6
+  start (NULL);	/* main-start */
Jan Kratochvil 1bcf9b6
+  return 0;
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil b0e03f5
Index: gdb-7.2.50.20110117/gdb/testsuite/gdb.threads/sigstep-threads.exp
Jan Kratochvil 1bcf9b6
===================================================================
Jan Kratochvil 1bcf9b6
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
Jan Kratochvil b0e03f5
+++ gdb-7.2.50.20110117/gdb/testsuite/gdb.threads/sigstep-threads.exp	2011-01-17 16:02:40.000000000 +0100
Jan Kratochvil 1bcf9b6
@@ -0,0 +1,74 @@
Jan Kratochvil 1bcf9b6
+# Copyright 2010 Free Software Foundation, Inc.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+# This program is free software; you can redistribute it and/or modify
Jan Kratochvil 1bcf9b6
+# it under the terms of the GNU General Public License as published by
Jan Kratochvil 1bcf9b6
+# the Free Software Foundation; either version 3 of the License, or
Jan Kratochvil 1bcf9b6
+# (at your option) any later version.
Jan Kratochvil 1bcf9b6
+#
Jan Kratochvil 1bcf9b6
+# This program is distributed in the hope that it will be useful,
Jan Kratochvil 1bcf9b6
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
Jan Kratochvil 1bcf9b6
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Jan Kratochvil 1bcf9b6
+# GNU General Public License for more details.
Jan Kratochvil 1bcf9b6
+#
Jan Kratochvil 1bcf9b6
+# You should have received a copy of the GNU General Public License
Jan Kratochvil 1bcf9b6
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+set testfile sigstep-threads
Jan Kratochvil 1bcf9b6
+set srcfile ${testfile}.c
Jan Kratochvil 1bcf9b6
+set executable ${testfile}
Jan Kratochvil 1bcf9b6
+set binfile ${objdir}/${subdir}/${executable}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
Jan Kratochvil 1bcf9b6
+    untested ${testfile}.exp
Jan Kratochvil 1bcf9b6
+    return -1
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+clean_restart $executable
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+if ![runto_main] {
Jan Kratochvil 1bcf9b6
+    return -1;
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+# `noprint' would not test the full logic of GDB.
Jan Kratochvil 1bcf9b6
+gdb_test "handle SIGUSR1 nostop print pass" "\r\nSIGUSR1\[ \t\]+No\[ \t\]+Yes\[ \t\]+Yes\[ \t\].*"
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+gdb_test_no_output "set scheduler-locking off"
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+gdb_breakpoint [gdb_get_line_number "step-1"]
Jan Kratochvil 1bcf9b6
+gdb_test_no_output {set $step1=$bpnum}
Jan Kratochvil 1bcf9b6
+gdb_continue_to_breakpoint "step-1" ".* step-1 .*"
Jan Kratochvil 1bcf9b6
+gdb_test_no_output {disable $step1}
Jan Kratochvil 1bcf9b6
+
Jan Kratochvil 1bcf9b6
+# 1 as we are now stopped at the `step-1' label.
Jan Kratochvil 1bcf9b6
+set step_at 1
Jan Kratochvil 1bcf9b6
+for {set i 0} {$i < 100} {incr i} {
Jan Kratochvil 1bcf9b6
+    set test "step $i"
Jan Kratochvil 1bcf9b6
+    # Presume this step failed - as in the case of a timeout.
Jan Kratochvil 1bcf9b6
+    set failed 1
Jan Kratochvil 1bcf9b6
+    gdb_test_multiple "step" $test {
Jan Kratochvil 1bcf9b6
+	-re "\r\nProgram received signal SIGUSR1, User defined signal 1.\r\n" {
Jan Kratochvil 1bcf9b6
+	    exp_continue -continue_timer
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+	-re "step-(\[012\]).*\r\n$gdb_prompt $" {
Jan Kratochvil 1bcf9b6
+	    set now $expect_out(1,string)
Jan Kratochvil 1bcf9b6
+	    if {$step_at == 2 && $now == 1} {
Jan Kratochvil 1bcf9b6
+		set failed 0
Jan Kratochvil 1bcf9b6
+	    } elseif {$step_at == 1 && $now == 2} {
Jan Kratochvil 1bcf9b6
+		set failed 0
Jan Kratochvil 1bcf9b6
+		# Continue over the re-signalling back to the handle entry.
Jan Kratochvil 1bcf9b6
+		gdb_test_no_output {enable $step1} ""
Jan Kratochvil 1bcf9b6
+		gdb_test "continue" " step-1 .*" ""
Jan Kratochvil 1bcf9b6
+		set now 1
Jan Kratochvil 1bcf9b6
+		gdb_test_no_output {disable $step1} ""
Jan Kratochvil 1bcf9b6
+	    } else  {
Jan Kratochvil 1bcf9b6
+		fail $test
Jan Kratochvil 1bcf9b6
+	    }
Jan Kratochvil 1bcf9b6
+	    set step_at $now
Jan Kratochvil 1bcf9b6
+	}
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+    if $failed {
Jan Kratochvil 1bcf9b6
+	return
Jan Kratochvil 1bcf9b6
+    }
Jan Kratochvil 1bcf9b6
+}
Jan Kratochvil 1bcf9b6
+# We can never reliably say the racy problematic case has been tested.
Jan Kratochvil 1bcf9b6
+pass "step"