This is the mail archive of the gdb-cvs@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]

[binutils-gdb/users/hjl/linux/master] gdb.threads/{siginfo-thread.c, watchthreads-reorder.c, ia64-sigill.c} races with GDB


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9665ffdd591e9b374b4e5f6aeffe15541346140d

commit 9665ffdd591e9b374b4e5f6aeffe15541346140d
Author: Pedro Alves <palves@redhat.com>
Date:   Mon Dec 29 19:41:04 2014 +0000

    gdb.threads/{siginfo-thread.c,watchthreads-reorder.c,ia64-sigill.c} races with GDB
    
    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/
    2015-01-09  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.

Diff:
---
 gdb/testsuite/ChangeLog                          | 14 ++++++++++++++
 gdb/testsuite/gdb.threads/ia64-sigill.c          | 11 +++++++++++
 gdb/testsuite/gdb.threads/siginfo-threads.c      | 13 +++++++++++++
 gdb/testsuite/gdb.threads/watchthreads-reorder.c | 13 +++++++++++++
 4 files changed, 51 insertions(+)

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 77758f1..cd38459 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,19 @@
 2015-01-09  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.
+
+2015-01-09  Pedro Alves  <palves@redhat.com>
+
 	* gdb.threads/attach-many-short-lived-threads.c: New file.
 	* gdb.threads/attach-many-short-lived-threads.exp: New file.
 
diff --git a/gdb/testsuite/gdb.threads/ia64-sigill.c b/gdb/testsuite/gdb.threads/ia64-sigill.c
index 6af0138..11782fa 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 95c3927..a8e5446 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 353b4a1..b28a0de 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)


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