Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <palves@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 1/8]  gdb.threads/{siginfo-thread.c,watchthreads-reorder.c,ia64-sigill.c} races with GDB
Date: Fri, 26 Dec 2014 20:31:00 -0000	[thread overview]
Message-ID: <1419625871-28848-2-git-send-email-palves@redhat.com> (raw)
In-Reply-To: <1419625871-28848-1-git-send-email-palves@redhat.com>

These three test all spawn a few threads and then send a SIGSTOP to
their parent GDB in order to pause it while the new threads set things
up for the test.  With a GDB patch that changes the inferior thread's
scheduling a bit, I sometimes see:

  FAIL: gdb.threads/siginfo-threads.exp: catch signal 0 (timeout)
  ...
  FAIL: gdb.threads/watchthreads-reorder.exp: reorder1: continue a (timeout)
  ...
  FAIL: gdb.threads/ia64-sigill.exp: continue (timeout)
  ...

The issue is that the test program stops GDB before it had a chance of
processing the new thread's clone event:

  (gdb) PASS: gdb.threads/siginfo-threads.exp: get pid
  continue
  Continuing.
  Stopping GDB PID 21541.
  Waiting till the threads initialize their TIDs.
  FAIL: gdb.threads/siginfo-threads.exp: catch signal 0 (timeout)

On Linux (at least), new threads start stopped, and the debugger must
resume them.  The fix is to make the test program wait for the new
threads to be running before stopping GDB.

gdb/testsuite/
2014-12-26  Pedro Alves  <palves@redhat.com>

	* gdb.threads/ia64-sigill.c (threads_started_barrier): New global.
	(thread_func): Wait on barrier.
	(main): Wait for all threads to start before stopping GDB.
	* gdb.threads/siginfo-threads.c (threads_started_barrier): New
	global.
	(thread1_func, thread2_func): Wait on barrier.
	(main): Wait for all threads to start before stopping GDB.
	* gdb.threads/watchthreads-reorder.c (threads_started_barrier):
	New global.
	(thread1_func, thread2_func): Wait on barrier.
	(main): Wait for all threads to start before stopping GDB.
---
 gdb/testsuite/gdb.threads/ia64-sigill.c          | 11 +++++++++++
 gdb/testsuite/gdb.threads/siginfo-threads.c      | 13 +++++++++++++
 gdb/testsuite/gdb.threads/watchthreads-reorder.c | 13 +++++++++++++
 3 files changed, 37 insertions(+)

diff --git a/gdb/testsuite/gdb.threads/ia64-sigill.c b/gdb/testsuite/gdb.threads/ia64-sigill.c
index 4833e47..a685fb0 100644
--- a/gdb/testsuite/gdb.threads/ia64-sigill.c
+++ b/gdb/testsuite/gdb.threads/ia64-sigill.c
@@ -44,6 +44,8 @@ static pthread_mutex_t thread2_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_
 
 static pthread_mutex_t terminate_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
 
+static pthread_barrier_t threads_started_barrier;
+
 /* Do not use alarm as it would create a ptrace event which would hang up us if
    we are being traced by GDB which we stopped ourselves.  */
 
@@ -78,6 +80,8 @@ thread_func (void *threadno_voidp)
   int threadno = (intptr_t) threadno_voidp;
   int i;
 
+  pthread_barrier_wait (&threads_started_barrier);
+
   switch (threadno)
   {
     case 1:
@@ -272,6 +276,8 @@ main (int argc, char **argv)
 
   timed_mutex_lock (&terminate_mutex);
 
+  pthread_barrier_init (&threads_started_barrier, NULL, 3);
+
   i = pthread_create (&thread1, NULL, thread_func, (void *) (intptr_t) 1);
   assert (i == 0);
 
@@ -298,6 +304,11 @@ main (int argc, char **argv)
 
   atexit (cleanup);
 
+  /* Wait until all threads are seen running.  On Linux (at least),
+     new threads start stopped, and the debugger must resume them.
+     Need to wait for that before stopping GDB.  */
+  pthread_barrier_wait (&threads_started_barrier);
+
   printf ("Stopping GDB PID %lu.\n", (unsigned long) tracer);
 
   if (tracer)
diff --git a/gdb/testsuite/gdb.threads/siginfo-threads.c b/gdb/testsuite/gdb.threads/siginfo-threads.c
index 7aa1ea2..b86df54 100644
--- a/gdb/testsuite/gdb.threads/siginfo-threads.c
+++ b/gdb/testsuite/gdb.threads/siginfo-threads.c
@@ -54,6 +54,8 @@ static int thread2_sigusr2_hit;
 static pthread_mutex_t terminate_mutex
   = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
 
+static pthread_barrier_t threads_started_barrier;
+
 /* Do not use alarm as it would create a ptrace event which would hang
    us up if we are being traced by GDB, which we stopped
    ourselves.  */
@@ -128,6 +130,8 @@ thread1_func (void *unused)
 {
   int i;
 
+  pthread_barrier_wait (&threads_started_barrier);
+
   timed_mutex_lock (&thread1_tid_mutex);
 
   /* THREAD1_TID_MUTEX must be already locked to avoid a race.  */
@@ -163,6 +167,8 @@ thread2_func (void *unused)
 {
   int i;
 
+  pthread_barrier_wait (&threads_started_barrier);
+
   timed_mutex_lock (&thread2_tid_mutex);
 
   /* THREAD2_TID_MUTEX must be already locked to avoid a race.  */
@@ -354,6 +360,8 @@ main (int argc, char **argv)
   assert_perror (errno);
   assert (i == 0);
 
+  pthread_barrier_init (&threads_started_barrier, NULL, 3);
+
   i = pthread_create (&thread1, NULL, thread1_func, NULL);
   assert (i == 0);
 
@@ -380,6 +388,11 @@ main (int argc, char **argv)
 
   atexit (cleanup);
 
+  /* Wait until all threads are seen running.  On Linux (at least),
+     new threads start stopped, and the debugger must resume them.
+     Need to wait for that before stopping GDB.  */
+  pthread_barrier_wait (&threads_started_barrier);
+
   printf ("Stopping GDB PID %lu.\n", (unsigned long) tracer);
 
   if (tracer)
diff --git a/gdb/testsuite/gdb.threads/watchthreads-reorder.c b/gdb/testsuite/gdb.threads/watchthreads-reorder.c
index 315104a..05b200c 100644
--- a/gdb/testsuite/gdb.threads/watchthreads-reorder.c
+++ b/gdb/testsuite/gdb.threads/watchthreads-reorder.c
@@ -44,6 +44,8 @@ static pthread_mutex_t thread2_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_
 
 static pthread_mutex_t terminate_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
 
+static pthread_barrier_t threads_started_barrier;
+
 /* These variables must have lower in-memory addresses than thread1_rwatch and
    thread2_rwatch so that they take their watchpoint slots.  */
 
@@ -87,6 +89,8 @@ thread1_func (void *unused)
   int i;
   volatile int rwatch_store;
 
+  pthread_barrier_wait (&threads_started_barrier);
+
   timed_mutex_lock (&thread1_tid_mutex);
 
   /* THREAD1_TID_MUTEX must be already locked to avoid race.  */
@@ -113,6 +117,8 @@ thread2_func (void *unused)
   int i;
   volatile int rwatch_store;
 
+  pthread_barrier_wait (&threads_started_barrier);
+
   timed_mutex_lock (&thread2_tid_mutex);
 
   /* THREAD2_TID_MUTEX must be already locked to avoid race.  */
@@ -279,6 +285,8 @@ main (int argc, char **argv)
 
   timed_mutex_lock (&terminate_mutex);
 
+  pthread_barrier_init (&threads_started_barrier, NULL, 3);
+
   i = pthread_create (&thread1, NULL, thread1_func, NULL);
   assert (i == 0);
 
@@ -305,6 +313,11 @@ main (int argc, char **argv)
 
   atexit (cleanup);
 
+  /* Wait until all threads are seen running.  On Linux (at least),
+     new threads start stopped, and the debugger must resume them.
+     Need to wait for that before stopping GDB.  */
+  pthread_barrier_wait (&threads_started_barrier);
+
   printf ("Stopping GDB PID %lu.\n", (unsigned long) tracer);
 
   if (tracer)
-- 
1.9.3


  parent reply	other threads:[~2014-12-26 20:31 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-26 20:31 [PATCH 0/8] Linux: starvation avoidance in non-stop mode Pedro Alves
2014-12-26 20:31 ` [PATCH 2/8] watch_thread_num.exp and targets with fairer event reporting Pedro Alves
2014-12-26 20:31 ` Pedro Alves [this message]
2015-01-06  6:20   ` [PATCH 1/8] gdb.threads/{siginfo-thread.c,watchthreads-reorder.c,ia64-sigill.c} races with GDB Yao Qi
2014-12-26 20:31 ` [PATCH 3/8] cleanup and speed up (software_)breakpoint_inserted_here_p Pedro Alves
2014-12-26 20:32 ` [PATCH 4/8] linux-nat.c: clean up pending status checking and resuming LWPs Pedro Alves
2015-01-06  8:12   ` Yao Qi
2015-01-07 13:22     ` Pedro Alves
2015-01-07 14:10       ` Yao Qi
2014-12-26 20:32 ` [PATCH 7/8] [gdbserver] linux-low.c: better starvation avoidance, handle non-stop mode too Pedro Alves
2014-12-26 20:32 ` [PATCH 6/8] linux-nat.c: " Pedro Alves
2015-01-07  7:06   ` Yao Qi
2015-01-07 13:22     ` Pedro Alves
2015-01-07 14:08       ` Yao Qi
2015-01-07 14:36         ` Pedro Alves
2014-12-26 20:32 ` [PATCH 5/8] linux-nat.c: always mark execing LWP as resumed Pedro Alves
2014-12-26 20:32 ` [PATCH 8/8] add non-stop test that stresses thread starvation issues Pedro Alves
2015-04-02 14:53   ` Yao Qi
2015-04-06 11:26     ` Pedro Alves
2015-04-07 10:10       ` Yao Qi
2015-04-07 10:22         ` Pedro Alves
2015-04-07 10:31           ` Yao Qi
2015-01-09 15:07 ` [PATCH 0/8] Linux: starvation avoidance in non-stop mode Pedro Alves

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=1419625871-28848-2-git-send-email-palves@redhat.com \
    --to=palves@redhat.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