* gdb.threads/pthread_cond_wait.c: New file.
authorJoel Brobecker <brobecker@gnat.com>
Wed, 19 May 2004 21:41:03 +0000 (21:41 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Wed, 19 May 2004 21:41:03 +0000 (21:41 +0000)
        * gdb.threads/pthread_cond_wait.exp: New testcase.

gdb/testsuite/ChangeLog
gdb/testsuite/gdb.threads/pthread_cond_wait.c [new file with mode: 0644]
gdb/testsuite/gdb.threads/pthread_cond_wait.exp [new file with mode: 0644]

index 683fa4e48b612f4f83fcbbbc309532007518b155..9d528417a844c2030f52bfe9f3dbbb69f94cc7c8 100644 (file)
@@ -1,3 +1,9 @@
+2004-05-19  J. Brobecker  <brobecker@gnat.com>
+            Michael Snyder  <msnyder@redhat.com>
+
+       * gdb.threads/pthread_cond_wait.c: New file.
+       * gdb.threads/pthread_cond_wait.exp: New testcase.
+
 2004-05-13  Andrew Cagney  <cagney@redhat.com>
 
        * gdb.base/signull.exp, gdb.base/signull.c: New files.
diff --git a/gdb/testsuite/gdb.threads/pthread_cond_wait.c b/gdb/testsuite/gdb.threads/pthread_cond_wait.c
new file mode 100644 (file)
index 0000000..ae87f8c
--- /dev/null
@@ -0,0 +1,76 @@
+/* A small multi-threaded test case.
+
+   Copyright 2004
+   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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <time.h>
+
+void
+cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut)
+{
+  pthread_mutex_lock(mut);
+  pthread_cond_wait (cond, mut);
+  pthread_mutex_unlock (mut);
+}
+
+void
+noreturn (void)
+{
+  pthread_mutex_t mut;
+  pthread_cond_t cond;
+
+  pthread_mutex_init (&mut, NULL);
+  pthread_cond_init (&cond, NULL);
+
+  /* Wait for a condition that will never be signaled, so we effectively
+     block the thread here.  */
+  cond_wait (&cond, &mut);
+}
+
+void *
+forever_pthread (void *unused)
+{
+  noreturn ();
+}
+
+void
+break_me (void)
+{
+  /* Just an anchor to help putting a breakpoint.  */
+}
+
+int
+main (void)
+{
+  pthread_t forever;
+  const struct timespec ts = { 0, 10000000 }; /* 0.01 sec */
+
+  pthread_create (&forever, NULL, forever_pthread, NULL);
+  for (;;)
+    {
+      nanosleep (&ts, NULL);
+      break_me();
+    }
+
+  return 0;
+}
+
diff --git a/gdb/testsuite/gdb.threads/pthread_cond_wait.exp b/gdb/testsuite/gdb.threads/pthread_cond_wait.exp
new file mode 100644 (file)
index 0000000..72ae03a
--- /dev/null
@@ -0,0 +1,73 @@
+# Copyright (C) 2004 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This file verifies that GDB is able to compute a backtrace for a thread
+# being blocked on a call to pthread_cond_wait(). 
+
+if $tracelevel then {
+       strace $tracelevel
+}
+
+set testfile "pthread_cond_wait"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "break break_me" \
+    "Breakpoint 1 at .*: file .*${srcfile}, line .*" \
+         "breakpoint on break_me"
+
+gdb_test "run" \
+         ".*Breakpoint 1, break_me ().*" \
+         "run to break_me"
+
+# 
+# Backtrace all threads, find the one running noreturn, and
+# verify that we are able to get a sensible backtrace, including
+# the frame for the pthread_cond_wait() call.
+#
+# The string below will only match if the functions named
+# occur in a single thread's backtrace, in the given order.
+#
+
+global hex
+global decimal
+
+#
+# This is a "backtrace break" ("btb"):
+#
+set btb "\[^\r\n\]+\[\r\n\]+\#${decimal}\[ \t\]+${hex} in "
+
+# One of the threads is blocked on a call to pthread_cond_wait, and
+# we want to verify that we are able to get a sensible backtrace for
+# that thread.  Because we don't know its thread ID, we can't switch
+# to it before doing the backtrace. So we get a backtrace for all
+# threads, and verify that one them returns the expected backtrace.
+gdb_test "thread apply all backtrace" \
+    "pthread_cond_wait${btb}cond_wait${btb}noreturn${btb}forever_pthread.*" \
+    "backtrace in blocked thread"
+