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]

[commit] New threads creation test


Working on the no-libthread_db patch I just posted was so confusing
that I lost track of my original goal!  Whoops.

NPTL allows multiple threads to create threads simultaneously, or as
simultaneously as the kernel's locking and scheduling will permit.
As a result it was possible for two threads to call
__nptl_create_event simultaneously.  Here's a test case which
demonstrated that.

In GDB this isn't a problem because we stop all threads when we
hit the breakpoint.  Gdbserver cleverly tries to escape the
breakpoint without stopping other threads.  But if multiple
threads can hit it simultaneously, we'll get behind and
show unexpected SIGTRAPs to the user.  My earlier patch
lets us avoid setting the breakpoint in the first place.

I previously reported this as a glibc bug:

  http://sourceware.org/bugzilla/show_bug.cgi?id=2697

The GDB solution turned out much more satisfactorily, though.

Tested on x86_64-linux native and remote; checked in.

-- 
Daniel Jacobowitz
CodeSourcery

2007-10-23  Daniel Jacobowitz  <dan@codesourcery.com>

	* gdb.threads/multi-create.c, gdb.threads/multi-create.exp: New.

Index: testsuite/gdb.threads/multi-create.c
===================================================================
RCS file: testsuite/gdb.threads/multi-create.c
diff -N testsuite/gdb.threads/multi-create.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.threads/multi-create.c	23 Oct 2007 20:17:21 -0000
@@ -0,0 +1,91 @@
+/* Create threads from multiple threads in parallel.
+   Copyright 2007 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <limits.h>
+
+#define NUM_CREATE 1
+#define NUM_THREAD 8
+
+void *
+thread_function (void *arg)
+{
+  int x = * (int *) arg;
+
+  printf ("Thread <%d> executing\n", x);
+
+  return NULL;
+}
+
+void *
+create_function (void *arg)
+{
+  pthread_attr_t attr;
+  pthread_t threads[NUM_THREAD];
+  int args[NUM_THREAD];
+  int i = * (int *) arg;
+  int j;
+
+  pthread_attr_init (&attr); /* set breakpoint 1 here.  */
+  pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+  /* Create a ton of quick-executing threads, then wait for them to
+     complete.  */
+  for (j = 0; j < NUM_THREAD; ++j)
+    {
+      args[j] = i * 1000 + j;
+      pthread_create (&threads[j], &attr, thread_function, &args[j]);
+    }
+
+  for (j = 0; j < NUM_THREAD; ++j)
+    pthread_join (threads[j], NULL);
+
+  pthread_attr_destroy (&attr);
+
+  return NULL;
+}
+
+int 
+main (int argc, char **argv)
+{
+  pthread_attr_t attr;
+  pthread_t threads[NUM_CREATE];
+  int args[NUM_CREATE];
+  int n, i;
+
+  pthread_attr_init (&attr);
+  pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+  for (n = 0; n < 100; ++n)
+    {
+      for (i = 0; i < NUM_CREATE; i++)
+	{
+	  args[i] = i;
+	  pthread_create (&threads[i], &attr, create_function, &args[i]);
+	}
+
+      create_function (&i);
+      for (i = 0; i < NUM_CREATE; i++)
+	pthread_join (threads[i], NULL);
+    }
+
+  pthread_attr_destroy (&attr);
+
+  return 0;
+}
Index: testsuite/gdb.threads/multi-create.exp
===================================================================
RCS file: testsuite/gdb.threads/multi-create.exp
diff -N testsuite/gdb.threads/multi-create.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.threads/multi-create.exp	23 Oct 2007 20:17:21 -0000
@@ -0,0 +1,40 @@
+# multi-create.exp -- Test creating many threads in parallel
+# Copyright (C) 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+set testfile "multi-create"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+	 executable {debug}] != "" } {
+    return -1
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+runto_main
+
+# Run to the beginning of create_function several times.  Make sure
+# we always stop there, and not somewhere else in the guts of the
+# thread library.
+
+set bp_location1 [gdb_get_line_number "set breakpoint 1 here"]
+gdb_breakpoint $srcfile:$bp_location1
+for {set i 0} {$i < 32} {incr i} {
+    gdb_test "continue" ".*Breakpoint $decimal,.*$srcfile:$bp_location1.*" \
+	"continue to breakpoint $i"
+}


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