gdb.threads testsuite patch

Jimmy Guo guo@cup.hp.com
Thu Jul 22 18:52:00 GMT 1999


This patch contains merged gdb.threads testsuite, and it concludes the
HP <-> Cygnus gdb testsuite merge patches for now :)

File renames / moves (a tar file of gdb.threads has been ftp'd over as
ftp.cygnus.com:/incoming/hp_gdb.threads.tar):

Old                                            New
---                                            ---
gdb.hp/attach2.exp                             attach2.exp
                                               compiler.c
gdb.hp/more-steps.c                            more-steps.c
gdb.hp/more-steps.exp                          more-steps.exp
gdb.hp/quicksort.c                             quicksort.c
gdb.hp/quicksort.exp                           quicksort.exp
gdb.hp/start-stop.c                            start-stop.c
gdb.hp/start-stop.exp                          start-stop.exp
gdb.hp/thr-lib.c                               thr-lib.c
gdb.hp/thr-lib.exp                             thr-lib.exp
gdb.hp/thr-lib.h                               thr-lib.h
gdb.hp/thr-liblib.c                            thr-liblib.c
gdb.hp/thr-stg.exp                             thr-stg.exp

- Jimmy Guo, guo@cup.hp.com

/opt/gnu/bin/diff -r -c -N  ../gdb-19990719/gdb/testsuite/gdb.threads gdb/testsuite/gdb.threads
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/Makefile.in gdb/testsuite/gdb.threads/Makefile.in
*** ../gdb-19990719/gdb/testsuite/gdb.threads/Makefile.in	Fri Oct 11 17:10:37 1996
--- gdb/testsuite/gdb.threads/Makefile.in	Thu Jul 22 17:50:35 1999
***************
*** 1,7 ****
  VPATH = @srcdir@
  srcdir = @srcdir@
  
! EXECUTABLES = pthreads
  
  all:
  	@echo "Nothing to be done for all..."
--- 1,9 ----
  VPATH = @srcdir@
  srcdir = @srcdir@
  
! EXECUTABLES = more-steps pthreads quicksort step start-stop thr-lib
! 
! MISCELLANEOUS = thr-liblib.sl
  
  all:
  	@echo "Nothing to be done for all..."
***************
*** 15,21 ****
  check:
  
  clean mostlyclean:
! 	-rm -f *~ *.o a.out xgdb *.x *.ci *.tmp core* $(EXECUTABLES)
  
  distclean maintainer-clean realclean: clean
  	-rm -f Makefile config.status config.log config.h
--- 17,25 ----
  check:
  
  clean mostlyclean:
! 	-rm -f *~ *.o *.ci
! 	-rm -f core $(EXECUTABLES)
! 	-rm -f $(MISCELLANEOUS)
  
  distclean maintainer-clean realclean: clean
  	-rm -f Makefile config.status config.log config.h
***************
*** 24,29 ****
--- 28,34 ----
  	$(SHELL) ./config.status --recheck
  
  config.h: stamp-h ; @true
+ 
  stamp-h: config.in config.status
  	CONFIG_HEADERS=config.h:config.in $(SHELL) config.status
  
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/attach2.exp gdb/testsuite/gdb.threads/attach2.exp
*** ../gdb-19990719/gdb/testsuite/gdb.threads/attach2.exp	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/attach2.exp	Thu Jul 22 17:50:37 1999
***************
*** 0 ****
--- 1,263 ----
+ # attach.exp -- Expect script to test attaching to a threaded pgm
+ # Copyright (C) 1992 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@prep.ai.mit.edu
+ 
+ if $tracelevel then {
+     strace $tracelevel
+ }
+ 
+ if { ![istarget "hppa*-*-hpux11.*"] } {
+     verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
+     return 0
+ }
+ 
+ set testfile quicksort
+ set srcfile ${srcdir}/${subdir}/${testfile}.c
+ set binfile ${objdir}/${subdir}/${testfile}
+ 
+ if [get_compiler_info ${binfile}] {
+     return -1
+ }
+ 
+ set oldtimeout $timeout
+ set oldverbose $verbose
+ 
+ # To build the executable we need to link against the thread library.
+ #
+ if { $hp_cc_compiler } {
+     set additional_flags "additional_flags=-Ae"
+ } else {
+     set additional_flags ""
+ }
+ 
+ if { [gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}" executable [list debug $additional_flags ldflags=-lpthread]] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ 
+ # Because we can't attach over nfs, copy binfile to /tmp/${binfile}.${pid}
+ # and replace binfile with a symbolic link
+ 
+ set pid [pid]
+ exec /bin/cp -f ${binfile} /tmp/attach2.${pid}
+ exec rm -f ${binfile}
+ exec ln -s /tmp/attach2.${pid} ${binfile}
+ 
+ # Thread stuff is _slow_; prepare for long waits.
+ #
+ # Further, this test has some "null" lines designed
+ # to consume output from gdb that was too late to be
+ # matched (sequence is "gdb_test" sends; timeout and
+ # on to next send; result finally comes in; mismatch).
+ #
+ # The null command is 'gdb_test "p \$pc" ".*" ""'
+ # NOTE: this command undoes any up/down stuff!
+ #
+ proc pre_timeout { how_long } {
+     global timeout
+ 
+     set timeout [expr "$timeout + $how_long"]
+ }
+ 
+ proc post_timeout {} {
+     global timeout
+     global oldtimeout
+ 
+     set timeout $oldtimeout
+     gdb_test "p \$pc" ".*" ""
+ }
+ 
+ # We used to wait 5 seconds , but tiamat is faster than
+ # hydra...or is it that the OS allocates time differently(?).
+ #
+ set delay 5
+ if { ![istarget "hppa*-*-hpux11.*"] } {
+     set delay 45
+ }
+ 
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ 
+ # Start the application running and get its pid.
+ # Then we wait for it to get started and attach.
+ # 
+ set testpid [eval exec $binfile 1 &]
+ exec sleep $delay
+ 
+ # Now attach to the file.
+ #
+ pre_timeout 100
+ gdb_test "file $binfile" ".*" "Force switch to gdb64 if necessary."
+ gdb_test "attach $testpid" ".*Attaching to.*process.*Reading symbols from.*done.*" "attach to target"
+ post_timeout
+ 
+ # Wait for things to quiesce.
+ #
+ exec sleep 0
+ 
+ send_gdb "bt\n" 
+ 
+ set do_return 0
+ set do_go_to_118 0
+ pre_timeout 400
+ gdb_expect {
+     -re ".*sleep.*work_init.*main.*$gdb_prompt $"   { 
+         pass "at expected location" 
+     }
+     -re ".*drand48.*$gdb_prompt $" {
+         set do_go_to_118 1
+     }
+     -re ".*pthread_mutex_lock.*$gdb_prompt $" {
+         set do_go_to_118 1
+     }
+     -re ".*pthread_mutex_unlock.*$gdb_prompt $" {
+         set do_go_to_118 1
+     }
+     -re ".*main.*$gdb_prompt $" {
+         set do_go_to_118 1
+     }
+     -re ".*No stack.*$gdb_prompt $" {
+         fail "Failed attach, change wait amount down, rest would fail"
+         set do_return 1
+     }
+     -re ".*$gdb_prompt $" {
+         # Who knows?
+         #
+         set do_go_to_118 1
+     }
+     timeout { 
+         set do_return 1
+         fail "timeout on bt, avoiding rest of test" 
+     }
+ }
+ post_timeout
+ 
+ # Too late; just give up.
+ #
+ if { $do_return } {
+     set timeout $oldtimeout
+     set verbose $oldverbose
+     return 0
+ }
+ 
+ # Maybe too early--set a temp break and continue.
+ # We have to set this on both paths, so that we can
+ # know what numbers breakpoints will be.
+ #
+ gdb_test "tb 118" ".*Breakpoint 1.*118.*"
+ if { $do_go_to_118 } {
+     pre_timeout 100
+     send_gdb "c\n"
+     gdb_expect {
+         -re ".*at.*118.*118.*$gdb_prompt $" {
+             # Ok, just keep going
+         }
+         -re ".*Program exited.*$gdb_prompt $" {
+             fail "Attached too late, set wait amount downwards"
+             set timeout $oldtimeout
+             set verbose $oldverbose
+             return 0
+         }
+         -re ".*$gdb_prompt $" {
+             fail "Unexpected result on attach" 
+             set timeout $oldtimeout
+             set verbose $oldverbose
+             return 0
+         }
+         timeout { 
+             fail "timeout on continue " 
+         }
+     }
+     post_timeout
+ }
+ gdb_test "delete 1" ".*" "delete bp 1 if it is still there."
+ 
+ # Look at the threads.
+ #
+ pre_timeout 100
+ gdb_test "info thread" ".*7.*6.*5.*4.*3.*2.*\\\* 1.*thread.*" "first info thread"
+ post_timeout
+ 
+ # We expect to be inside the "sleep" call, so check that.
+ #
+ if { [expr "!$do_go_to_118"] } {
+     gdb_test "up" ".*\#1.*(nanosleep|_sigtimedwait|sigtimedwait).*" "up 1" 
+     gdb_test "up" ".*\#2.*sleep.*"     "up 2" 
+     pre_timeout 100
+     gdb_test "up" ".*\#3.*work_init.*$testfile.*c:11\[48\].*sleep.*" "up 3" 
+     post_timeout
+ } else {
+     send_user "Skipped three tests\n"
+ }
+ 
+ # Get out of that call.
+ #
+ gdb_test "b 120" ".*Breakpoint 2.*120.*" "set bp"
+ pre_timeout 100
+ gdb_test "c"     ".*Breakpoint 2.*at.*120.*" "hit bp"
+ post_timeout
+ 
+ # Look at the threads.
+ #
+ pre_timeout 100
+ gdb_test "info thread" ".*7.*6.*5.*4.*3.*2.*1.*thread.*$testfile.*c*120.*" "2nd info thread"
+ post_timeout
+ 
+ # Do some more stuff, to make sure we can
+ #
+ gdb_test "thread 3" ".*Switching to.*thread.*ksleep.*" "switch thread"
+ 
+ if [istarget "hppa2.0w-*-*"] {
+   gdb_test "up" ".*in .stub.*from.*libpthread.*"   "up 5"
+ } else {
+   gdb_test "up" ".*_lwp_cond_timedwait.*"   "up 5"
+ }
+ gdb_test "up" ".*pthread_cond_wait.*"     "up 6"
+ gdb_test "up" ".*\#3.*worker.*144.*"      "up 7"
+ gdb_test "up" ".*(__pthread_exit|__pthread_create_system).*" "up 8"
+ gdb_test "up" ".*Initial.*cannot go up.*" "found thread base"
+ 
+ gdb_test "b 145 thr 3" ".*Breakpoint 3.*145.*"             "thread-specific bp"
+ gdb_test "i b"         ".*2.*breakpoint.*at.*120.*3.*breakpoint.*at.*145 thread 3.*" "show thread-specific bp"
+ gdb_test "del 2" ".*"
+ 
+ gdb_test "c" ".*Breakpoint 3.*145.*" "hit thread-specific bp"
+ gdb_test "i th" ".*\\\* 3.*145.*" "at correct thread"
+ 
+ pre_timeout 100
+ gdb_test "n" ".*146.*" "next from thread-specific bp"
+ post_timeout
+ 
+ gdb_test "d 3" ".*"
+ gdb_test "c"   ".*Program exited normally\..*" "run to finish"
+ 
+ # Done!
+ #
+ gdb_exit
+ 
+ set timeout $oldtimeout
+ set verbose $oldverbose
+ 
+ # Cleanup the file placed in /tmp and the symlink
+ #
+ exec rm -f ${binfile} /tmp/attach2.${pid}
+ 
+ return 0
+ 
+ 
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/compiler.c gdb/testsuite/gdb.threads/compiler.c
*** ../gdb-19990719/gdb/testsuite/gdb.threads/compiler.c	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/compiler.c	Thu Jul 22 17:48:46 1999
***************
*** 0 ****
--- 1,31 ----
+ /* Often the behavior of any particular test depends upon what compiler was
+    used to compile the test.  As each test is compiled, this file is
+    preprocessed by the same compiler used to compile that specific test
+    (different tests might be compiled by different compilers, particularly
+    if compiled at different times), and used to generate a *.ci (compiler
+    info) file for that test.
+ 
+    I.E., when callfuncs is compiled, a callfuncs.ci file will be generated,
+    which can then be sourced by callfuncs.exp to give callfuncs.exp access
+    to information about the compilation environment.
+ 
+    TODO:  It might be a good idea to add expect code that tests each
+    definition made with 'set" to see if one already exists, and if so
+    warn about conflicts if it is being set to something else.  */
+ 
+ /* This needs to be kept in sync with whatis.c and gdb.exp(get_compiler_info).
+    If this ends up being hairy, we could use a common header file.  */
+ 
+ #if defined (__STDC__) || defined (_AIX)
+ set signed_keyword_not_used 0
+ #else
+ set signed_keyword_not_used 1
+ #endif
+ 
+ #if defined (__GNUC__)
+ set gcc_compiled __GNUC__
+ #else
+ set gcc_compiled 0
+ #endif
+ 
+ return 0
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/more-steps.c gdb/testsuite/gdb.threads/more-steps.c
*** ../gdb-19990719/gdb/testsuite/gdb.threads/more-steps.c	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/more-steps.c	Thu Jul 22 17:50:38 1999
***************
*** 0 ****
--- 1,140 ----
+ /* BeginSourceFile more_steps.c
+ 
+   This file creates a lot of threads which then execute
+   in parallel, so that wdb can be tested on handling
+   simultaneous thread events.
+ 
+   To compile:
+ 
+       cc -Ae +DA1.0 -g -o more_steps -lpthread more_steps.c
+ 
+   To run:
+   
+      more_threads
+ */
+ 
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <assert.h>
+ #include <pthread.h>
+ 
+ #define TRUE 1
+ #define FALSE 0
+ #define N_THREADS 3
+ #define PHASES 3
+ 
+ typedef enum {
+   ZERO,
+   ONE,
+   TWO,
+   THREE
+ } phase_t;
+ 
+ /* Uncomment to turn on debugging output */
+ /* #define DEBUG  */
+ 
+ /* Locks.
+  */
+ int lock_one; /* Main W, others R */
+ int lock_two; /* ditto */
+ int lock_end[ N_THREADS ]; /* Main R, others R[i] */
+ int phase[ N_THREADS ];
+ 
+ /* Routine for each thread to run.
+  */
+ void *spin( vp )
+     void * vp;
+ {
+     int me = (int) vp;
+     int i;
+ 
+     lock_end[ me ] = TRUE;
+ 
+     phase[ me ] = ONE;
+ 
+     while( lock_one );
+ 
+     phase[ me ] = TWO;
+ 
+     while( lock_two );
+ 
+     phase[ me ] = THREE;
+ 
+     lock_end[ me ] = FALSE;
+ }
+ 
+ void
+ do_pass()
+ {
+     int i;
+     pthread_t t[ N_THREADS ];
+     int err;
+     int done;
+ 
+     /* Start N_THREADS threads, then join them so
+      * that they are terminated.
+      */
+     for( i = 0; i < N_THREADS; i++ ) {
+         err = pthread_create( &t[i], NULL, spin, (void *)i );
+         if( err != 0 ) {
+             printf( "== Start/stop, error in thread %d create\n", i );
+         }
+     }
+ 
+     /* Do phase 1.
+      */
+     lock_one = FALSE;
+ 
+     /* Do phase 2.
+      */
+     lock_two = FALSE;
+     
+     /* Be done.
+      */
+     done = 0;
+     while( !done ) {
+ 
+        /* Be optimistic.
+         */
+        done = 1;
+        for( i = 0; i < N_THREADS; i++ ) {
+            if( lock_end[i] ) {
+                /* Thread "i" is not ready yet.
+                 */
+                done = 0;
+                break;
+            }
+        }
+     }
+     
+     /* Finish up
+      */
+     for( i = 0; i < N_THREADS; i++ ) {
+         err = pthread_join(t[i], NULL );    /* Line 105 */
+         if( err != 0 ) {                    /* Line 106 */
+             printf( "== Start/stop, error in thread %d join\n", i );
+         }
+     }
+ 
+     i = 10;  /* Line 109.  Null line for setting bpts on. */
+ }
+ 
+ main( argc, argv )
+ int    argc;
+ char **argv;
+ {
+     int i;
+     
+     /* Init
+      */
+     lock_one = TRUE;
+     lock_two = TRUE;
+     for( i = 0; i < N_THREADS; i++ ) {
+         lock_end[i] = TRUE;
+         phase[i]    = ZERO;
+     }
+     
+     do_pass();
+     return(0);
+ }
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/more-steps.exp gdb/testsuite/gdb.threads/more-steps.exp
*** ../gdb-19990719/gdb/testsuite/gdb.threads/more-steps.exp	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/more-steps.exp	Thu Jul 22 17:50:38 1999
***************
*** 0 ****
--- 1,131 ----
+ # more-steps.exp -- Expect script to test gdb's ability to step threaded pgms
+ # Copyright (C) 1992 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@prep.ai.mit.edu
+ 
+ if $tracelevel then {
+     strace $tracelevel
+ }
+ 
+ if { ![istarget "hppa*-*-hpux11.*"] } {
+     verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
+     return 0
+ }
+ 
+ set testfile more-steps
+ set srcfile ${srcdir}/${subdir}/${testfile}.c
+ set binfile ${objdir}/${subdir}/${testfile}
+ 
+ if [get_compiler_info ${binfile}] {
+     return -1
+ }
+ 
+ # To build the executable we need to link against the thread library.
+ #
+ if { $hp_cc_compiler } {
+     set additional_flags "additional_flags=-Ae"
+ } else {
+     set additional_flags ""
+ }
+ 
+ if { [gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}" executable [list debug $additional_flags ldflags=-lpthread]] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ 
+ # Thread stuff is _slow_; prepare for long waits.
+ #
+ set oldtimeout $timeout
+ set timeout [expr "$timeout + 300"]
+ set oldverbose $verbose
+ #set verbose 40
+ 
+ # Further, this test has some "null" lines designed
+ # to consume output from gdb that was too late to be
+ # matched (sequence is "gdb_test" sends; timeout and
+ # on to next send; result finally comes in; mismatch).
+ #
+ # The null command is 'gdb_test "p \$pc" ".*" ""'
+ #
+ # NOTE: to pass a literal "$", "/" or "*" (etc.) to gdb_test, 
+ #       remember that the pattern will be escaped once and 
+ #       $-evaluated twice:
+ #
+ #          "\\\*" matches "\*"
+ #          "\$"  matches "$"
+ #
+ proc fix_timeout {} {
+     gdb_test "p \$pc" ".*" ""
+ }
+ 
+ #=========================
+ #
+ # Simple sanity test first.
+ #
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+ 
+ # First, step in the main thread.
+ #
+ gdb_test "b do_pass" ".*Breakpoint 1.*" "breakpoint at do_pass"
+ gdb_test "r" ".*Breakpoint 1.*do_pass.*" "run"
+ 
+ # Breaks as well as nexts to make
+ # sure we can handle simultaneous hit
+ # of bpt and step, as well as stepping
+ # past bpts.
+ #
+ gdb_test "tb 87" ".*Breakpoint 2.*" "tbreak at line 87"
+ gdb_test "tb 91" ".*Breakpoint 3.*" "tbreak at line 91"
+ gdb_test "tb 96" ".*Breakpoint 4.*" "tbreak at line 96"
+ gdb_test "tb 113" ".*Breakpoint 5.*" "tbreak at line 113"
+ gdb_test "c" ".*do_pass.*87.*" "87"
+ gdb_test "n" ".*do_pass.*91.*" "n"
+ 
+ # This only gets a number, as it doesn't
+ # hit a bpt.
+ #
+ gdb_test "n" ".*95.*" "n"
+ 
+ gdb_test "n" ".*do_pass.*96.*" "n"
+ gdb_test "c" ".*do_pass.*113.*" "c"
+ gdb_test "c" ".*Program exited normally.*" "c"
+ 
+ # Now step in a thread
+ #
+ gdb_test "r" ".*Breakpoint.*do_pass.*" "do_pass"
+ gdb_test "until 87" ".*do_pass.*87.*" "until"
+ gdb_test "thr 4" ".*Switching to thread 4.*spin.*56.*" "switch"
+ gdb_test "tb 60 thr 4" ".*Breakpoint.*" "tbreak at line 60 thread 4"
+ 
+ # If we do "next" now, all the other threads 
+ # can finish!
+ #
+ gdb_test "n"    ".*58.*" "next line"
+ gdb_test "i th" ".*\\\* 4 sys.*spin.*1 sys.*do_pass.*" "still in 4"
+ 
+ # Done!
+ #
+ gdb_exit
+ 
+ set timeout $oldtimeout
+ set verbose $oldverbose
+ 
+ return 0
+ 
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/pthreads.exp gdb/testsuite/gdb.threads/pthreads.exp
*** ../gdb-19990719/gdb/testsuite/gdb.threads/pthreads.exp	Tue Feb  9 14:43:31 1999
--- gdb/testsuite/gdb.threads/pthreads.exp	Thu Jul 22 17:50:37 1999
***************
*** 50,55 ****
--- 50,56 ----
      set options "debug"
      lappend options "incdir=${objdir}/${subdir}"
      lappend options "libs=$lib"
+     clone_output "Trying to link against $lib"
      set ccout [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $options]
      switch -regexp -- $ccout {
  	".*no posix threads support.*" {
***************
*** 65,73 ****
--- 66,77 ----
  	{^$} {
  	    pass "successfully compiled posix threads test case"
  	    set built_binfile 1
+ 	    clone_output "Linking against $lib works."
  	    break
  	}
      }
+ 
+     clone_output "Failure ignored."
  }
  if {$built_binfile == "0"} {
      unsupported "Couldn't compile ${srcfile}, ${why_msg}"
***************
*** 180,186 ****
      # We should be able to do an info threads before starting any others.
      send_gdb "info threads\n"
      gdb_expect {
! 	-re ".*Thread.*LWP.*main.*$gdb_prompt $" {
  	    pass "info threads"
  	}
  	-re "\r\n$gdb_prompt $" {
--- 184,190 ----
      # We should be able to do an info threads before starting any others.
      send_gdb "info threads\n"
      gdb_expect {
! 	-re ".*(Thread.*LWP| thread ).*main.*$gdb_prompt $" {
  	    pass "info threads"
  	}
  	-re "\r\n$gdb_prompt $" {
***************
*** 193,223 ****
  
      # Extract the thread id number of main thread from "info threads" output.
      send_gdb "info threads\n"
!     gdb_expect -re "(\[0-9\]+)(${horiz}Thread${horiz}main.*)($gdb_prompt $)"
      set main_id $expect_out(1,string)
  
      # Check that we can continue and create the first thread.
      gdb_test "break thread1" "Breakpoint .* file .*$srcdir.*"
      gdb_test "continue" \
! 	    "Continuing.*Breakpoint .*, thread1 \\(arg=0xfeedface\\).*at.*$srcfile.*" \
  	    "Continue to creation of first thread"
      gdb_test "disable" ""
  
      # Extract the thread id number of thread 1 from "info threads" output.
      send_gdb "info threads\n"
!     gdb_expect -re "(\[0-9\]+)(${horiz}Thread${horiz}thread1.*)($gdb_prompt $)"
      set thread1_id $expect_out(1,string)
  
      # Check that we can continue and create the second thread,
      # ignoring the first thread for the moment.
      gdb_test "break thread2" "Breakpoint .* file .*$srcdir.*"
      gdb_test "continue" \
! 	    "Continuing.*Breakpoint .*, thread2 \\(arg=0xdeadbeef\\).*at.*$srcfile.*" \
  	    "Continue to creation of second thread"
  
      # Extract the thread id number of thread 2 from "info threads" output.
      send_gdb "info threads\n"
!     gdb_expect -re "(\[0-9\]+)(${horiz}Thread${horiz}thread2.*)($gdb_prompt $)"
      set thread2_id $expect_out(1,string)
  
      return 1
--- 197,227 ----
  
      # Extract the thread id number of main thread from "info threads" output.
      send_gdb "info threads\n"
!     gdb_expect -re "(\[0-9\]+)${horiz}(Thread|thread)${horiz}main.*$gdb_prompt $"
      set main_id $expect_out(1,string)
  
      # Check that we can continue and create the first thread.
      gdb_test "break thread1" "Breakpoint .* file .*$srcdir.*"
      gdb_test "continue" \
! 	    "Continuing.*Breakpoint .*, thread1 \\(arg=0xfeedface.*\\).*at.*$srcfile.*" \
  	    "Continue to creation of first thread"
      gdb_test "disable" ""
  
      # Extract the thread id number of thread 1 from "info threads" output.
      send_gdb "info threads\n"
!     gdb_expect -re "(\[0-9\]+)${horiz}(Thread|thread)${horiz}thread1.*$gdb_prompt $"
      set thread1_id $expect_out(1,string)
  
      # Check that we can continue and create the second thread,
      # ignoring the first thread for the moment.
      gdb_test "break thread2" "Breakpoint .* file .*$srcdir.*"
      gdb_test "continue" \
! 	    "Continuing.*Breakpoint .*, thread2 \\(arg=0xdeadbeef.*\\).*at.*$srcfile.*" \
  	    "Continue to creation of second thread"
  
      # Extract the thread id number of thread 2 from "info threads" output.
      send_gdb "info threads\n"
!     gdb_expect -re "(\[0-9\]+)${horiz}(Thread|thread)${horiz}thread2.*$gdb_prompt $"
      set thread2_id $expect_out(1,string)
  
      return 1
***************
*** 232,240 ****
      }
  
      # Send a continue followed by ^C to the process to stop it.
!     send_gdb "continue\n"
      set description "Stopped with a ^C"
!     after 1000 [send_gdb "\003"]
      gdb_expect {
  	-re "Program received signal SIGINT.*$gdb_prompt $" {
  	    pass $description
--- 236,256 ----
      }
  
      # Send a continue followed by ^C to the process to stop it.
!     #
!     # On fast systems the 'after 1000' part will have the threads
!     # stopped by breakpoint SIGTRAP.
!     # On HP-UX we'll just send ^C when we see that the threads are
!     # running again.
!     # - guo
!     #
      set description "Stopped with a ^C"
!     if [istarget "hppa*-hp-hpux*"] {
! 	send_gdb "continue\n"
! 	gdb_expect -re "Continuing"
! 	send_gdb "\003"
!     } else {
! 	after 1000 [send_gdb "\003"]
!     }
      gdb_expect {
  	-re "Program received signal SIGINT.*$gdb_prompt $" {
  	    pass $description
***************
*** 242,247 ****
--- 258,266 ----
  	-re "Quit.*$gdb_prompt $" {
  	    pass $description
  	}
+ 	-re "$gdb_prompt $" {
+ 	    fail $description
+ 	}
  	timeout {
  	    fail "$description (timeout)"
  	}
***************
*** 263,272 ****
  	    ".* in main \\(argc=.*, argv=.*\\).*" \
  	    "check backtrace from main thread"
      gdb_test "thread apply $thread1_id backtrace" \
! 	    ".* in thread1 \\(arg=0xfeedface\\).*" \
  	    "check backtrace from thread 1"
      gdb_test "thread apply $thread2_id backtrace" \
! 	    ".* in thread2 \\(arg=0xdeadbeef\\).*" \
  	    "check backtrace from thread 2"
  
      # Check that we can apply the backtrace command to all
--- 282,291 ----
  	    ".* in main \\(argc=.*, argv=.*\\).*" \
  	    "check backtrace from main thread"
      gdb_test "thread apply $thread1_id backtrace" \
! 	    ".* in thread1 \\(arg=0xfeedface.*\\).*" \
  	    "check backtrace from thread 1"
      gdb_test "thread apply $thread2_id backtrace" \
! 	    ".* in thread2 \\(arg=0xdeadbeef.*\\).*" \
  	    "check backtrace from thread 2"
  
      # Check that we can apply the backtrace command to all
***************
*** 324,328 ****
--- 343,355 ----
  	check_control_c
  	check_backtraces
      }
+ 
+     # let the program continue so we don't have the process hanging
+     # on the system
+     # - guo
+     send_gdb "disable\n"
+     gdb_expect -re "$gdb_prompt $"
+     send_gdb "continue\n"
+     gdb_expect -re "$gdb_prompt $"
  }
  clear_xfail "alpha-*-osf*"
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/quicksort.c gdb/testsuite/gdb.threads/quicksort.c
*** ../gdb-19990719/gdb/testsuite/gdb.threads/quicksort.c	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/quicksort.c	Thu Jul 22 17:50:38 1999
***************
*** 0 ****
--- 1,284 ----
+ /* BeginSourceFile quicksort.c
+ 
+   This file is take from the DDE test system.  It spawns six
+   threads to do a sort of an array of random numbers.
+ 
+   The locations marked "quick N" are used in the test "quicksort.exp".
+ 
+   The locations marked "att N" are used in the test "attach.exp".
+ 
+   To compile:
+ 
+       cc -Ae +DA1.0 -g -o quicksort -lpthread quicksort.c
+ 
+   To run:
+   
+      quicksort     --normal run
+      quicksort 1   --waits before starting to allow attach
+ */
+ 
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <assert.h>
+ #include <pthread.h>
+ 
+ #define TRUE 1
+ #define FALSE 0
+ #define SORTSET 100000
+ 
+ /* Uncomment to turn on debugging output */
+ /* #define QUICK_DEBUG  */
+ 
+ /* Uncomment to turn on wait on each thread create */
+ /* #define THREAD_WAIT */
+ 
+ /* Fewer than SORT_DIRECT items are sorted with an insertion sort. */
+ #define SORT_DIRECT 20
+ 
+ /* Work at this depth or less generates a separate work item. */
+ #define DEFER_DEPTH 6
+ 
+ /* Workpile controller */
+ typedef void (*work_proc_t)(void *);
+ 
+ typedef struct workpile_struct {
+ 	pthread_mutex_t lock;	       /* mutex for this structure */
+ 	pthread_cond_t work_wait;      /* workers waiting for work */
+ 	pthread_cond_t finish_wait;    /* to wait for workers to finish */
+ 	int max_pile;		       /* length of workpile array */
+ 	work_proc_t worker_proc;       /* work procedure */
+ 	int n_working;		       /* number of workers working */
+ 	int n_waiting;		       /* number of workers waiting for work */
+ 	int n_pile;		       /* number of pointers in the workpile */
+ 	int inp;		       /* FIFO input pointer */
+ 	int outp;		       /* FIFO output pointer */
+ 	void *pile[1];		       /* array of pointers - the workpile */
+ } *workpile_t;
+ 
+ typedef struct {
+ 	float *data;		   /* Array to sort */
+ 	int n;			   /* Number of elements in the array */
+ 	int depth;		   /* Depth of recursion */
+ 	workpile_t wp;		   /* Workpile to use */
+ } quick_sort_args;
+ 
+ /* True if waiting for attach.
+  */
+ int wait_here = FALSE;
+ 
+ static workpile_t quick_sort_workpile = NULL;
+ 
+ void *worker(void * wptr);
+ 
+ /* Allocates and initializes a workpile that holds max_pile entries.
+  * worker_proc is called to process each work item on the queue.
+  */
+ workpile_t
+ work_init(int max_pile, work_proc_t worker_proc, int n_threads)
+ {
+ 	int err;
+ 	pthread_t t;
+ 	workpile_t *wpptr = (workpile_t *)malloc (sizeof(workpile_t));	
+ 	workpile_t wp = (workpile_t)malloc(sizeof (struct workpile_struct) +
+ 			(max_pile * sizeof (void *)));
+ 	if (wp != NULL) {
+ 		*wpptr = wp;
+ 		pthread_mutex_init(&wp->lock, NULL);
+ 		pthread_cond_init(&wp->work_wait, NULL);
+ 		pthread_cond_init(&wp->finish_wait, NULL);
+ 		wp->max_pile = max_pile;
+ 		wp->worker_proc = worker_proc;
+ 		wp->n_working = wp->n_waiting = wp->n_pile = 0;
+ 		wp->inp = wp->outp = 0;
+ 		while (n_threads--) {
+ 			err = pthread_create(&t, NULL,
+ 			      worker, (void *)wpptr);
+ #ifdef QUICK_DEBUG
+                         printf( "== Quicksort: created new thread\n" );
+ #ifdef THREAD_WAIT
+                         if( n_threads > 0 ) {
+                             int i;
+                         printf( "== Quicksort: waiting on user input of an integer\n" );
+                             scanf( "%d", &i );
+                             printf( "== Quicksort: continuing with quicksort\n" );
+                         }
+ #endif
+ #endif
+ 
+ 			assert(err == 0);    /* quick 1 */
+ 		}
+                 /* All the threads have now been created.
+                  */
+                 assert( n_threads == -1 );         /* att 1 */
+                 if( wait_here ) {  sleep(10); /* gdb.threads/attache.exp */
+ #ifdef QUICK_DEBUG			     /* wants to hit 118 after c */
+                     printf( "== Quicksort: waiting for attach\n" );
+ #endif
+                     sleep( 25 );
+                 }
+                 wait_here = 99;              /* att 2, otherwise useless */
+ 	}
+ 	return (wp);                         /* quick 2 */
+ }
+ 
+ /*
+  * Worker thread routine. Continuously looks for work, calls the
+  * worker_proc associated with the workpile to do work.
+  */
+ void *
+ worker(void * wptr)
+ {
+         workpile_t wp;
+ 	void *ptr;
+ 
+         wp = * (workpile_t *) wptr;
+ 
+ 	pthread_mutex_lock(&wp->lock);
+ 	wp->n_working++;
+ 	for (;;) {
+ 		while (wp->n_pile == 0) {								/* wait for new work */
+ 			if (--wp->n_working == 0)
+ 				pthread_cond_signal(&wp->finish_wait);
+ 			wp->n_waiting++;
+ 			pthread_cond_wait(&wp->work_wait, &wp->lock);
+ 			wp->n_waiting--;       /* quick 3 */
+ 			wp->n_working++;
+ 		}
+ 		wp->n_pile--;
+ 		ptr = wp->pile[wp->outp];
+ 		wp->outp = (wp->outp + 1) % wp->max_pile;
+ 		pthread_mutex_unlock(&wp->lock);
+ 		/* Call application worker routine. */
+ 		(*wp->worker_proc)(ptr);
+ 		pthread_mutex_lock(&wp->lock);  /* quick 4 */
+ 	}
+ 	/* NOTREACHED */
+ }
+ 
+ /* Puts ptr in workpile. Called at the outset, or within a worker. */
+ void
+ work_put(workpile_t wp, void *ptr)
+ {
+ 	pthread_mutex_lock(&wp->lock);
+ 	if (wp->n_waiting) {
+ 		/* idle workers to be awakened */
+ 		pthread_cond_signal(&wp->work_wait);
+ 	}
+ 	assert(wp->n_pile != wp->max_pile);									/* check for room */
+ 	wp->n_pile++;
+ 	wp->pile[wp->inp] = ptr;
+ 	wp->inp = (wp->inp + 1) % wp->max_pile;
+ 	pthread_mutex_unlock(&wp->lock);
+ }
+ 
+ 
+ /* Wait until all work is done and workers quiesce. */
+ void
+ work_wait(workpile_t wp)
+ {
+ 	pthread_mutex_lock(&wp->lock);
+ 	while(wp->n_pile !=0 || wp->n_working != 0)
+ 		pthread_cond_wait(&wp->finish_wait, &wp->lock);
+ 	pthread_mutex_unlock(&wp->lock);
+ }
+ 
+ void
+ quick_sort_aux(float *data, int n, int depth, workpile_t wp, int deferrable)
+ {
+ 	int i,j;
+ 
+ 	/* If array small, use insertion sort */
+ 	if (n <= SORT_DIRECT) {
+ 		for (j = 1; j < n; j++) {
+ 			/* data[0..j-1] in sort; find a spot for data[j] */
+ 			float key = data[j];
+ 			for (i = j - 1; i >= 0 && key < data[i]; i--)
+ 				data[i+1] = data[i];
+ 			data[i+1] = key;
+ 		}
+ 		return;
+ 	}
+ 	/* Defer this work to work queue if policy says so */
+ 	if (deferrable && depth <= DEFER_DEPTH) {
+ 		quick_sort_args *q = (quick_sort_args *)
+ 								malloc(sizeof (quick_sort_args));
+ 		assert(q != NULL);
+ 		q->data = data; q->n = n; q->depth = depth; q->wp = wp;
+ 		work_put(wp, (void *)q);
+ 		return;
+ 	}
+ 	/* Otherwise, partition data based on a median estimate */
+ #define swap(i,j) {float t = data[i]; data[i] = data[j]; data[j] = t;}
+ 	i = 0;
+ 	j = n - 1;
+ 	for (;;) {
+ 		while (data[i] < data[j]) j--;
+ 		if (i >= j) break;
+ 		swap(i, j); i++;
+ 		while (data[i] < data[j]) i++;
+ 		if (i >= j) { i = j; break; }
+ 		swap(i, j); j--;
+ 	}
+ 	/* Median value is now at data[i] */
+ 	/* Partitioned so that data[0..i-1] <= median <= data[i+1..n-1] */
+ 	quick_sort_aux(data,       i,     depth+1, wp, TRUE);
+ 	quick_sort_aux(&data[i+1], n-i-1, depth+1, wp, TRUE);
+ }
+ /* Called from workpile controller with argument pointing to work. */
+ void
+ quick_sort_worker(void *a)
+ {
+ 	quick_sort_args *q = (quick_sort_args *)a;
+ 	quick_sort_aux(q->data, q->n, q->depth, q->wp, FALSE);
+ 	free(q);
+ }
+ /* Main routine, called by client to do a sort. */
+ void
+ quick_sort(float *data, int n)
+ {
+ 	if (quick_sort_workpile == NULL) {
+ 		int n_threads = 6;
+ 		quick_sort_workpile = work_init(2 << DEFER_DEPTH,
+ 			quick_sort_worker, n_threads);
+ 		assert(quick_sort_workpile != NULL);
+ 	}
+         
+ 	quick_sort_aux(data, n, 0, quick_sort_workpile, FALSE);
+         
+ 	/* Wait for all work to finish */
+ 	work_wait(quick_sort_workpile);
+         
+ #ifdef QUICK_DEBUG
+         printf( "== Quicksort: done sorting\n" );
+ #endif
+ }
+ 
+ 
+ main( argc, argv )
+ int    argc;
+ char **argv;
+ {
+ 	float data[SORTSET];
+ 	int i; int debugging = 0;
+ 
+         if((argc > 1) && (0 != argv )) {
+             if( 1 == atoi( argv[1] ) )
+                wait_here = TRUE;
+         }
+ 
+ 	for(i = 0; i < SORTSET; i++)
+ 		data[SORTSET -1 -i] = drand48();
+                 
+ 	for(i = 0; i < SORTSET; i++)
+ 		if (debugging)
+                    printf("data[%d] = %f\n", i, data[i]);
+ 
+ 	quick_sort(data, SORTSET);
+ 	for(i = 0; i < SORTSET; i++)
+ 		if (debugging)
+ 		printf("data[%d] = %f\n", i, data[i]);
+ 
+ 	return(0);
+ }
+ /* EndSourceFile */
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/quicksort.exp gdb/testsuite/gdb.threads/quicksort.exp
*** ../gdb-19990719/gdb/testsuite/gdb.threads/quicksort.exp	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/quicksort.exp	Thu Jul 22 18:50:01 1999
***************
*** 0 ****
--- 1,839 ----
+ # quicksort.exp -- Expect script to test gdb with quicksort.c
+ # Copyright (C) 1992 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@prep.ai.mit.edu
+ 
+ if $tracelevel then {
+     strace $tracelevel
+ }
+ 
+ if { ![istarget "hppa*-*-hpux11.*"] } {
+     verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
+     return 0
+ }
+ 
+ set testfile quicksort
+ set srcfile ${srcdir}/${subdir}/${testfile}.c
+ set binfile ${objdir}/${subdir}/${testfile}
+ 
+ if [get_compiler_info ${binfile}] {
+     return -1
+ }
+ 
+ # To build the executable we need to link against the thread library.
+ #
+ 
+ if { $hp_cc_compiler } {
+     set additional_flags "additional_flags=-Ae"
+ } else {
+     set additional_flags ""
+ }
+ 
+ if { [gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}" executable [list debug $additional_flags ldflags=-lpthread]] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ 
+ # Thread stuff is _slow_; prepare for long waits.
+ #
+ set oldtimeout $timeout
+ set timeout [expr "$timeout + 600"]
+ 
+ # Further, this test has some "null" lines designed
+ # to consume output from gdb that was too late to be
+ # matched (sequence is "gdb_test" sends; timeout and
+ # on to next send; result finally comes in; mismatch).
+ #
+ # The null command is 'gdb_test "p \$pc" ".*" ""'
+ #
+ # NOTE: to pass a literal "$", "/" or "*" (etc.) to gdb_test, 
+ #       remember that the pattern will be escaped once and 
+ #       $-evaluated twice:
+ #
+ #          "\\\*" matches "\*"
+ #          "\$"  matches "$"
+ #
+ proc fix_timeout {} {
+     gdb_test "p \$pc" ".*" ""
+ }
+ 
+ #=========================
+ #
+ # Simple sanity test first.
+ #
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+ 
+ gdb_test "tb 122" ".*Breakpoint.*" "tbreak at line 122"
+ gdb_test "r" ".*122.*" "run to line 122"
+ gdb_test "thr 99" ".*Thread ID 99 not known.*" "Check too-big thread number"
+ gdb_test "tb 145 thr 3" ".*Breakpoint.*" "set thread-specific bp 145"
+ gdb_test "tb 146 thr 4" ".*Breakpoint.*" "set thread-specific bp 146"
+ gdb_test "c" ".*Switched to thread.*14\[56\].*" "auto switch"
+ gdb_test "c" ".*Switched to thread.*14\[56\].*" "auto switch 2"
+ gdb_test "c" ".*Program exited normally.*" "continue"
+ 
+ #=========================
+ #
+ # Test that you can't do a thread select after a program runs.
+ #
+ gdb_test "thread" ".*No stack.*" "No live thread after run"
+ gdb_test "thr 2"  ".*No stack.*" "Can't set thread after run"
+ 
+ #=========================
+ #
+ # Test thread command changes, look for frame level reset bug.
+ #
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+ gdb_test "b 122" ".*" "break at line 122"
+ gdb_test "r" ".*122.*" "run to line 122"
+ 
+ # Prep for frame level test--go up/info thread/check frame
+ #
+ gdb_test "up" ".*quick_sort.*" "up"
+ gdb_test "up" ".*main.*"       "up"
+ 
+ send_gdb "i th\n"
+ gdb_expect {
+   -re ".*7 thread.* in .* from .* in .* from .* 6 thread.*$gdb_prompt $" {
+       fail "old thread command, says things twice"
+   }
+   -re ".*7 system thread.*6 system th.*5 sys.*4.*3.*2.*1.*work_init.*$gdb_prompt $" {
+       pass "info threads"
+   }
+   -re ".*$gdb_prompt $"  { fail "no info thread command" }
+   timeout { fail "timeout" }
+ }
+ 
+ # We should have been restored two frames up--check.
+ #
+ send_gdb "up\n"
+ gdb_expect {
+     -re ".*Initial frame selected.*$gdb_prompt $" {
+         pass "Frame correctly reset after 'info threads'"
+     }
+     -re ".*quick_sort.*$gdb_prompt $" {
+         fail "Old gdb bug; should be fixed someday"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "real bug--FIX!"
+     }
+     timeout { fail "timeout" }
+ }
+ 
+ # Do it again, only just go to a middle frame, and use another thread.
+ #
+ gdb_test "thr 5" ".*" "switching to thread 5"
+ gdb_test "bt" ".*0.*__ksleep.*.*1.*libpthread.*.*2.*pthread_cond_wait.*.*3.*worker.*144.*.*4.*__pthread_create_system.*" "backtrace in thread 5"
+ send_gdb "up\n"
+ gdb_expect {
+     -re ".*1.*_lwp_cond_timedwait.*$gdb_prompt $" { pass "up 1 in thread 5 (1)" }
+     -re ".*1.*in .stub.*libpthread.*$gdb_prompt $" { pass "up 1 in thread 5 (2)" }
+     timeout { fail "(timeout) up 1 in thread 5" }
+ }
+ gdb_test "up" ".*2.*pthread_cond_wait.*"   "up 2 in thread 5"
+ gdb_test "up" ".*3.*worker.*"              "up 3 in thread 5"
+ gdb_test "i th" ".*7.*6.*work_init.*"      "getting ids of the current threads"
+ gdb_test "f"  ".*3.*worker.*"              "Frame restored"
+ gdb_test "p wp->max_pile" ".*= 128.*"      "can see vars in frame"
+ 
+ # Thread command changes
+ #
+ gdb_test "thr"    ".*Current thread is 5.*"   "threads-no-num"
+ gdb_test "thr 6"  ".*Switching to thread 6.*" "new switch"
+ gdb_test "thr"    ".*Current thread is 6.*"   "check switch"
+ gdb_test "thr 6"  ".*Current thread is already 6.*" "dup, no switch"
+ gdb_test "thr app all p x" ".*No symbol.*"    "thread app all"
+ gdb_test "thr"    ".*Current thread is 6.*"   "restore current thread"
+ 
+ #=========================
+ #
+ # Test new stepping
+ #
+ 
+ proc get_hit { } {
+     global hit2
+     global hit3
+     global hit4
+     global hit5
+     global hit6
+     global hit7
+     global gdb_prompt
+ 
+     send_gdb "cont\n"
+     gdb_expect {
+         -re ".*Breakpoint.*145.*$gdb_prompt $" {
+             send_gdb "thr\n"
+             gdb_expect {
+                 -re ".*is 7.*$gdb_prompt $" {
+                     set hit7 [expr "$hit7 + 1"]
+                 }
+                 -re ".*is 6.*$gdb_prompt $" {
+                     set hit6 [expr "$hit6 + 1"]
+                 }
+                 -re ".*is 5.*$gdb_prompt $" {
+                     set hit5 [expr "$hit5 + 1"]
+                 }
+                 -re ".*is 4.*$gdb_prompt $" {
+                     set hit4 [expr "$hit4 + 1"]
+                 }
+                 -re ".*is 3.*$gdb_prompt $" {
+                     set hit3 [expr "$hit3 + 1"]
+                 }
+                 -re ".*is 2.*$gdb_prompt $" {
+                     set hit2 [expr "$hit2 + 1"]
+                 }
+                 -re ".*$gdb_prompt $" {
+                     fail "can't see which thread"
+                 }
+                 timeout { fail "timeout" }
+             }
+         }
+         -re ".*$gdb_prompt $" {
+             fail "thread command"
+         }
+         timeout { fail "timeout" }
+     }
+ }
+ 
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+ gdb_test "break 122" ".*" "break at line 122"
+ gdb_test "run"      ".*122.*" "run to line 122"
+ 
+ # Make sure we hit a bp on every thread.
+ #
+ # Try one, via thread-specific bps
+ #
+ gdb_test "break 145 thr 2" ".*" "set thread-specific bp thr 2"
+ gdb_test "break 145 thr 3" ".*" "set thread-specific bp thr 3"
+ gdb_test "break 145 thr 4" ".*" "set thread-specific bp thr 4"
+ gdb_test "break 145 thr 5" ".*" "set thread-specific bp thr 5"
+ gdb_test "break 145 thr 6" ".*" "set thread-specific bp thr 6"
+ gdb_test "break 145 thr 7" ".*" "set thread-specific bp thr 7"
+ 
+ set hit2 0
+ set hit3 0
+ set hit4 0
+ set hit5 0
+ set hit6 0
+ set hit7 0
+ 
+ get_hit
+ get_hit
+ get_hit
+ get_hit
+ get_hit
+ get_hit
+ 
+ # Sometimes we hit one twice and don't hit another.
+ set total_hits [expr $hit2 + $hit3 + $hit4 + $hit5 + $hit6 + $hit7 ]
+ if $total_hits==6 {
+     pass "thread-specific bps 1"
+ } else {
+     fail "thread-specific bps 1"
+ }
+ 
+ #====================
+ #
+ # Now use generic bps
+ #
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+ gdb_test "b 122" ".*" "break at line 122"
+ gdb_test "r" ".*122.*" "run to line 122"
+ 
+ # Make sure we hit a bp on every thread.
+ #
+ # Try two, via non-thread-specific bp
+ #
+ gdb_test "b 145" ".*" "b 145"
+ 
+ set hit2 0
+ set hit3 0
+ set hit4 0
+ set hit5 0
+ set hit6 0
+ set hit7 0
+ 
+ get_hit
+ get_hit
+ get_hit
+ get_hit
+ get_hit
+ get_hit
+ 
+ # Sometimes we hit one twice and don't hit another.
+ set hit_totals [expr "$hit2 + $hit3 + $hit4 + $hit5 + $hit6 + $hit7"]
+ if { [expr "$hit_totals == 6"] } {
+     pass "thread-specific bps 2"
+ } else {
+     fail "thread-specific bps 2"
+ }
+ 
+ #====================
+ #
+ # Complicated (original) test next.
+ #
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+ 
+ if ![runto_main] then {
+    fail "Can't run to main"
+    return 0
+ }
+ 
+ # OK, we're at "main", there should be one thread.
+ #
+ gdb_test "info thread" ".*\\\* 1 system thread .*main.*" "initial thread"
+  
+ # Try to see the threads being created: set a breakpoint 
+ # after the creation and go around the loop a few times.
+ #
+ gdb_test "break 109" "Breakpoint.*109.*" "set bpt"
+ 
+ gdb_test "c" ".*New thread.*Breakpoint.*109.*" "first continue"
+ fix_timeout
+ 
+ # Make sure we don't wait (waiting is for attach test)
+ #
+ gdb_test "set wait_here = 0" ".*" "make sure we don't wait"
+ 
+ send_gdb "info thr\n"
+ gdb_expect {
+     -re ".*2 system th.*1 sy.*109.*$gdb_prompt $" { pass "saw thread create" }
+     -re ".*1 system thread.*87.*$gdb_prompt $"    { fail "didn't see thread create" }
+     -re ".*$gdb_prompt $"                         { fail "no info thread command" }
+     timeout { fail "timeout" }
+ }
+ 
+ gdb_test "c"      ".*New thread.*Breakpoint.*109.*" "continue"
+ fix_timeout
+ 
+ send_gdb "info thr\n"
+ gdb_expect {
+     -re ".*3 system thread.*2 sys.*\\\* 1 system thread.*109.*$gdb_prompt $" { 
+         pass "saw thread create" }
+     -re ".*2 system thread.*1 sys.*109.*$gdb_prompt $" { 
+         fail "didn't see thread create" 
+     }
+     -re ".*1 system thread.*109.*$gdb_prompt $" {
+         fail "didn't see thread create" 
+     }
+     -re ".*$gdb_prompt $" {
+         fail "no info thread command" 
+     }
+     timeout { fail "timeout" }
+ }
+ 
+ fix_timeout
+ gdb_test "clear" ".*Deleted breakpoint.*" "clear"
+ 
+ # Now go on to the end of thread creation.
+ #
+ gdb_test "b 122"  ".*"     "set bpt 122"
+ gdb_test "c"     ".*New thread.*New thread.*New thread.*122.*" "continue"
+ gdb_test "p \$pc" ".*" "print pc"
+ gdb_test "clear" ".*Deleted breakpoint.*" "clear"
+ 
+ send_gdb "info thr\n"
+ gdb_expect {
+     -re ".*7 system thread.*6 sys.*5.*1 system thread.*122.*$gdb_prompt $" 
+         { pass "saw thread creates" }
+     -re ".*$gdb_prompt $"                           
+         { fail "no info thread command" }
+     timeout { fail "timeout" }
+ }
+ 
+ # Try a thread-specific breakpoint; we expect the other threads to
+ # be waiting at this point.
+ #
+ gdb_test "thr 3"  ".*Switching to thread.*ksleep.*" "thread switch"
+ gdb_test "i th"   ".*\\\* 3 system thread.*"        "show new current thread"
+ 
+ send_gdb "up\n"
+ gdb_expect {
+     -re ".*lwp_cond_timedwait.*$gdb_prompt $" { pass "up to _lwp_cond_timedwait (1)"}
+     -re ".*stub.*$gdb_prompt $" { pass "up to _lwp_cond_timedwait (1)"}
+     timeout { fail "(timeout) up to _lwp_cond_timedwait" }
+ }
+ gdb_test "up"     ".*pthread_cond_wait.*"  "up to __pthread_cond_wait"
+ gdb_test "up"     ".*worker.*144.*"        "up to worker"
+ 
+ gdb_test "b 145 th 3" ".*Breakpoint.*145.*" "set thread-specific bp"
+ gdb_test "i b"    ".*breakpoint.*breakpoint.*145 thread 3.*" "show thread-specific bp"
+ 
+ gdb_test "c"      ".*Breakpoint.*145.*145.*" "hit thread-specific bp"
+ gdb_test "p \$pc" ".*" "print pc"
+ 
+ # Test thread apply command on thread specific data.
+ #
+ gdb_test "thre app all p \$pc" ".*Thread 7.*Thread 6.*Thread 5.*Thread 4.*Thread 3.*Thread 2.*Thread 1.*" "thread apply all"
+ gdb_test "thr ap 1 3 5 p \$pc" ".*Thread 1.*Thread 3.*Thread 5.*" "thr app 1 3 5"
+ 
+ # Switch again, and test that others continue on a "next"
+ # This test _could_ fail due to timing issues, but that's
+ # unlikely.
+ #
+ gdb_test "thr 7" ".*Switching to thread.*" "switch to thread 7"
+ 
+ # Make sure that "up" stops at __pthread_exit, or
+ # __pthread_create, the pseudo-roots, and that we 
+ # only see that pseudo-root once.
+ #
+ send_gdb "bt\n"
+ gdb_expect {
+     -re ".*Error accessing memory address.*$gdb_prompt $" { fail "bt" }
+     -re ".*pthread_create.*pthread_create.*$gdb_prompt $" { fail "bt" }
+     -re ".*worker.*pthread_create.*$gdb_prompt $"         { pass "bt" }
+     -re ".*pthread_exit.*$gdb_prompt $"                   { pass "bt" }
+     -re ".*$gdb_prompt $" { fail "bt" }
+     timeout { fail "timeout on bt" }
+ }
+ 
+ gdb_test "up" ".*"           "up"
+ gdb_test "up" ".*"           "up"
+ send_gdb "up\n"
+ # The ".*__pthread_cond_wait" pattern happens if we were stopped in
+ # __ksleep
+ gdb_expect {
+     -re ".*144.*$gdb_prompt $"	{ pass "Up 3" }
+     -re ".*pthread_cond_wait.*$gdb_prompt $" { pass "Up 3" }
+     -re ".*$gdb_prompt $" { fail "Up 3" }
+     timeout { fail "timeout on Up 3" }
+ }
+ 
+ gdb_test "up" ".*pthread_.*" "Up 4"
+ send_gdb "up\n"
+ gdb_expect {
+     -re ".*Initial frame selected; you cannot go up.*$gdb_prompt $" { pass "catch end of thread stack" }
+     -re ".* in __pthread_create_system.*$gdb_prompt $" {
+ 	gdb_test "up" ".*Initial frame selected; you cannot go up.*" "catch end of thread stack"
+     }
+     -re ".*$gdb_prompt $" { fail "catch end of thread stack" }
+     timeout { fail "(timeout) catch end of thread stack" }
+ }
+ 
+ #=====================
+ #
+ # Things get iffy here; when we step, sometimes the step
+ # completes, sometimes it doesn't.  When it doesn't, we
+ # hit a bp somewhere else and the step never completes
+ # (wait_for_inferior just evaporates it). 
+ #
+ # I think the right answer is that any failures here
+ # should stick around to trigger later fixing.
+ #
+ #  Here's the plan: 
+ #
+ #  Bps at 148 (5) and 154 (6) on thread 7 (two bps so we 
+ #     see the difference between going around the loop and
+ #     reporting the same bp hit twice).
+ #
+ #  Bp at 144 on thread 3.
+ #
+ #  Step out of a library routine.
+ #
+ # Either the step will finish or a bp will hit.  Try to
+ # handle all the cases.
+ #
+ gdb_test "b 148 thr 7" ".*Breakpoint.*148.*" "set bpt 1"
+ gdb_test "b 154 thr 7" ".*Breakpoint.*154.*" "set bpt 2"
+ 
+ set hit_154_bp 0
+ set hit_148_bp 0
+ set hit_145_bp 0
+ set step_completed 0
+ 
+ # Expect zero hits
+ #
+ gdb_test "i b" ".*" "info break"
+ 
+ # DTS 10080CLLbs - thread switch not reported
+ setup_xfail hppa*-*-*11* 10080CLLbs
+ send_gdb "n\n"
+ gdb_expect {
+     -re ".*Single stepping.*_lwp_cond_timedwait.*$gdb_prompt $" {
+         send_gdb "thr\n"
+         gdb_expect {
+             -re ".*is 7.*$gdb_prompt $" {
+                 set step_completed 1
+                 pass "completed step in library code"
+             }
+             -re ".*$gdb_prompt $" {
+                 fail "completed step in library code, but in wrong thread"
+             }
+             timeout { fail "timeout" }
+         }
+     }
+     -re ".*Single stepping.*Switched to thread 3.*Breakpoint.*$gdb_prompt $" {
+         pass "step cancelled; hit bp due to thread parallelism"
+         set hit_145_bp 1
+     }
+     -re ".*Single stepping.*Switched to thread 7.*Breakpoint.*148.*$gdb_prompt $" {
+         pass "step cancelled; hit bp due to thread parallelism"
+         set hit_148_bp 1
+     }
+     -re ".*Single stepping.*Switched to thread 7.*Breakpoint.*154.*$gdb_prompt $" {
+         pass "step cancelled; hit bp due to thread parallelism"
+         set hit_154_bp 1
+     }
+     -re ".*$gdb_prompt $" {
+         send_gdb "thr\n"
+         gdb_expect {
+             -re ".*is 7.*$gdb_prompt $" {
+                 fail "No event?"
+             }
+             -re ".*$gdb_prompt $" {
+                 fail "No event"
+             }
+             timeout { fail "timeout" }
+         }
+     }
+     timeout { fail "timeout" }
+ }
+ 
+ # Sometimes used to get SIGTRAP here; that should be fixed
+ #
+ 
+ # Expect appropriate hits of bpt; too much work to parse
+ # result and check...
+ #
+ gdb_test "i b" ".*" "info break"
+ 
+ send_gdb "c\n"
+ gdb_expect {
+     -re ".*SIGTRAP.*$gdb_prompt $" {
+         fail "got SIGTRAP"
+     }
+     -re ".*Switched to thread 7.*Breakpoint.*154.*$gdb_prompt $" {
+         if { $hit_154_bp == 1 } {
+             fail "re-hit old bp"
+         } else {
+             pass "continue; hit parallel event after continue"
+         }
+         set hit_154_bp 1
+     }
+     -re ".*Switched to thread 7.*Breakpoint.*148.*$gdb_prompt $" {
+         if { $hit_148_bp == 1 } {
+             fail "re-hit old bp"
+         } else {
+             pass "continue; hit parallel event after continue"
+         }
+         set hit_148_bp 1
+     }
+     -re ".*Breakpoint.*154.*$gdb_prompt $" {
+         if { $hit_154_bp == 1 } {
+             fail "re-hit old bp"
+         } else {
+             send_gdb "thr\n"
+             gdb_expect {
+                 -re ".*is 7.*$gdb_prompt $" {
+                     pass "continue; hit parallel event after continue"
+                 }
+                 -re ".*$gdb_prompt $" {
+                     fail "hit bp in wrong thread"
+                 }
+                 timeout { fail "timeout" }
+             }
+         }
+         set hit_154_bp 1
+     }
+     -re ".*Breakpoint.*148.*$gdb_prompt $" {
+         if { $hit_148_bp == 1 } {
+             fail "re-hit old bp"
+         } else {
+             send_gdb "thr\n"
+             gdb_expect {
+                 -re ".*is 7.*$gdb_prompt $" {
+                     pass "continue; hit parallel event after continue"
+                 }
+                 -re ".*$gdb_prompt $" {
+                     fail "hit bp in wrong thread"
+                 }
+                 timeout { fail "timeout" }
+             }
+         }
+         set hit_148_bp 1
+     }
+     -re ".*Breakpoint.*145.*$gdb_prompt $" {
+         if { $hit_145_bp == 1 } {
+             fail "re-hit old bp"
+         } else {
+             send_gdb "thr\n"
+             gdb_expect {
+                 -re ".*is 3.*$gdb_prompt $" {
+                     pass "continue; hit parallel event after continue"
+                 }
+                 -re ".*$gdb_prompt $" {
+                     fail "hit bp in wrong thread"
+                 }
+                 timeout { fail "timeout" }
+             }
+         }
+         set hit_145_bp 1
+     }
+     -re ".*_lwp_cond_timedwait.*$gdb_prompt $" {
+         pass "continue; hit step completion after continue"
+     }
+     -re ".*Program exited normally.*" {
+         fail "Program ended? HOW?"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "Unexpected event"
+     }
+     timeout { fail "timeout" }
+ }
+ 
+ # There are a number of places we _could_ be now;
+ # this is the price of really running in parallel.
+ #
+ send_gdb "n\n"
+ gdb_expect {
+     -re ".*Switched to thread 7.*pthread_cond_wait.*$gdb_prompt $" {
+         if { $step_completed } {
+             fail "step already completed"
+         } else {
+             pass "finish step"
+         }
+     }
+     -re ".*pthread_cond_wait.*$gdb_prompt $" {
+         #
+         # Unlikely, but we might finish the range step from inside
+         # ksleep, before anything else.
+         #
+         if { $step_completed } {
+             fail "step already completed"
+         } else {
+             send_gdb "thr\n"
+             gdb_expect {
+                 -re ".*is 7.*$gdb_prompt $" {
+                     pass "finish step"
+                 }
+                 -re ".*$gdb_prompt $" {
+                     fail "step in wrong thread"
+                 }
+                 timeout { fail "timeout" }
+             }
+         }
+     }
+     -re ".*Switched to thread.*Breakpoint.*145.*$gdb_prompt $" {
+         pass "auto-switch thread" 
+     }
+     -re ".*Breakpoint.*145.*$gdb_prompt $" {
+         pass "auto-switch not needed, ok" 
+     }
+     -re "146.*wp->n_working.*" {
+         pass "auto-switch not needed, ok" 
+     }
+     -re ".*140.*while.*n_pile.*$gdb_prompt $" {
+         #
+         # This is just going around the loop from the 154 bp.
+         #
+         send_gdb "thr\n"
+         gdb_expect {
+             -re ".*is 7.*$gdb_prompt $" {
+                 pass "finish step"
+             }
+             -re ".*$gdb_prompt $" {
+                 fail "step in wrong thread"
+             }
+             timeout { fail "timeout" }
+         }
+     }
+     -re ".*149.*ptr = wp.*pile.*$gdb_prompt $" {
+         #
+         # This is just going around the loop from the 148 bp.
+         #
+         if { $hit_154_bp } {
+             send_gdb "thr\n"
+             gdb_expect {
+                 -re ".*is 7.*$gdb_prompt $" {
+                     pass "finish step"
+                 }
+                 -re ".*$gdb_prompt $" {
+                     fail "step in wrong thread"
+                 } 
+                 timeout { fail "timeout" }
+             }
+         } else {
+             pass "step from 149 but didn't hit it first"
+         }
+     }
+     -re ".*Breakpoint 5.*154.*$gdb_prompt $" {
+         gdb_test "i b" ".*"
+         if { $hit_154_bp } {
+             fail "hit bp again?"
+         } else {
+             pass "hit bp"
+         }
+     }
+     -re ".*Breakpoint 5.*148.*$gdb_prompt $" {
+         gdb_test "i b" ".*"
+         if { $hit_148_bp } {
+             fail "hit bp again?"
+         } else {
+             pass "hit bp"
+         }
+     }
+     -re ".*$gdb_prompt $" {
+         fail "no step finished"
+     }
+     timeout { fail "timeout on 'next'" }
+ }
+ 
+ # Let's get into some kind of known state again.
+ #
+ gdb_test "thr 7" ".*" "thread 7"
+ gdb_test "info thread" ".*" "info thread"
+ #gdb_test "i b" ".*"
+ 
+ # Leave breakpoint "154 thr 7" as only live bp.
+ # 
+ gdb_test "d 1"   ".*" "del main bp"
+ gdb_test "d 4"   ".*" "thread-specific bpt delete"
+ gdb_test "d 5"   ".*" "other bp delete"
+ send_gdb "i b\n"
+ gdb_expect {
+     -re ".*breakpoint.*breakpoint.*$gdb_prompt $" {
+         fail "more than one bp left"
+     }
+     -re ".*breakpoint.*154.*thread.*7.*$gdb_prompt $" {
+         pass "Only one bp left"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "Wrong or no bp left"
+     }
+     timeout { fail "timeout on info b" }
+ }
+ 
+ send_gdb "c\n" 
+ gdb_expect {
+     -re ".*SIGTRAP.*Switched to thread.*$gdb_prompt $" {
+         fail "SIGTRAP error; lost thread-specific bpt"
+     }
+     -re ".*SIGTRAP.*Switched to thread.*154.*$gdb_prompt $" {
+         fail "SIGTRAP, but hit right thread-specific bpt"
+     }
+     -re ".*Switched to thread.*Breakpoint.*154.*$gdb_prompt $" {
+         pass "auto-switch back"
+     }
+     -re ".*Breakpoint.*154.*$gdb_prompt $" {
+         pass "step to bp"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "auto-switch back" 
+     }
+     -re ".*Program exited normally.*$gdb_prompt $" {
+         fail "step lost"
+     }
+     timeout {
+         fail "timeout"
+     }
+ }
+ fix_timeout
+ 
+ gdb_test "cle"   ".*Deleted breakpoint.*" "delete last breakpoint"
+ 
+ # Sometimes get SIGTRAP here.  Continue sometimes gets another...
+ #
+ # DTS 10082CLLbs - Sometimes gdb gets a SIGTRAP on a deleted breakpoint
+ setup_xfail hppa*-*-*11* 10082CLLbs
+ send_gdb "c\n"
+ gdb_expect {
+     -re ".*SIGTRAP.*154.*154.*$gdb_prompt $" {
+         fail "SIGTRAP on deleted bp 154 "
+ 	gdb_test "n" ".*"
+ 	gdb_test "set confirm off" ".*"
+ 	gdb_test "delete" ".*"
+ 	gdb_test "c" ".*"
+ 	gdb_test "n" ".*"
+ 	gdb_test "c" ".*"
+ 	gdb_test "n" ".*"
+ 	gdb_test "c" ".*"
+ 	gdb_test "n" ".*"
+ 	gdb_test "c" ".*"
+ 	gdb_test "n" ".*"
+ 	gdb_test "c" ".*"
+ 	gdb_test "n" ".*"
+ 	gdb_test "c" ".*"
+ 	gdb_test "n" ".*"
+         send_gdb "c\n" 
+         gdb_expect {
+             -re ".*$gdb_prompt $" { pass "fixup"}
+             timeout { fail "fixup" }
+         }
+    }
+     -re ".*SIGTRAP.*144.*145.*$gdb_prompt $" {
+         fail "SIGTRAP on deleted bp 145 "
+         send_gdb "c\n"
+         gdb_expect {
+             -re ".*$gdb_prompt $" { pass "fixup"}
+             timeout { fail "fixup" }
+         }
+     }
+     -re ".*SIGTRAP.*148.*148.*$gdb_prompt $" {
+         fail "SIGTRAP on deleted bp 148 "
+         send_gdb "c\n"
+         gdb_expect {
+             -re ".*$gdb_prompt $" { pass "fixup"}
+             timeout { fail "fixup" }
+         }
+     }
+     -re ".*SIGTRAP.*$gdb_prompt $" {
+         fail "unknown SIGTRAP"
+         send_gdb "c\n"
+         gdb_expect {
+             -re ".*$gdb_prompt $" { pass "fixup"}
+             timeout { fail "fixup" }
+         }
+     }
+     -re ".*Program exited.*$gdb_prompt $" {
+         pass "run to end"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "run to end"
+         send_gdb "c\n"
+         gdb_expect {
+             -re ".*$gdb_prompt $" { pass "fixup"}
+             timeout { fail "fixup" }
+         }
+     }
+     timeout { fail "timeout" }
+ }
+ 
+ gdb_test "p \$pc" ".*No registers.*" "program done"
+ 
+ # Done!
+ #
+ gdb_exit
+ 
+ set timeout $oldtimeout
+ 
+ return 0
+ 
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/start-stop.c gdb/testsuite/gdb.threads/start-stop.c
*** ../gdb-19990719/gdb/testsuite/gdb.threads/start-stop.c	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/start-stop.c	Thu Jul 22 17:50:39 1999
***************
*** 0 ****
--- 1,161 ----
+ /* BeginSourceFile start_stop.c
+ 
+   This file creates and deletes threads, so that wdb
+   can be tested on thread delete.
+ 
+   To compile:
+ 
+       cc -Ae +DA1.0 -g -o start_stop -lpthread start_stop.c
+ 
+   To run:
+   
+      start_stop     --normal run
+      start_stop 1   --waits in each thread to keep it alive.
+ */
+ 
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <assert.h>
+ #include <pthread.h>
+ 
+ #define TRUE 1
+ #define FALSE 0
+ #define OUTER_LOOP_COUNT 3
+ #define N_THREADS 3
+ #define MAX_LOCAL_VAL 40
+ 
+ /* Uncomment to turn on debugging output */
+ /* #define START_DEBUG  */
+ 
+ /* True if waiting for attach.
+  */
+ int wait_here;
+ 
+ /* Thing to check for debugging purposes.
+ */
+ int a_global = 0;
+ 
+ /* Thread-local storage.
+  */
+ __thread int a_thread_local;
+ 
+ /* Check the results of thread-local storage.
+  */
+ int thread_local_val[ N_THREADS ];
+ int val_debugger_saw[ N_THREADS ];
+ 
+ /* Routine for each thread to run, does nothing.
+  */
+ void *spin( vp )
+     void * vp;
+ {
+     int me = (int) vp;
+     int i;
+     
+ #ifdef START_DEBUG
+     printf( "== In thread %d\n", me );
+ #endif
+ 
+     a_global++;
+ 
+     a_thread_local = 0;
+     for( i = 0; i < a_global; i++ ) {
+         a_thread_local += i;
+     }
+ 
+     thread_local_val[ me ] = a_thread_local; /* Line 67 */
+ 
+     printf( "== Thread %d, a_thread_local is %d\n",
+             (int) vp, a_thread_local );
+ 
+    if( wait_here ) {
+        /* Extend life of thread to extend life of thread-local var.
+         * This makes life easier for human debugging (though you'd
+         * probably want to make the delay longer).
+         */
+      /*sleep( 5 );*/
+    }
+ }
+ 
+ void
+ do_pass( pass )
+     int pass;
+ {
+     int i;
+     pthread_t t[ N_THREADS ];
+     int err;
+ 
+     for( i = 0; i < N_THREADS; i++) {
+         thread_local_val[i] = 0;
+         val_debugger_saw[i] = 0;
+     }
+    
+     /* Start N_THREADS threads, then join them so
+      * that they are terminated.
+      */
+     for( i = 0; i < N_THREADS; i++ ) {
+         err = pthread_create( &t[i], NULL, spin, (void *)i );
+         if( err != 0 ) {
+             printf( "== Start/stop, error in thread %d create\n", i );
+         }
+     }
+ 
+     for( i = 0; i < N_THREADS; i++ ) {
+         err = pthread_join(t[i], NULL );    /* Line 105 */
+         if( err != 0 ) {                    /* Line 106 */
+             printf( "== Start/stop, error in thread %d join\n", i );
+         }
+     }
+ 
+     i = 10;  /* Line 111.  Null line for setting bpts on. */
+ 
+ /*#ifdef START_DEBUG*/
+     for( i = 0; i < N_THREADS; i++) {
+         printf( "   Local in thread %d was %d, debugger saw %d\n",
+                  i, thread_local_val[i], val_debugger_saw[i] );
+     }
+     printf( "== Pass %d done\n", pass );
+ /*#endif*/
+    
+ }
+ 
+ void
+ do_it()
+ {
+     /* We want to start some threads and then
+      * end them, and then do it again and again
+      */
+     int i;
+     int dummy;
+     
+     for( i = 0; i < OUTER_LOOP_COUNT; i++ ) {
+         do_pass( i );
+         dummy = i;      /* Line 134, null line for setting bps on */
+     }
+ }
+ 
+ main( argc, argv )
+ int    argc;
+ char **argv;
+ {
+    wait_here = FALSE;
+    if((argc > 1) && (0 != argv )) {
+        if( 1 == atoi( argv[1] ) )
+            wait_here = TRUE;
+     }
+ 
+ #ifdef START_DEBUG 
+     printf( "== Test starting\n" );
+ #endif
+ 
+     do_it();
+     
+ #ifdef START_DEBUG
+     printf( "== Test done\n" );
+ #endif
+ 
+     return(0);
+ }
+ 
+ /* EndSourceFile */
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/start-stop.exp gdb/testsuite/gdb.threads/start-stop.exp
*** ../gdb-19990719/gdb/testsuite/gdb.threads/start-stop.exp	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/start-stop.exp	Thu Jul 22 17:50:39 1999
***************
*** 0 ****
--- 1,373 ----
+ # start-stop.exp -- Expect script to test a threaded pgm which has terminating threads
+ # Copyright (C) 1992 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@prep.ai.mit.edu
+ 
+ # Comment out for now, since this test is (sometimes?) hanging on 11.0
+ #
+ # return 0
+ 
+ if $tracelevel then {
+     strace $tracelevel
+ }
+ 
+ if { ![istarget "hppa*-*-hpux11.*"] } {
+     verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
+     return 0
+ }
+ 
+ set testfile start-stop
+ set srcfile ${srcdir}/${subdir}/${testfile}.c
+ set binfile ${objdir}/${subdir}/${testfile}
+ 
+ if [get_compiler_info ${binfile}] {
+     return -1
+ }
+ 
+ # To build the executable we need to link against the thread library.
+ #
+ if { $hp_cc_compiler } {
+     set additional_flags "additional_flags=-Ae"
+ } else {
+     set additional_flags ""
+ }
+ 
+ if  { [gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}" executable [list debug $additional_flags ldflags=-lpthread]] != "" } {
+      gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ 
+ # Thread stuff is _slow_; prepare for long waits.
+ #
+ # Further, this test has some "null" lines designed
+ # to consume output from gdb that was too late to be
+ # matched (sequence is "gdb_test" sends; timeout and
+ # on to next send; result finally comes in; mismatch).
+ #
+ # The null command is 'gdb_test "p \$pc" ".*" ""'
+ # NOTE: this command undoes any up/down stuff!
+ #
+ proc pre_timeout {} {
+     global timeout
+ 
+     set timeout [expr "$timeout + 100"]
+ }
+ 
+ proc post_timeout {} {
+     global timeout
+     global oldtimeout
+ 
+     set timeout $oldtimeout
+     gdb_test "p \$pc" ".*" ""
+ }
+ 
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ 
+ gdb_load ${binfile}
+ if ![runto_main] then {
+    fail "Can't run to main"
+    return 0
+ }
+ 
+ set oldtimeout $timeout
+ #set timeout [expr "$timeout + 200"]
+ set oldverbose $verbose
+ #set verbose 40
+ 
+ gdb_test "b do_pass" ".*" "set do_pass bp"
+ gdb_test "c" ".*Breakpoint.*do_pass.*" "run to do_pass"
+ 
+ # Should be only one thread.
+ #
+ pre_timeout
+ send_gdb "info thread\n"
+ gdb_expect {
+     -re ".*2 process.*$gdb_prompt $" { fail "Old code for 'thread.c'" }
+     -re ".*2 system thread.*1 sys.*$gdb_prompt $" { fail "Too many threads" }
+     -re ".*1 system thread.*$gdb_prompt $" { pass "Just one thread" }
+     -re ".*$gdb_prompt $" { fail "no thread info" }
+     timeout { fail "timeout on info thread 1" }
+ }
+ post_timeout
+ 
+ # Run to a point after the thread creates (105 is just
+ # before the first join).
+ #
+ # The "== Thread" stuff is output from the computing threads.
+ #
+ gdb_test "b 105" ".*Breakpoint.*" "set 105 bp"
+ 
+ pre_timeout
+ send_gdb "c\n"
+ gdb_expect {
+     -re ".*== Thread.*== Thread.*== Thread.*105.*$gdb_prompt $" {
+         set threads_exist 0
+         pass "new threads created and ended - 1st case"
+     }
+     -re ".*== Thread.*== Thread.*105.*$gdb_prompt $" {
+         set threads_exist 1
+         pass "new threads created and ended - 2nd case"
+     }
+     -re ".*== Thread.*.*105.*$gdb_prompt $" {
+         set threads_exist 2
+         pass "new threads created and ended - 3rd case"
+     }
+     -re ".*New thread.*New th.*New th.*105.*$gdb_prompt $" { 
+         set threads_exist 3
+         pass "new threads created" 
+     }
+     -re ".*Breakpoint.*105.*$gdb_prompt $" {
+         set threads_exist 0
+         fail "didn't see any threads" 
+     }
+     -re ".*$gdb_prompt $" {
+         set threads_exist 0
+         fail "didn't even hit bp"
+     }
+     timeout { 
+         set threads_exist -1 
+         fail "timeout on continue" 
+     }
+ }
+ 
+ gdb_test "cle"  ".*Deleted.*" "del bp at 105"
+ 
+ # Check that threads are being consumed at the join call.
+ # We expect to join three times.  If we ever see the bp at
+ # 111, we've gone too far.
+ #
+ gdb_test "b 106" ".*Breakpoint.*106.*" "set bp at 106"
+ gdb_test "b 111" ".*Breakpoint.*111.*" "set bp at 111"
+ 
+ # This one is sure: we're already in the loop.
+ #
+ #gdb_test "c"    ".*Breakpoint.*106.*" "hit bp at 106 1st time, 2 left"
+ send_gdb "c\n"
+ gdb_expect {
+     -re ".*== Thread.*== Thread.*== Thread.*Breakpoint.*106.*$gdb_prompt $" {
+         set threads_exist [expr "$threads_exist - 3"]
+         pass "hit bp at 106 1st time, 2 left - 1st case"
+     }
+     -re ".*== Thread.*== Thread.*Breakpoint.*106.*$gdb_prompt $" {
+         set threads_exist [expr "$threads_exist - 2"]
+         pass "hit bp at 106 1st time, 2 left - 2nd case"
+     }
+     -re ".*== Thread.*.*Breakpoint.*106.*$gdb_prompt $" {
+         set threads_exist [expr "$threads_exist - 1"]
+         pass "hit bp at 106 1st time, 2 left - 3rd case"
+     }
+     -re ".*Breakpoint.*106.*$gdb_prompt $" {
+         pass "hit bp at 106 1st time, 2 left"
+     }
+     -re ".*$gdb_prompt $" { fail "hit bp at 106 1st time, 2 left" }
+     timeout { fail "timeout on hit bp at 106 1st time, 2 left" }
+ }
+ 
+ # Look at the threads again.  We expect that some of
+ # the threads may have already finished execution.
+ #
+ send_gdb "info thread\n" 
+ gdb_expect {
+     -re ".*system.*system.*system.*system.*thread.*$gdb_prompt $" { set seen_threads 3 }
+     -re ".*system.*system.*system.*thread.*$gdb_prompt $"    { set seen_threads 2 }
+     -re ".*system.*system.*thread.*$gdb_prompt $"            { set seen_threads 1 }
+     -re ".*system.*thread.*$gdb_prompt $"                    { set seen_threads 0 }
+     -re ".*$gdb_prompt $"                                    { set seen_threads 0 }
+     timeout          { 
+         set seen_threads -10
+         fail "timeout on second info thread" 
+     }
+ }
+ post_timeout
+ 
+ if { $seen_threads == $threads_exist } {
+     pass "saw all threads that existed"
+ } else {
+     if { $seen_threads > $threads_exist } {
+         fail "may have seen threads ($threads_exist vs $seen_threads) that didn't finish exiting yet"
+     } else {
+         fail "didn't see live threads ($threads_exist vs $seen_threads)"
+     }
+ }
+ 
+ # Did we go around the loop again?
+ #
+ send_gdb "c\n"
+ gdb_expect {
+     -re ".*Breakpoint.*111.*" { 
+         fail "didn't join right 1" 
+         gdb_test "cle" ".*"
+     }
+     -re ".*Breakpoint.*106.*" { 
+         pass "hit bp at 106 2nd time, 1 left" 
+         send_gdb "c\n" 
+         gdb_expect {
+             -re ".*Breakpoint.*111.*" { 
+                  fail "didn't join right 2" 
+                  gdb_test "cle" ".*"
+             }
+             -re ".*Breakpoint.*106.*" { 
+                  pass "hit bp at 106 3rd time, 0 left"
+                  gdb_test "cle" ".*"
+                  gdb_test "c" ".*Breakpoint.*111.*"
+                  gdb_test "cle" ".*"
+             }
+             timeout { fail "timeout going around the loop"}
+         }
+     }
+     timeout { fail "timeout getting to 106"}
+ }
+ 
+ # Should only be one thread now.
+ #
+ pre_timeout
+ send_gdb "info thread\n"
+ gdb_expect {
+     -re ".*2 system thread.*1 sys.*$gdb_prompt $" { fail "Too many threads" }
+     -re ".*1 system th.*$gdb_prompt $"            { pass "Just one thread"  }
+     -re ".*$gdb_prompt $"     { pass "One thread shown as no threads, ok" }
+     timeout               { fail "timeout third info thread" }
+ }
+ post_timeout
+ 
+ #============================= Begin pass 2 ===========
+ #
+ # Ok, go around again
+ #
+ gdb_test "c" ".*Breakpoint.*do_pass.*" "hit do_pass bp again 2"
+ gdb_test "b 105" ".*Breakpoint.*" "set 105 bp 2"
+ 
+ pre_timeout
+ send_gdb "c\n"
+ gdb_expect {
+     -re ".*== Thread.*== Thread.*== Thread.*$gdb_prompt $" {
+         set threads_exist 0
+         pass "new threads created and ended 2 - 1st case"
+     }
+     -re ".*== Thread.*== Thread.*== Thread.*" {
+         pass "new threads created and ended 2 - variant on 1st case"
+    }
+     -re ".*== Thread.*== Thread.*$gdb_prompt $" {
+         set threads_exist 1
+         pass "new threads created and ended 2 - 2nd case"
+     }
+     -re ".*== Thread.*$gdb_prompt $" {
+         set threads_exist 2
+         pass "new threads created and ended 2 - 3rd case"
+     }
+     -re ".*New system thread.*New sys.*New.*105.*$gdb_prompt $" { 
+         set threads_exist 3
+         pass "new threads created 2"
+     }
+     timeout { 
+         set threads_exist -1 
+         fail "timeout on continue 2" 
+     }
+ }
+ 
+ # Look at the threads again.  We expect that some of
+ # the threads may have already finished execution.
+ #
+ send_gdb "info thread\n"
+ gdb_expect {
+     -re ".*4 .*3 .*2 .* 1.*thread.*$gdb_prompt $" { set seen_threads 3 }
+     -re ".*3 .*2 .* 1.*thread.*$gdb_prompt $"    { set seen_threads 2 }
+     -re ".*2 .* 1.*thread.*$gdb_prompt $"       { set seen_threads 1 }
+     -re ".* 1.*thread.*$gdb_prompt $"          { set seen_threads 0 }
+     -re ".*$gdb_prompt $"                      { set seen_threads 0 }
+     timeout          { 
+         set seen_threads -10
+         fail "timeout on second info thread 2" 
+     }
+ }
+ post_timeout
+ 
+ if { $seen_threads == $threads_exist } {
+     pass "saw all threads that existed 2"
+ } else {
+     if { $seen_threads > $threads_exist } {
+         fail "may have seen threads ($threads_exist vs $seen_threads) that didn't finish exiting yet 2"
+     } else {
+         fail "didn't see live threads 2 ($threads_exist vs $seen_threads)"
+     }
+ }
+ 
+ gdb_test "cle"  ".*Deleted.*" "del bp at 105 2"
+ 
+ # Check that threads are being consumed at the join call.
+ # We expect to join three times.  If we ever see the bp at
+ # 111, we've gone too far.
+ #
+ gdb_test "b 106" ".*Breakpoint.*106.*" "set bp at 106 2"
+ gdb_test "b 111" ".*Breakpoint.*111.*" "set bp at 111 2"
+ 
+ # This one is sure: we're already in the loop.
+ #
+ gdb_test "c"  ".*Breakpoint.*106.*" "hit bp at 106 1st time, 2 left 2"
+ 
+ # Did we go around the loop again?
+ #
+ send_gdb "c\n"
+ gdb_expect {
+     -re ".*Breakpoint.*111.*" { 
+         fail "didn't join right 1, pass 2" 
+         gdb_test "cle" ".*"
+     }
+     -re ".*Breakpoint.*106.*" { 
+         pass "hit bp at 106 2nd time, 1 left, pass 2" 
+         send_gdb "c\n" 
+         gdb_expect {
+             -re ".*Breakpoint.*111.*" { 
+                  fail "didn't join right 2, pass 2" 
+                  gdb_test "cle" ".*"
+             }
+             -re ".*Breakpoint.*106.*" { 
+                  pass "hit bp at 106 3rd time, 0 left, pass 2"
+                  gdb_test "cle" ".*"
+                  gdb_test "c" ".*Breakpoint.*111.*"
+                  gdb_test "cle" ".*"
+             }
+             timeout { fail "timeout going around loop, pass 2"}
+         }
+     }
+     timeout { fail "timeout continue to 106, pass 2"}
+ }
+ 
+ # Should only be one thread now.
+ #
+ pre_timeout
+ send_gdb "info thread\n"
+ gdb_expect {
+     -re ".*2 system thread.*1 sys.*$gdb_prompt $" { fail "Too many threads, pass 2" }
+     -re ".*1 system thread.*$gdb_prompt $" { pass "Just one thread, pass 2" }
+     -re ".*$gdb_prompt $" { pass "One thread shown as no threads, ok, pass 2" }
+     timeout { fail "timeout last info thread, pass 2" }
+ }
+ post_timeout
+ 
+ # Done!
+ #
+ gdb_exit
+ 
+ set timeout $oldtimeout
+ set verbose $oldverbose
+ 
+ # execute_anywhere "rm -f ${binfile}"
+ #
+ return 0
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/thr-lib.c gdb/testsuite/gdb.threads/thr-lib.c
*** ../gdb-19990719/gdb/testsuite/gdb.threads/thr-lib.c	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/thr-lib.c	Thu Jul 22 17:50:39 1999
***************
*** 0 ****
--- 1,79 ----
+ /* Thread local in a library.
+ */
+ #include "thr-lib.h"
+ /*
+  *     #define NTHREADS    4
+  *     #define NUM_ELEMS  12
+  */
+ 
+ extern void* adder( void * );
+ 
+ pthread_mutex_t mutex; /* mutex for protecting global data total */
+ 
+ int numbers[NUM_ELEMS] = {5, 4, 3, 2, 1, 6, 7, 8, 9, 10, 12, 11};
+ int total = 0;
+ 
+ int debugger_saw[NTHREADS][ELEMS_PER_THREAD]; /* [4][3] */
+ int the_code_saw[NTHREADS][ELEMS_PER_THREAD];
+ 
+ int get_number(i)
+ int i;
+ {
+    /* sleep to force context switch to another thread in non-MP system 
+     * so that TLS symbols are used by multiple threads concurrently
+     * in some way. 
+     */
+    sleep(1); 
+    return numbers[i];
+ }
+ 
+ main()
+ {
+    pthread_t	thread[NTHREADS];
+    void 	*status;
+    int 		i, j, ret;
+ 
+    printf("== Thread: Test started\n");
+ 
+    for( i = 0; i < NTHREADS; i++ ) {
+        for( j = 0; j < ELEMS_PER_THREAD; j++ ) {
+            debugger_saw[i][j] = 0;
+            the_code_saw[i][j] = 0;
+        }
+    }
+    
+    ret = pthread_mutex_init(&mutex, NULL);
+    if (ret != 0) {
+       printf("== Thread: pthread_mutex_init() error: %d\n", ret);
+       exit(1);
+    }
+ 
+    for (i=0; i < NTHREADS; i++) {
+       ret = pthread_create( &thread[i],
+                             NULL,
+                             adder,
+                             (void *) i);
+       if (ret != 0) {
+          printf("== Thread: pthread_create() error: %d\n", ret);
+          exit(1);
+       }
+       printf("== Thread: thread %d created\n", i);
+    }
+    
+    for (i=0; i < NTHREADS; i++) {
+       pthread_join( thread[i], &status);
+    }
+ 
+    printf("== Thread: total = %d\n", total); /* Expect "78" */
+ 
+    for( i = 0; i < NTHREADS; i++ ) {
+        for( j = 0; j < ELEMS_PER_THREAD; j++ ) {
+            printf( "== Thread: the debugger saw %d, the program saw %d\n",
+                    debugger_saw[i][j],
+                    the_code_saw[i][j] );
+        }
+    }
+ 
+    printf("== Thread: Test ended\n");
+    exit(0);
+ }
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/thr-lib.exp gdb/testsuite/gdb.threads/thr-lib.exp
*** ../gdb-19990719/gdb/testsuite/gdb.threads/thr-lib.exp	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/thr-lib.exp	Thu Jul 22 17:50:39 1999
***************
*** 0 ****
--- 1,253 ----
+ # thr-lib.exp -- Expect script to test thread-local storage in lib
+ # Copyright (C) 1992 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@prep.ai.mit.edu
+ 
+ if $tracelevel then {
+     strace $tracelevel
+ }
+ 
+ if { ![istarget "hppa*-*-hpux11.*"] } {
+     verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
+     return 0
+ }
+ 
+ set testfile thr-lib
+ set srcfile ${srcdir}/${subdir}/${testfile}.c
+ set libsrc  ${srcdir}/${subdir}/${testfile}lib.c
+ set mainobj ${objdir}/${testfile}.o
+ set libobj  ${objdir}/${testfile}lib.o
+ set libsl   ${objdir}/${subdir}/${testfile}lib.sl
+ set binfile ${objdir}/${subdir}/${testfile}
+ 
+ # To build the executable we need to do this:
+ #
+ #   cc -c -Aa -g -D_HPUX_SOURCE -D_REENTRANT +DA1.0 ./gdb.hp/thr-lib.c
+ #   cc -c -Aa -g -D_HPUX_SOURCE -D_REENTRANT +DA1.0 +z ./gdb.hp/thr-liblib.c
+ #   ld -o thread_local_in_lib.lib.sl -b ./gdb.hp/thr-liblib.o
+ #   ld -a archive /opt/langtools/lib/crt0.o /opt/langtools/lib/end.o \
+ #     thr-lib.o ./gdb.hp/thr-liblib.sl \
+ #     -o thr-lib -lpthread -lc
+ #
+ if  { [gdb_compile "${srcfile}" "${mainobj}" object {debug}] != "" } {
+      gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ if  { [gdb_compile "${libsrc}" "${libobj}" object {debug additional_flags=+z}] != "" } {
+      gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ 
+ remote_exec build "ld -o ${libsl} -b ${libobj}"
+ if [istarget "hppa2.0w-*-*"] {
+     remote_exec build "ld -a archive /opt/langtools/lib/pa20_64/crt0.o /opt/langtools/lib/pa20_64/end.o ${mainobj} ${libsl} -lpthread -lc -o ${binfile}"
+ } else {
+     remote_exec build "ld -a archive /opt/langtools/lib/crt0.o /opt/langtools/lib/end.o ${mainobj} ${libsl} -lpthread -lc -o ${binfile}"
+ }
+ 
+ # Thread stuff is _slow_; prepare for long waits.
+ #
+ # Further, this test has some "null" lines designed
+ # to consume output from gdb that was too late to be
+ # matched (sequence is "gdb_test" sends; timeout and
+ # on to next send; result finally comes in; mismatch).
+ #
+ # The null command is 'gdb_test "p \$pc" ".*" ""'
+ # NOTE: this command undoes any up/down stuff!
+ #
+ proc pre_timeout {} {
+     global timeout
+ 
+     set timeout [expr "$timeout + 100"]
+ }
+ 
+ proc post_timeout {} {
+     global timeout
+     global oldtimeout
+ 
+     set timeout $oldtimeout
+     gdb_test "p \$pc" ".*" ""
+ }
+ 
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ 
+ set oldtimeout $timeout
+ # RM: Set timeout to a lower value so this test doesn't run forever
+ set timeout [expr "30"]
+ set oldverbose $verbose
+ 
+ gdb_load ${binfile}
+ 
+ # Here we go: test various things.
+ #
+ gdb_test "b adder" ".*Breakpoint.*deferred.*adder.*Breakpoint deferred until a shared library containing.*" "shared loc, needs to run"
+ gdb_test "b main" ".*"
+ gdb_test "run"    ".*Breakpoint 2, main.*"
+ 
+ # Set a bp to inspect the results
+ #
+ gdb_test "b 67" ".*Breakpoint 3.*"
+ 
+ # get to a point where we can set the collection breakpoint.
+ #
+ gdb_test "tb adder" ".*Breakpoint 4.*line 47.*"  "set bp in shared lib"
+ gdb_test "c"       ".*Switched to.*adder.*"     "run to shared lib rtn"
+ 
+ # Check locations of things
+ #
+ gdb_test "i ad sum" ".*Symbol \"sum\" is a thread-local variable.*offset.*from the thread base register mpsfu_high.*" "find sum"
+ gdb_test "i add x"      ".*Symbol \"x\" is a thread-local variable.*"  "find x"
+ 
+ # Set a breakpoint later on in "adder" and
+ # collect the thread local's value.  
+ #
+ gdb_test "b 61" ".*Breakpoint 5.*61.*"   "Set collection bp"
+ 
+ # extra check for grins, expect to hit "adder" in thread 2 first
+ # but could be wrong...
+ #
+ gdb_test "info thread" ".*\\\* 2.*thread.*thread.*" "two threads"
+ 
+ # Can't use "gdb_test", as it uses "$gdb_prompt $" in
+ # testing the result.  Our new prompt is ">", with
+ # no trailing space, so we can't do this just by
+ # changing "prompt". 
+ #
+ # Anyway, I couldn't get expect to see the ">" prompt,
+ # during the command addition, so I just punted.
+ # _You_ are welcome to try, if you want!
+ #
+ send_gdb "commands 5\n"
+ gdb_expect {
+     -re "(.*Type commands.*\"end\"\.\r\n\>)" {
+         pass "start commands"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "start commands"
+     }
+ }
+ 
+ # Assume we're in commands-input mode.  (Self-debug stuff turned off)
+ #
+ send_gdb "silent\n"
+ #send_gdb "p id\n"
+ #send_gdb "p j\n"
+ #send_gdb "p x\[j\]\n"
+ send_gdb "set debugger_saw\[id\]\[j\] = x\[j\]\n"
+ send_gdb "continue\n"
+ send_gdb "end\n"
+ 
+ gdb_expect {
+     -re ".*set.*cont.*$gdb_prompt $" {
+         pass "add commands"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "add commands"
+     }
+ }
+ 
+ # Check out of paranoia.
+ #
+ send_gdb "info break 5\n"
+ gdb_expect {
+     -re ".*breakpoint.*set debugger_saw.*continue.*$gdb_prompt $" {
+         pass "Commands added"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "Commands not added."
+     }
+ }
+ 
+ # When we hit the breakpoint for which we have commands set, 
+ # gdb is going to dump core because there is a continue command embedded
+ # in the commands set and this is due to DTS 10120CLLbs.  When this
+ # DTS is fixed, we should be able to continue with the rest of the test.
+ 
+ setup_xfail "hppa*-*-*" 10120CLLbs
+ send_gdb " \n"
+ gdb_expect {
+     -re ".*$gdb_prompt $" { fail "About to dump core -- returning"; return  }
+ }
+ 
+ # We now expect to run through the whole application
+ # Since this'll run for while, set a generous timeout.
+ #
+ #RM: Keep low timeout here too
+ #set timeout [expr "$timeout + 30"]
+ send_gdb "c\n"
+ gdb_expect {
+     -re ".*Program exited normally.*$gdb_prompt $" {
+         fail "program runaway"
+     }
+     -re ".*Breakpoint 2.*67.*$gdb_prompt $" {
+         pass "get to end"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "No progress?"
+     }
+     timeout { fail "timeout" }
+ }
+ #RM: Still want a low timeout
+ #set timeout $oldtimeout
+ 
+ gdb_test "p debugger_saw" ".*5, 1, 9.*4, 6, 10.*3, 7, 12.*2, 8, 11.*" "check results"
+ 
+ # Often only one misses; let's get detailed!
+ #
+ gdb_test "p debugger_saw\[0\]\[0\]" ".*= 5.*" "1"
+ gdb_test "p debugger_saw\[0\]\[1\]" ".*= 1.*" "2"
+ gdb_test "p debugger_saw\[0\]\[2\]" ".*= 9.*" "3"
+ gdb_test "p debugger_saw\[1\]\[0\]" ".*= 4.*" "4"
+ gdb_test "p debugger_saw\[1\]\[1\]" ".*= 6.*" "5"
+ gdb_test "p debugger_saw\[1\]\[2\]" ".*= 10.*" "6"
+ gdb_test "p debugger_saw\[2\]\[0\]" ".*= 3.*" "7"
+ gdb_test "p debugger_saw\[2\]\[1\]" ".*= 7.*" "8"
+ gdb_test "p debugger_saw\[2\]\[2\]" ".*= 12.*" "9"
+ gdb_test "p debugger_saw\[3\]\[0\]" ".*= 2.*" "10"
+ gdb_test "p debugger_saw\[3\]\[1\]" ".*= 8.*" "11"
+ gdb_test "p debugger_saw\[3\]\[2\]" ".*= 11.*" "12"
+ 
+ send_gdb "i th\n" 
+ gdb_expect {
+     -re ".* 1.*system thread.* 2.*system thread.*$gdb_prompt $" {
+         fail "Too many threads left"
+     }
+     -re ".*\\\* 1.*system thread.*main.*$gdb_prompt $" {
+         pass "Expect only base thread"
+     }
+     -re ".*No stack.*$gdb_prompt $" {
+         fail "runaway"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "Hunh?"
+     }
+     timeout { fail "timeout" }
+ }
+ 
+ gdb_test "c" ".*exited normally.*" "run to completion"
+ 
+ # Done!
+ #
+ gdb_exit
+ 
+ set timeout $oldtimeout
+ set verbose $oldverbose
+ 
+ # execute_anywhere "rm -f ${binfile}"
+ #
+ return 0
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/thr-lib.h gdb/testsuite/gdb.threads/thr-lib.h
*** ../gdb-19990719/gdb/testsuite/gdb.threads/thr-lib.h	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/thr-lib.h	Thu Jul 22 17:50:40 1999
***************
*** 0 ****
--- 1,7 ----
+ #include <stdio.h>
+ #include <pthread.h>
+ 
+ #define NTHREADS 	 4
+ #define NUM_ELEMS	12
+ 
+ #define ELEMS_PER_THREAD (NUM_ELEMS/NTHREADS)
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/thr-liblib.c gdb/testsuite/gdb.threads/thr-liblib.c
*** ../gdb-19990719/gdb/testsuite/gdb.threads/thr-liblib.c	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/thr-liblib.c	Thu Jul 22 17:50:40 1999
***************
*** 0 ****
--- 1,92 ----
+ #include <stdio.h>
+ 
+ /* Library code for thread local in lib test.
+ */
+ #include "thr-lib.h"
+ 
+ extern pthread_mutex_t mutex;
+ extern int get_number();
+ extern int total;
+ extern int the_code_saw[NTHREADS][ELEMS_PER_THREAD];
+ 
+ /* The debugger should see this without a declaration.
+  *
+  * extern int debugger_saw[NTHREADS][ELEMS_PER_THREAD]; 
+  */
+ 
+ /* The actual thread locals.
+  */
+ __thread int sum;
+ __thread int x[ ELEMS_PER_THREAD ]; /* [3] */
+ 
+ void sumup()
+ {
+    int j;
+ 
+    sum = 0;
+    for (j = 0; j < ELEMS_PER_THREAD; j++) {
+       sum += x[j];
+    }
+ 
+    if( sum == x[0] )
+        /* It won't be "==", but this lets us set a breakpoint
+         * and look at the thread-local storage.
+         */
+        sum++;
+ 
+    x[0] = x[2];  /* Another no-op for debugger use */
+ }
+ 
+ void *adder( vid )
+    void * vid;
+ {
+    int id;
+    int i, j;
+    int ret;
+ 
+    id = (int) vid;
+    
+    /* printf( "== Thread: Welcome to adder %d\n", id ); */
+ 
+    for (j = 0; j < ELEMS_PER_THREAD; j++) {
+       x[j] = 0;
+    }
+ 
+    for (i = id, j = 0; i < NUM_ELEMS; i += NTHREADS, j++ ) {
+ 
+    /*   printf( "== Thread: id %d, i %d, j %d\n", id, i, j );
+       fflush( stdout ); */
+     
+       x[j] = get_number(i); /* {0,1,2,3} +0, +4, +8 */
+ 
+       /* Record for posterity; the debugger will gather
+        * the same data here, using "x[j]".
+        */
+       the_code_saw[ id ][ j ] = x[j];   
+ 
+    /*   printf( "== Thread %d, sample %d, val %d, i %d\n", id, j, x[j],i );
+       fflush( stdout ); */
+    }
+ 
+    sumup();
+    /* printf("== Thread: adder %d contributes total %d\n", id, sum); */
+ 
+    /* protect global data */
+    ret = pthread_mutex_lock(&mutex);
+    if (ret != 0) {
+       printf("== Thread: pthread_mutex_lock() error: %d\n", ret);
+       exit(1);
+    }
+ 
+    total += sum;
+ 
+    ret = pthread_mutex_unlock(&mutex);
+    if (ret != 0) {
+       printf("== Thread: pthread_mutex_unlock() error: %d\n", ret);
+       exit(1);
+    }
+ 
+    if( NTHREADS != 4 || ELEMS_PER_THREAD != 3 || NUM_ELEMS != 12 ) {
+       printf( "** ERROR in test code **\n" );
+    }
+ }
diff -r -c -N ../gdb-19990719/gdb/testsuite/gdb.threads/thr-stg.exp gdb/testsuite/gdb.threads/thr-stg.exp
*** ../gdb-19990719/gdb/testsuite/gdb.threads/thr-stg.exp	Wed Dec 31 16:00:00 1969
--- gdb/testsuite/gdb.threads/thr-stg.exp	Thu Jul 22 17:50:40 1999
***************
*** 0 ****
--- 1,245 ----
+ # thread_local_stg.exp -- Expect script to test thread-local storage
+ # Copyright (C) 1992 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@prep.ai.mit.edu
+ 
+ if $tracelevel then {
+     strace $tracelevel
+ }
+ 
+ if { ![istarget "hppa*-*-hpux11.*"] } {
+     verbose "HPUX thread test ignored for non-hppa or pre-HP/UX-10.30 targets."
+     return 0
+ }
+ 
+ set testfile start-stop
+ set srcfile ${srcdir}/${subdir}/${testfile}.c
+ set binfile ${objdir}/${subdir}/${testfile}
+ 
+ if [get_compiler_info ${binfile}] {
+     return -1
+ }
+ 
+ # To build the executable we need to link against the thread library.
+ #
+ if { $hp_cc_compiler } {
+     set additional_flags "additional_flags=-Ae"
+ } else {
+     set additional_flags ""
+ }
+ if { [gdb_compile "${srcdir}/${subdir}/${testfile}.c" "${binfile}" executable [list debug $additional_flags ldflags=-lpthread]] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+ }
+ 
+ # Thread stuff is _slow_; prepare for long waits.
+ #
+ # Further, this test has some "null" lines designed
+ # to consume output from gdb that was too late to be
+ # matched (sequence is "gdb_test" sends; timeout and
+ # on to next send; result finally comes in; mismatch).
+ #
+ # The null command is 'gdb_test "p \$pc" ".*" ""'
+ # NOTE: this command undoes any up/down stuff!
+ #
+ proc pre_timeout {} {
+     global timeout
+ 
+     set timeout [expr "$timeout + 100"]
+ }
+ 
+ proc post_timeout {} {
+     global timeout
+     global oldtimeout
+ 
+     set timeout $oldtimeout
+     gdb_test "p \$pc" ".*" ""
+ }
+ 
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ 
+ gdb_load ${binfile}
+ if ![runto_main] then {
+    fail "Can't run to main"
+    return 0
+ }
+ 
+ set oldtimeout $timeout
+ #set timeout [expr "$timeout + 200"]
+ set oldverbose $verbose
+ #set verbose 40
+ 
+ gdb_test "b do_pass" ".*"  "set do_pass bp"
+ gdb_test "c" ".*do_pass.*" "run to do_pass"
+ gdb_test "cle" ".*"
+ 
+ # Set a breakpoint at the "spin" routine and
+ # collect the thread local's value.  
+ #
+ gdb_test "b 67" ".*Breakpoint 3.*67.*"   "Set bp"
+ 
+ # Can't use "gdb_test", as it uses "$gdb_prompt $" in
+ # testing the result.  Our new prompt is ">", with
+ # no trailing space, so we can't do this just by
+ # changing "prompt". 
+ #
+ # Anyway, I couldn't get expect to see the ">" prompt,
+ # during the command addition, so I just punted.
+ # _You_ are welcome to try, if you want!
+ #
+ send_gdb "commands 3\n"
+ gdb_expect {
+     -re "(.*Type commands.*\"end\"\.\r\n\>)" {
+         pass "start commands"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "start commands"
+     }
+ }
+ 
+ # Assume we're in commands-input mode.
+ #
+ send_gdb "silent\n"
+ send_gdb "set val_debugger_saw\[me\] = a_thread_local\n"
+ send_gdb "continue\n"
+ send_gdb "end\n"
+ 
+ gdb_expect {
+     -re ".*set.*cont.*$gdb_prompt $" {
+         pass "add commands"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "add commands"
+     }
+ }
+ 
+ # Check out of paranoia.
+ #
+ send_gdb "info break 3\n"
+ gdb_expect {
+     -re ".*breakpoint.*set val_debugger.*continue.*$gdb_prompt $" {
+         pass "Commands added"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "Commands not added."
+     }
+ }
+ 
+ # Set a bp to inspect the results
+ #
+ gdb_test "b 134" ".*Breakpoint 4.*"
+ 
+ # We now expect to run through a whole pass, seeing 
+ # specific results as noted below (actual gotten by
+ # running application with debugging print statements
+ # turned on.
+ #
+ # Since this'll run for while, set a generous timeout.
+ #
+ set timeout [expr "$timeout + 30"]
+ send_gdb "c\n"
+ gdb_expect {
+     -re ".*Program exited normally.*$gdb_prompt $" {
+         fail "program runaway"
+     }
+     -re ".*Pass 0 done.*Pass 1 done.*$gdb_prompt $" {
+         fail "program runaway 2"
+     }
+     -re ".*Pass 0 done.*Breakpoint 4.*134.*$gdb_prompt $" {
+         pass "get to end of first pass"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "No progress?"
+     }
+     timeout { fail "timeout" }
+ }
+ 
+ gdb_test "p val_debugger_saw" ".*0, 1, 3.*"   "first pass"
+ 
+ send_gdb "i th\n" 
+ gdb_expect {
+     -re ".* 1.*system thread.* 2.*system thread.*$gdb_prompt $" {
+         fail "Too many threads left"
+     }
+     -re ".*\\\* 1 system thread.*$gdb_prompt $" {
+         pass "Expect only base thread"
+     }
+     -re ".*No stack.*$gdb_prompt $" {
+         fail "runaway"
+     }
+     -re ".*$gdb_prompt $" {
+         fail "Hunh?"
+     }
+     timeout { fail "timeout" }
+ }
+ 
+ gdb_test "i b"  ".*4.*breakpoint.*134.*hit.*1 time.*" "Expect 134 bp to exist"
+ 
+ gdb_test "c" ".*Breakpoint 4.*134.*" "get to end of second pass"
+ gdb_test "p val_debugger_saw" ".*6, 10, 15.*" "second pass"
+ 
+ gdb_test "c" ".*Breakpoint 4.*134.*" "get to end of third pass"
+ gdb_test "p val_debugger_saw" ".*21, 28, 36.*" "third pass"
+ 
+ gdb_test "info bre 3" ".*already hit 9 times.*" "count of silent bp hits"
+ 
+ # Start over and do some "info address" stuff
+ #
+ send_gdb "d\n"
+ gdb_expect {
+    -re ".*Delete all breakpoints.*$" {
+        send_gdb "y\n"
+        gdb_expect {
+            -re ".*$gdb_prompt $" {
+                pass "del bps"
+            }
+        }
+    }
+    -re ".*$gdb_prompt $" { fail "no question" }
+ }
+ 
+ gdb_test "b spin" ".*Breakpoint 5.*"
+ 
+ send_gdb "r\n"
+ gdb_expect {
+    -re ".*Start it from the beginning.*$" {
+        send_gdb "y\n"
+        gdb_expect {
+            -re ".*$gdb_prompt $" { pass "restart" }
+        }
+    }
+    -re ".*Starting program.*$gdb_prompt $" {
+        pass "restart after previous fails"
+    }
+    -re ".*$gdb_prompt $" { fail "Can't restart" }
+ }
+ gdb_test "i ad a_global" ".*a_global.*static storage at address.*" "i ad a_global"
+ gdb_test "i add me"      ".*me.*local variable at frame offset.*"  "i ad me"
+ gdb_test "i ad a_thread_local" ".*a_thread_local.*a thread-local variable at offset.*" "i ad a_thread_local"
+ 
+ # Done!
+ #
+ gdb_exit
+ 
+ set timeout $oldtimeout
+ set verbose $oldverbose
+ 
+ # execute_anywhere "rm -f ${binfile}"
+ #
+ return 0



More information about the Gdb-patches mailing list