[prev in list] [next in list] [prev in thread] [next in thread]
List: gdb-patches
Subject: gdb.threads testsuite patch
From: guo () cup ! hp ! com (Jimmy Guo)
Date: 1999-07-22 18:52:00
Message-ID: Pine.LNX.4.10.9907221847020.2057-100000 () hpcll168 ! cup ! hp ! com
[Download RAW message or body]
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 s
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic