URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/gnu-old/gdb-7.1/gdb/testsuite/gdb.threads
- from Rev 227 to Rev 816
- ↔ Reverse comparison
Rev 227 → Rev 816
/print-threads.exp
0,0 → 1,126
# Copyright (C) 1996, 1997, 2002, 2003, 2007, 2008, 2009, 2010 |
# Free Software Foundation, Inc. |
|
# This program is free software; you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation; either version 3 of the License, or |
# (at your option) any later version. |
# |
# This program is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# GNU General Public License for more details. |
# |
# You should have received a copy of the GNU General Public License |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
# This file was written by Daniel Jacobowitz <drow@mvista.com> |
# (parts based on pthreads.exp by Fred Fish (fnf@cygnus.com). |
# |
# It tests miscellaneous actions with multiple threads, including |
# handling for thread exit. |
|
if $tracelevel then { |
strace $tracelevel |
} |
|
set prms_id 0 |
set bug_id 0 |
|
set testfile "print-threads" |
set srcfile ${testfile}.c |
set binfile ${objdir}/${subdir}/${testfile} |
|
# regexp for "horizontal" text (i.e. doesn't include newline or |
# carriage return) |
set horiz "\[^\n\r\]*" |
|
if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } { |
return -1 |
} |
|
# Now we can proceed with the real testing. |
|
# Start with a fresh gdb. |
|
gdb_exit |
gdb_start |
gdb_reinitialize_dir $srcdir/$subdir |
gdb_load ${binfile} |
|
gdb_test "set print sevenbit-strings" "" |
#gdb_test "set print address off" "" |
gdb_test "set width 0" "" |
|
# We'll need this when we send_gdb a ^C to GDB. Need to do it before we |
# run the program and gdb starts saving and restoring tty states. |
# On Ultrix, we don't need it and it is really slow (because shell_escape |
# doesn't use vfork). |
if ![istarget "*-*-ultrix*"] then { |
gdb_test "shell stty intr '^C'" "" |
} |
|
proc test_all_threads { name kill } { |
global gdb_prompt |
|
set i 0 |
set j 0 |
send_gdb "continue\n" |
gdb_expect { |
-re "Breakpoint \[0-9\]+, thread_function \\(arg=.*\\) at .*print-threads.c:\[0-9\]+.*$gdb_prompt" { |
set i [expr $i + 1] |
pass "Hit thread_function breakpoint, $i ($name)" |
send_gdb "continue\n" |
exp_continue |
} |
-re "Breakpoint \[0-9\]+, .* kill \\(.*\\) .*$gdb_prompt" { |
set j [expr $j + 1] |
if { $kill == 1 } { |
pass "Hit kill breakpoint, $j ($name)" |
} else { |
fail "Hit kill breakpoint, $j ($name) (unexpected)" |
} |
send_gdb "continue\n" |
exp_continue |
} |
-re "Program exited normally\\.\[\r\n\]+$gdb_prompt" { |
pass "program exited normally" |
if {$i == 5} { |
pass "all threads ran once ($name)" |
} else { |
fail "all threads ran once ($name) (total $i threads ran)" |
} |
} |
-re "Program received signal SIGTRAP.*(Thread \[-0-9a-fx\]* \\(zombie\\)|0x00000000 in ).*$gdb_prompt $" { |
if { $kill == 1 } { |
kfail "gdb/1265" "Running threads ($name) (zombie thread)" |
} else { |
fail "Running threads ($name) (unknown output)" |
} |
} |
-re "$gdb_prompt" { |
fail "Running threads ($name) (unknown output)" |
} |
timeout { |
fail "Running threads ($name) (timeout)" |
} |
} |
} |
|
runto_main |
gdb_test "break thread_function" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*print-threads.c, line \[0-9\]*\\." |
gdb_test "set var slow = 0" "" |
test_all_threads "fast" 0 |
|
runto_main |
gdb_test "break thread_function" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*print-threads.c, line \[0-9\]*\\." "break thread_function (2)" |
gdb_test "set var slow = 1" "" |
test_all_threads "slow" 0 |
|
runto_main |
gdb_test "break thread_function" "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*print-threads.c, line \[0-9\]*\\." "break thread_function (3)" |
gdb_test "set var slow = 1" "" "set var slow = 1 (2)" |
gdb_breakpoint "kill" |
test_all_threads "slow with kill breakpoint" 1 |
|
return 0 |
/threxit-hop-specific.c
0,0 → 1,48
/* This testcase is part of GDB, the GNU debugger. |
|
Copyright 2009, 2010 Free Software Foundation, Inc. |
|
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 3 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
|
#include <pthread.h> |
#include <unistd.h> |
#include <stdlib.h> |
|
void * |
thread_function (void *arg) |
{ |
/* We'll next over this, with scheduler-locking off. */ |
pthread_exit (NULL); |
} |
|
void |
hop_me (void) |
{ |
} |
|
int |
main (int argc, char **argv) |
{ |
pthread_t thread; |
|
pthread_create (&thread, NULL, thread_function, NULL); |
pthread_join (thread, NULL); /* wait for exit */ |
|
/* The main thread should be able to hop over the breakpoint set |
here... */ |
hop_me (); /* set thread specific breakpoint here */ |
|
/* ... and reach here. */ |
exit (0); /* set exit breakpoint here */ |
} |
threxit-hop-specific.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: linux-dp.c
===================================================================
--- linux-dp.c (nonexistent)
+++ linux-dp.c (revision 816)
@@ -0,0 +1,207 @@
+/* linux-dp.c --- dining philosophers, on LinuxThreads
+ Jim Blandy --- March 1999 */
+
+/* It's okay to edit this file and shift line numbers around. The
+ tests use gdb_get_line_number to find source locations, so they
+ don't depend on having certain line numbers in certain places. */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* The number of philosophers at the table. */
+int num_philosophers;
+
+/* Mutex ordering -
+ If you want to lock a mutex M, all the mutexes you have locked
+ already must appear before M on this list.
+
+ fork_mutex[0]
+ fork_mutex[1]
+ ...
+ fork_mutex[num_philosophers - 1]
+ stdout_mutex
+ random_mutex
+*/
+
+/* You must hold this mutex while writing to stdout. */
+pthread_mutex_t stdout_mutex;
+
+/* You must hold this mutex while calling any of the random number
+ generation routines. */
+pthread_mutex_t random_mutex;
+
+/* array of mutexes, one for each fork; fork_mutex[i] is to the left
+ of philosopher i. A philosopher is holding fork i iff his/her
+ thread has locked fork_mutex[i]. */
+pthread_mutex_t *fork_mutex;
+
+/* array of threads, one representing each philosopher. */
+pthread_t *philosophers;
+
+void *
+xmalloc (size_t n)
+{
+ void *p = malloc (n);
+
+ if (! p)
+ {
+ fprintf (stderr, "out of memory\n");
+ exit (2);
+ }
+
+ return p;
+}
+
+void
+shared_printf (char *format, ...)
+{
+ va_list ap;
+
+ va_start (ap, format);
+ pthread_mutex_lock (&stdout_mutex);
+ vprintf (format, ap);
+ pthread_mutex_unlock (&stdout_mutex);
+ va_end (ap);
+}
+
+int
+shared_random ()
+{
+ static unsigned int seed;
+ int result;
+
+ pthread_mutex_lock (&random_mutex);
+ result = rand_r (&seed);
+ pthread_mutex_unlock (&random_mutex);
+ return result;
+}
+
+void
+my_usleep (long usecs)
+{
+ struct timeval timeout;
+
+ timeout.tv_sec = usecs / 1000000;
+ timeout.tv_usec = usecs % 1000000;
+
+ select (0, 0, 0, 0, &timeout);
+}
+
+void
+random_delay ()
+{
+ my_usleep ((shared_random () % 2000) * 100);
+}
+
+void
+print_philosopher (int n, char left, char right)
+{
+ int i;
+
+ shared_printf ("%*s%c %d %c\n", (n * 4) + 2, "", left, n, right);
+}
+
+void *
+philosopher (void *data)
+{
+ int n = * (int *) data;
+
+ print_philosopher (n, '_', '_');
+
+#if 1
+ if (n == num_philosophers - 1)
+ for (;;)
+ {
+ /* The last philosopher is different. He goes for his right
+ fork first, so there is no cycle in the mutex graph. */
+
+ /* Grab the right fork. */
+ pthread_mutex_lock (&fork_mutex[(n + 1) % num_philosophers]);
+ print_philosopher (n, '_', '!');
+ random_delay ();
+
+ /* Then grab the left fork. */
+ pthread_mutex_lock (&fork_mutex[n]);
+ print_philosopher (n, '!', '!');
+ random_delay ();
+
+ print_philosopher (n, '_', '_');
+ pthread_mutex_unlock (&fork_mutex[n]);
+ pthread_mutex_unlock (&fork_mutex[(n + 1) % num_philosophers]);
+ random_delay ();
+ }
+ else
+#endif
+ for (;;)
+ {
+ /* Grab the left fork. */
+ pthread_mutex_lock (&fork_mutex[n]);
+ print_philosopher (n, '!', '_');
+ random_delay ();
+
+ /* Then grab the right fork. */
+ pthread_mutex_lock (&fork_mutex[(n + 1) % num_philosophers]);
+ print_philosopher (n, '!', '!');
+ random_delay ();
+
+ print_philosopher (n, '_', '_');
+ pthread_mutex_unlock (&fork_mutex[n]);
+ pthread_mutex_unlock (&fork_mutex[(n + 1) % num_philosophers]);
+ random_delay ();
+ }
+
+ return (void *) 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ num_philosophers = 5;
+
+ /* Set up the mutexes. */
+ {
+ pthread_mutexattr_t ma;
+ int i;
+
+ pthread_mutexattr_init (&ma);
+ pthread_mutex_init (&stdout_mutex, &ma);
+ pthread_mutex_init (&random_mutex, &ma);
+ fork_mutex = xmalloc (num_philosophers * sizeof (fork_mutex[0]));
+ for (i = 0; i < num_philosophers; i++)
+ pthread_mutex_init (&fork_mutex[i], &ma);
+ pthread_mutexattr_destroy (&ma);
+ }
+
+ /* Set off the threads. */
+ {
+ int i;
+ int *numbers = xmalloc (num_philosophers * sizeof (*numbers));
+ pthread_attr_t ta;
+
+ philosophers = xmalloc (num_philosophers * sizeof (*philosophers));
+
+ pthread_attr_init (&ta);
+
+ for (i = 0; i < num_philosophers; i++)
+ {
+ numbers[i] = i;
+ /* linuxthreads.exp: create philosopher */
+ pthread_create (&philosophers[i], &ta, philosopher, &numbers[i]);
+ }
+
+ pthread_attr_destroy (&ta);
+ }
+
+ /* linuxthreads.exp: info threads 2 */
+ sleep (1000000);
+
+ /* Drink yourself into oblivion. */
+ for (;;)
+ sleep (1000000);
+
+ return 0;
+}
linux-dp.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: Makefile.in
===================================================================
--- Makefile.in (nonexistent)
+++ Makefile.in (revision 816)
@@ -0,0 +1,13 @@
+VPATH = @srcdir@
+srcdir = @srcdir@
+
+EXECUTABLES = pthreads
+
+all info install-info dvi install uninstall installcheck check:
+ @echo "Nothing to be done for $@..."
+
+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
Index: attachstop-mt.exp
===================================================================
--- attachstop-mt.exp (nonexistent)
+++ attachstop-mt.exp (revision 816)
@@ -0,0 +1,267 @@
+# Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This test is based on gdb.base/attach.exp with modifications by Jeff Johnston
+# and Jan Kratochvil .
+
+# This test only works on Linux
+if { ![isnative] || [is_remote host] || ![istarget *-linux*] } {
+ continue
+}
+
+set testfile "attachstop-mt"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set escapedbinfile [string_to_regexp ${objdir}/${subdir}/${testfile}]
+
+#execute_anywhere "rm -f ${binfile}"
+remote_exec build "rm -f ${binfile}"
+# For debugging this test
+#
+#log_user 1
+
+# build the test case
+#
+if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested attachstop-mt.exp
+ return -1
+}
+
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+# Start the program running and then wait for a bit, to be sure
+# that it can be attached to.
+
+set testpid [eval exec $binfile &]
+
+# No race
+sleep 2
+
+# The testcase has three threads, find some other thread TID for $testpid2.
+set tids [exec sh -c "echo /proc/$testpid/task/*"]
+regsub -all /proc/$testpid/task/ $tids {} tids
+if {$tids == "*"} {
+ unresolved "/proc/PID/task is not supported (kernel-2.4?)"
+ remote_exec build "kill -9 ${testpid}"
+ return -1
+}
+set tids [lsort -integer [split $tids]]
+if {[llength $tids] != 3 || [lindex $tids 0] != $testpid} {
+ verbose -log "Invalid TIDs <$tids> for PID $testpid"
+ fail "Invalid TIDs found"
+ remote_exec build "kill -9 ${testpid}"
+ return -1
+}
+set testpid2 [lindex $tids 2]
+
+# Initial sanity test it is normally sleeping
+set status2 /proc/${testpid}/task/${testpid2}/status
+set fileid0 [open $status2 r];
+gets $fileid0 line1;
+gets $fileid0 line2;
+close $fileid0;
+
+set test "attach0, initial sanity check of the sleeping state"
+if {[string match "*(sleeping)*" $line2]} {
+ pass $test
+} else {
+ fail $test
+}
+
+# Sttach and detach to test it will not become stopped
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set test "attach0 to sleeping"
+gdb_test_multiple "attach $testpid" "$test" {
+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
+ pass "$test"
+ }
+}
+
+gdb_test "gcore /dev/null" ".*aved corefile.*" "attach0 to sleeping gcore invocation"
+
+gdb_test "thread 2" ".*witching to thread 2 .*" "attach0 to sleeping switch thread"
+
+gdb_test "bt" ".*sleep.*func.*" "attach0 to sleeping bt"
+
+# Exit and detach the process.
+
+gdb_exit
+
+# No race
+sleep 2
+
+# Check it did not get stopped by our gdb
+set fileid1 [open $status2 r];
+gets $fileid1 line1;
+gets $fileid1 line2;
+close $fileid1;
+
+set test "attach1, post-gdb sanity check of the sleeping state - Red Hat BZ 197584"
+if {[string match "*(sleeping)*" $line2]} {
+ pass $test
+} else {
+ fail $test
+}
+
+# Stop the program
+remote_exec build "kill -s STOP ${testpid}"
+
+# No race
+sleep 2
+
+# Check it really got stopped by kill(1)
+set fileid2 [open $status2 r];
+gets $fileid2 line1;
+gets $fileid2 line2;
+close $fileid2;
+
+set test "attach2, initial sanity check of the stopped state"
+if {[string match "*(stopped)*" $line2]} {
+ pass $test
+} else {
+ fail $test
+}
+
+# Start with clean gdb
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Verify that we can attach to the process by first giving its
+# executable name via the file command, and using attach with the
+# process ID.
+
+set test "set file, before attach3 to stopped process"
+gdb_test_multiple "file $binfile" "$test" {
+ -re "Load new symbol table from.*y or n. $" {
+ gdb_test "y" "Reading symbols from $escapedbinfile\.\.\.*done." \
+ "$test (re-read)"
+ }
+ -re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $" {
+ pass "$test"
+ }
+}
+
+set test "attach3 to stopped, after setting file"
+gdb_test_multiple "attach $testpid" "$test" {
+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
+ pass "$test"
+ }
+}
+
+# We may be already after the threads phase.
+# `thread 2' command is important for the test to switch the current thread to
+# a non-primary one for the detach process.
+
+gdb_test "thread 2" ".*(witching to thread 2 |hread ID 2 not known).*" "attach3 to stopped switch thread"
+gdb_test "bt" ".*sleep.*(func|main).*" "attach3 to stopped bt"
+
+# Exit and detach the process.
+gdb_exit
+
+# Stop the program
+remote_exec build "kill -s STOP ${testpid}"
+
+# No race
+sleep 2
+
+# Continue the test as we would hit another expected bug regarding
+# Program received signal SIGSTOP, Stopped (signal).
+# across NPTL threads.
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Verify that we can attach to the process just by giving the
+# process ID.
+
+set test "attach4 to stopped, after setting file"
+gdb_test_multiple "attach $testpid" "$test" {
+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
+ pass "$test"
+ }
+}
+
+# We may be already after the threads phase.
+# `thread 2' command is important for the test to switch the current thread to
+# a non-primary one for the detach process.
+
+gdb_test "thread 2" ".*(witching to thread 2 |hread ID 2 not known).*" "attach4 to stopped switch thread"
+gdb_test "bt" ".*sleep.*(func|main).*" "attach4 to stopped bt"
+
+# RHEL3U8 kernel-2.4.21-47.EL will not return SIGINT but only shorten the sleep.
+gdb_breakpoint [gdb_get_line_number "Ridiculous time"]
+gdb_breakpoint [gdb_get_line_number "cut the sleep time"]
+set test "attach4 continue"
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing"
+ { pass "continue ($test)" }
+ timeout
+ { fail "continue ($test) (timeout)" }
+}
+
+# For this to work we must be sure to consume the "Continuing."
+# message first, or GDB's signal handler may not be in place.
+after 1000 {send_gdb "\003"}
+set test "attach4 stop by interrupt"
+gdb_expect {
+ -re "Program received signal SIGINT.*$gdb_prompt $"
+ {
+ pass $test
+ }
+ -re "Breakpoint \[0-9\].*$srcfile.*$gdb_prompt $"
+ {
+ pass $test
+ }
+ timeout
+ {
+ fail "$test (timeout)"
+ }
+}
+
+gdb_exit
+
+# No race
+sleep 2
+
+# At this point, the process should be sleeping
+
+set fileid4 [open $status2 r];
+gets $fileid4 line1;
+gets $fileid4 line2;
+close $fileid4;
+
+set test "attach4, exit leaves process sleeping"
+if {[string match "*(sleeping)*" $line2]} {
+ pass $test
+} else {
+ fail $test
+}
+
+# Make sure we don't leave a process around to confuse
+# the next test run (and prevent the compile by keeping
+# the text file busy), in case the "set should_exit" didn't
+# work.
+
+remote_exec build "kill -9 ${testpid}"
+
+return 0
Index: staticthreads.c
===================================================================
--- staticthreads.c (nonexistent)
+++ staticthreads.c (revision 816)
@@ -0,0 +1,71 @@
+/* This test program is part of GDB, The GNU debugger.
+
+ Copyright 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Originally written by Jeff Johnston ,
+ contributed by Red Hat
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+#include
+#include
+
+sem_t semaphore;
+
+void *
+thread_function (void *arg)
+{
+ printf ("Thread executing\n");
+ while (sem_wait (&semaphore) != 0)
+ {
+ if (errno != EINTR)
+ {
+ perror ("thread_function");
+ return;
+ }
+ }
+ return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+ pthread_attr_t attr;
+
+ pthread_attr_init (&attr);
+ pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
+
+ if (sem_init (&semaphore, 0, 0) == -1)
+ {
+ perror ("semaphore");
+ return -1;
+ }
+
+
+ /* Create a thread, wait for it to complete. */
+ {
+ pthread_t thread;
+ pthread_create (&thread, &attr, thread_function, NULL);
+ sem_post (&semaphore);
+ pthread_join (thread, NULL);
+ }
+
+ pthread_attr_destroy (&attr);
+ return 0;
+}
staticthreads.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: killed.c
===================================================================
--- killed.c (nonexistent)
+++ killed.c (revision 816)
@@ -0,0 +1,42 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2002, 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+#include
+#include
+
+int pid;
+
+void *
+child_func (void *dummy)
+{
+ kill (pid, SIGKILL);
+ exit (1);
+}
+
+int
+main ()
+{
+ pthread_t child;
+
+ pid = getpid ();
+ pthread_create (&child, 0, child_func, 0);
+ for (;;)
+ sleep (10000);
+}
killed.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: thread_check.c
===================================================================
--- thread_check.c (nonexistent)
+++ thread_check.c (revision 816)
@@ -0,0 +1,73 @@
+/* Copyright (C) 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ This file was written by Steve Munroe (sjmunroe@us.ibm.com). */
+
+/* Test break points and single step on thread functions. */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define N 2
+
+static void *
+tf (void *arg)
+{
+ int n = (int) (long int) arg;
+ char number[160];
+ int unslept = 10;
+
+ sprintf(number, "tf(%ld): begin", (long)arg);
+ puts (number);
+
+ while (unslept > 0)
+ unslept = sleep(unslept);
+
+ sprintf(number, "tf(%ld): end", (long)arg);
+ puts (number);
+ return NULL;
+}
+
+int main (int argc, char *argv[])
+{
+ int n;
+ int unslept = 2;
+ pthread_t th[N];
+
+ for (n = 0; n < N; ++n)
+ if (pthread_create (&th[n], NULL, tf, (void *) (long int) n) != 0)
+ {
+ while (unslept > 0)
+ unslept = sleep(2);
+ puts ("create failed");
+ exit (1);
+ }
+
+ puts("after create");
+
+ for (n = 0; n < N; ++n)
+ if (pthread_join (th[n], NULL) != 0)
+ {
+ puts ("join failed");
+ exit (1);
+ }
+
+ puts("after join");
+ return 0;
+}
thread_check.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: multi-create.exp
===================================================================
--- multi-create.exp (nonexistent)
+++ multi-create.exp (revision 816)
@@ -0,0 +1,40 @@
+# multi-create.exp -- Test creating many threads in parallel
+# Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+set testfile "multi-create"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+ executable {debug}] != "" } {
+ return -1
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+runto_main
+
+# Run to the beginning of create_function several times. Make sure
+# we always stop there, and not somewhere else in the guts of the
+# thread library.
+
+set bp_location1 [gdb_get_line_number "set breakpoint 1 here"]
+gdb_breakpoint $srcfile:$bp_location1
+for {set i 0} {$i < 32} {incr i} {
+ gdb_test "continue" ".*Breakpoint $decimal,.*$srcfile:$bp_location1.*" \
+ "continue to breakpoint $i"
+}
Index: schedlock.exp
===================================================================
--- schedlock.exp (nonexistent)
+++ schedlock.exp (revision 816)
@@ -0,0 +1,346 @@
+# Copyright (C) 1996, 1997, 2002, 2003, 2007, 2008, 2009, 2010
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file was written by Daniel Jacobowitz
+# (parts based on pthreads.exp by Fred Fish (fnf@cygnus.com).
+#
+# This test covers the various forms of "set scheduler-locking".
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "schedlock"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# The number of threads, including the main thread.
+set NUM 2
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+# Now we can proceed with the real testing.
+
+proc get_args { } {
+ global list_count
+ global gdb_prompt
+ global NUM
+
+ set pattern "(\[0-9\]+)"
+ for {set i 1} {[expr $i < $NUM]} {incr i} {
+ append pattern ", (\[0-9\]+)"
+ }
+
+ send_gdb "print args\n"
+ gdb_expect {
+ -re "\\\$\[0-9\]+ = {$pattern}.*$gdb_prompt"
+ {
+ set list_count [expr $list_count + 1]
+ pass "listed args ($list_count)"
+
+ set result ""
+ for {set i 1} {[expr $i <= $NUM]} {incr i} {
+ lappend result $expect_out($i,string)
+ }
+ return $result
+ }
+ -re "$gdb_prompt"
+ {
+ fail "listed args ($list_count) (unknown output)"
+ }
+ timeout
+ {
+ fail "listed args ($list_count) (timeout)"
+ }
+ }
+}
+
+proc stop_process { description } {
+ global gdb_prompt
+
+ # For this to work we must be sure to consume the "Continuing."
+ # message first, or GDB's signal handler may not be in place.
+ after 1000 {send_gdb "\003"}
+ gdb_expect {
+ -re "Program received signal SIGINT.*$gdb_prompt $"
+ {
+ pass $description
+ }
+ timeout
+ {
+ fail "$description (timeout)"
+ }
+ }
+}
+
+proc get_current_thread { description } {
+ global gdb_prompt
+
+ send_gdb "bt\n"
+ gdb_expect {
+ -re "thread_function \\(arg=0x(\[0-9\])\\).*$gdb_prompt $"
+ {
+ pass $description
+ return $expect_out(1,string)
+ }
+ -re "$gdb_prompt $"
+ {
+ fail "$description (unknown output)"
+ }
+ timeout
+ {
+ fail "$description (timeout)"
+ }
+ }
+}
+
+proc my_continue { msg } {
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Continuing"
+ { pass "continue ($msg)" }
+ timeout
+ { fail "continue ($msg) (timeout)" }
+ }
+
+ stop_process "stop all threads ($msg)"
+
+ # Make sure we're in one of the non-main looping threads.
+ gdb_breakpoint [concat [gdb_get_line_number "schedlock.exp: main loop"] " if arg != 0"]
+ gdb_continue_to_breakpoint "return to loop ($msg)"
+ delete_breakpoints
+}
+
+proc step_ten_loops { msg } {
+ global gdb_prompt
+
+ for {set i 0} {[expr $i < 10]} {set i [expr $i + 1]} {
+ send_gdb "step\n"
+ set other_step 0
+ gdb_expect {
+ -re ".*myp\\) \\+\\+;\[\r\n\]+$gdb_prompt $" {
+ pass "step to increment ($msg $i)"
+ }
+ -re "$gdb_prompt $" {
+ if {$other_step == 0} {
+ set other_step 1
+ send_gdb "step\n"
+ exp_continue
+ } else {
+ fail "step to increment ($msg $i)"
+ # FIXME cascade?
+ }
+ }
+ timeout {
+ fail "step to increment ($msg $i) (timeout)"
+ }
+ }
+ }
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# We'll need this when we send_gdb a ^C to GDB. Need to do it before we
+# run the program and gdb starts saving and restoring tty states.
+# On Ultrix, we don't need it and it is really slow (because shell_escape
+# doesn't use vfork).
+if ![istarget "*-*-ultrix*"] then {
+ gdb_test "shell stty intr '^C'" ""
+}
+
+gdb_load ${binfile}
+
+gdb_test "set print sevenbit-strings" ""
+gdb_test "set width 0" ""
+
+runto_main
+
+# See if scheduler locking is available on this target.
+send_gdb "set scheduler-locking off\n"
+global gdb_prompt
+gdb_expect {
+ -re "Target .* cannot support this command"
+ {
+ unsupported "target does not support scheduler locking"
+ return
+ }
+ -re "$gdb_prompt $"
+ {
+ pass "scheduler locking set to none"
+ }
+ timeout
+ {
+ unsupported "target does not support scheduler locking (timeout)"
+ return
+ }
+}
+
+gdb_breakpoint [gdb_get_line_number "schedlock.exp: last thread start"]
+gdb_continue_to_breakpoint "all threads started"
+
+global list_count
+set list_count 0
+
+set start_args [get_args]
+
+# First make sure that all threads are alive.
+my_continue "initial"
+
+set cont_args [get_args]
+
+set bad 0
+for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} {
+ if {[lindex $start_args $i] == [lindex $cont_args $i]} {
+ incr bad
+ }
+}
+if { $bad == 0 } {
+ pass "all threads alive"
+} else {
+ fail "all threads alive ($bad/$NUM did not run)"
+}
+
+# We can't change threads, unfortunately, in current GDB. Use
+# whichever we stopped in.
+set curthread [get_current_thread "find current thread (1)"]
+
+
+
+
+# Test stepping without scheduler locking.
+gdb_test "set scheduler-locking off" ""
+
+step_ten_loops "unlocked"
+
+# Make sure we're still in the same thread.
+set newthread [get_current_thread "find current thread (2)"]
+if {$curthread == $newthread} {
+ pass "step without lock does not change thread"
+} else {
+ fail "step without lock does not change thread (switched to thread $newthread)"
+}
+
+set start_args $cont_args
+set cont_args [get_args]
+
+set num_other_threads 0
+for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} {
+ if {[lindex $start_args $i] == [lindex $cont_args $i]} {
+ if {$i == $curthread} {
+ fail "current thread stepped (didn't run)"
+ }
+ } else {
+ if {$i == $curthread} {
+ if {[lindex $start_args $i] == [expr [lindex $cont_args $i] - 10]} {
+ pass "current thread stepped"
+ } else {
+ fail "current thread stepped (wrong amount)"
+ }
+ } else {
+ set num_other_threads [expr $num_other_threads + 1]
+ }
+ }
+}
+if {$num_other_threads > 0} {
+ pass "other threads ran - unlocked"
+} else {
+ fail "other threads ran - unlocked"
+}
+
+# Test continue with scheduler locking
+gdb_test "set scheduler-locking on" ""
+
+my_continue "with lock"
+
+# Make sure we're still in the same thread.
+set newthread [get_current_thread "find current thread (3)"]
+if {$curthread == $newthread} {
+ pass "continue with lock does not change thread"
+} else {
+ fail "continue with lock does not change thread (switched to thread $newthread)"
+}
+
+set start_args $cont_args
+set cont_args [get_args]
+
+set num_other_threads 0
+for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} {
+ if {[lindex $start_args $i] == [lindex $cont_args $i]} {
+ if {$i == $curthread} {
+ fail "current thread ran (didn't run)"
+ }
+ } else {
+ if {$i == $curthread} {
+ pass "current thread ran"
+ } else {
+ incr num_other_threads
+ }
+ }
+}
+if {$num_other_threads > 0} {
+ fail "other threads didn't run - locked"
+} else {
+ pass "other threads didn't run - locked"
+}
+
+# Test stepping with scheduler locking
+step_ten_loops "locked"
+
+# Make sure we're still in the same thread.
+set newthread [get_current_thread "find current thread (2)"]
+if {$curthread == $newthread} {
+ pass "step with lock does not change thread"
+} else {
+ fail "step with lock does not change thread (switched to thread $newthread)"
+}
+
+set start_args $cont_args
+set cont_args [get_args]
+
+set num_other_threads 0
+for {set i 0} {[expr $i < $NUM]} {set i [expr $i + 1]} {
+ if {[lindex $start_args $i] == [lindex $cont_args $i]} {
+ if {$i == $curthread} {
+ fail "current thread stepped locked (didn't run)"
+ }
+ } else {
+ if {$i == $curthread} {
+ if {[lindex $start_args $i] == [expr [lindex $cont_args $i] - 10]} {
+ pass "current thread stepped locked"
+ } else {
+ fail "current thread stepped locked (wrong amount)"
+ }
+ } else {
+ incr num_other_threads
+ }
+ }
+}
+if {$num_other_threads > 0} {
+ fail "other threads didn't run - step locked"
+} else {
+ pass "other threads didn't run - step locked"
+}
+
+return 0
Index: pthreads.c
===================================================================
--- pthreads.c (nonexistent)
+++ pthreads.c (revision 816)
@@ -0,0 +1,171 @@
+/* Pthreads test program.
+ Copyright 1996, 2002, 2003, 2004, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
+
+ Written by Fred Fish of Cygnus Support
+ Contributed by Cygnus Support
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+
+/* Under OSF 2.0 & 3.0 and HPUX 10, the second arg of pthread_create
+ is prototyped to be just a "pthread_attr_t", while under Solaris it
+ is a "pthread_attr_t *". Arg! */
+
+#if defined (__osf__) || defined (__hpux__)
+#define PTHREAD_CREATE_ARG2(arg) arg
+#define PTHREAD_CREATE_NULL_ARG2 null_attr
+static pthread_attr_t null_attr;
+#else
+#define PTHREAD_CREATE_ARG2(arg) &arg
+#define PTHREAD_CREATE_NULL_ARG2 NULL
+#endif
+
+static int verbose = 0;
+
+static void
+common_routine (arg)
+ int arg;
+{
+ static int from_thread1;
+ static int from_thread2;
+ static int from_main;
+ static int hits;
+ static int full_coverage;
+
+ if (verbose) printf("common_routine (%d)\n", arg);
+ hits++;
+ switch (arg)
+ {
+ case 0:
+ from_main++;
+ break;
+ case 1:
+ from_thread1++;
+ break;
+ case 2:
+ from_thread2++;
+ break;
+ }
+ if (from_main && from_thread1 && from_thread2)
+ full_coverage = 1;
+}
+
+static void *
+thread1 (void *arg)
+{
+ int i;
+ int z = 0;
+
+ if (verbose) printf ("thread1 (%0x) ; pid = %d\n", arg, getpid ());
+ for (i=1; i <= 10000000; i++)
+ {
+ if (verbose) printf("thread1 %d\n", pthread_self ());
+ z += i;
+ common_routine (1);
+ sleep(1);
+ }
+ return (void *) 0;
+}
+
+static void *
+thread2 (void * arg)
+{
+ int i;
+ int k = 0;
+
+ if (verbose) printf ("thread2 (%0x) ; pid = %d\n", arg, getpid ());
+ for (i=1; i <= 10000000; i++)
+ {
+ if (verbose) printf("thread2 %d\n", pthread_self ());
+ k += i;
+ common_routine (2);
+ sleep(1);
+ }
+ sleep(100);
+ return (void *) 0;
+}
+
+void
+foo (a, b, c)
+ int a, b, c;
+{
+ int d, e, f;
+
+ if (verbose) printf("a=%d\n", a);
+}
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ pthread_t tid1, tid2;
+ int j;
+ int t = 0;
+ void (*xxx) ();
+ pthread_attr_t attr;
+
+ if (verbose) printf ("pid = %d\n", getpid());
+
+ foo (1, 2, 3);
+
+#ifndef __osf__
+ if (pthread_attr_init (&attr))
+ {
+ perror ("pthread_attr_init 1");
+ exit (1);
+ }
+#endif
+
+#ifdef PTHREAD_SCOPE_SYSTEM
+ if (pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM))
+ {
+ perror ("pthread_attr_setscope 1");
+ exit (1);
+ }
+#endif
+
+ if (pthread_create (&tid1, PTHREAD_CREATE_ARG2(attr), thread1, (void *) 0xfeedface))
+ {
+ perror ("pthread_create 1");
+ exit (1);
+ }
+ if (verbose) printf ("Made thread %d\n", tid1);
+ sleep (1);
+
+ if (pthread_create (&tid2, PTHREAD_CREATE_NULL_ARG2, thread2, (void *) 0xdeadbeef))
+ {
+ perror ("pthread_create 2");
+ exit (1);
+ }
+ if (verbose) printf("Made thread %d\n", tid2);
+
+ sleep (1);
+
+ for (j = 1; j <= 10000000; j++)
+ {
+ if (verbose) printf("top %d\n", pthread_self ());
+ common_routine (0);
+ sleep(1);
+ t += j;
+ }
+
+ exit(0);
+}
+
pthreads.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: sigthread.c
===================================================================
--- sigthread.c (nonexistent)
+++ sigthread.c (revision 816)
@@ -0,0 +1,77 @@
+/* Test case for C-c sent to threads with pending signals. Before I
+ even get there, creating a thread and sending it a signal before it
+ has a chance to run leads to an internal error in GDB. We need to
+ record that there's a pending SIGSTOP, so that we'll ignore it
+ later, and pass the current signal back to the thread.
+
+ The fork/vfork case has similar trouble but that's even harder
+ to get around. We may need to send a SIGCONT to cancel out the
+ SIGSTOP. Different kernels may do different things if the thread
+ is stopped by ptrace and sent a SIGSTOP. */
+
+#include
+#include
+#include
+#include
+#include
+
+/* Loop long enough for GDB to send a few signals of its own, but
+ don't hang around eating CPU forever if something goes wrong during
+ testing. */
+#define NSIGS 10000000
+
+pthread_barrier_t barrier;
+
+void
+handler (int sig)
+{
+ ;
+}
+
+pthread_t main_thread;
+pthread_t child_thread, child_thread_two;
+
+void *
+child_two (void *arg)
+{
+ int i;
+
+ pthread_barrier_wait (&barrier);
+
+ for (i = 0; i < NSIGS; i++)
+ pthread_kill (child_thread, SIGUSR1);
+}
+
+void *
+thread_function (void *arg)
+{
+ int i;
+
+ pthread_barrier_wait (&barrier);
+
+ for (i = 0; i < NSIGS; i++)
+ pthread_kill (child_thread_two, SIGUSR2);
+}
+
+int main()
+{
+ int i;
+
+ signal (SIGUSR1, handler);
+ signal (SIGUSR2, handler);
+
+ pthread_barrier_init (&barrier, NULL, 3);
+
+ main_thread = pthread_self ();
+ pthread_create (&child_thread, NULL, thread_function, NULL);
+ pthread_create (&child_thread_two, NULL, child_two, NULL);
+
+ pthread_barrier_wait (&barrier);
+
+ for (i = 0; i < NSIGS; i++)
+ pthread_kill (child_thread_two, SIGUSR1);
+
+ pthread_join (child_thread, NULL);
+
+ exit (0);
+}
sigthread.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: threadapply.c
===================================================================
--- threadapply.c (nonexistent)
+++ threadapply.c (revision 816)
@@ -0,0 +1,81 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2002, 2003, 2004, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ This file is copied from schedlock.c. */
+
+#include
+#include
+#include
+#include
+
+void *thread_function(void *arg); /* Pointer to function executed by each thread */
+
+#define NUM 5
+
+unsigned int args[NUM+1];
+
+int main() {
+ int res;
+ int all_started;
+ pthread_t threads[NUM];
+ void *thread_result;
+ long i;
+
+ for (i = 0; i < NUM; i++)
+ {
+ args[i] = 1; /* Init value. */
+ res = pthread_create(&threads[i],
+ NULL,
+ thread_function,
+ (void *) i);
+ }
+
+ all_started = 0;
+ while (!all_started)
+ {
+ all_started = 1;
+ for (i = 0; i < NUM; i++)
+ {
+ if (args[i] == 1)
+ {
+ all_started = 0;
+ break;
+ }
+ }
+ }
+
+ args[i] = 1;
+ /* Break here */
+ thread_function ((void *) i);
+
+ exit(EXIT_SUCCESS);
+}
+
+void *thread_function(void *arg) {
+ int my_number = (long) arg;
+ int *myp = (int *) &args[my_number];
+
+ /* Don't run forever. Run just short of it :) */
+ while (*myp > 0)
+ {
+ (*myp) ++; /* Loop increment. */
+ }
+
+ pthread_exit(NULL);
+}
+
threadapply.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: thread-execl.exp
===================================================================
--- thread-execl.exp (nonexistent)
+++ thread-execl.exp (revision 816)
@@ -0,0 +1,53 @@
+# Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Test that GDB doesn't get stuck when stepping over an exec call done
+# by a thread other than the main thread.
+
+# There's no support for exec events in the remote protocol.
+if { [is_remote target] } {
+ return 0
+}
+
+set testfile "thread-execl"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+ executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+runto_main
+
+# Get ourselves to the thread that execs
+gdb_breakpoint "thread_execler"
+gdb_test "continue" ".*thread_execler.*" "continue to thread start"
+
+# Now set a breakpoint at `main', and step over the execl call. The
+# breakpoint at main should be reached. GDB should not try to revert
+# back to the old thread from the old image and resume stepping it
+# (since it is gone).
+gdb_breakpoint "main"
+gdb_test "next" ".*main.*" "get to main in new image"
+
+return 0
Index: fork-child-threads.exp
===================================================================
--- fork-child-threads.exp (nonexistent)
+++ fork-child-threads.exp (revision 816)
@@ -0,0 +1,53 @@
+# Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Only GNU/Linux is known to support `set follow-fork-mode child'.
+if { ! [istarget "*-*-linux*"] } {
+ return 0
+}
+
+set testfile fork-child-threads
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+gdb_test "set follow-fork-mode child"
+gdb_breakpoint "start"
+
+# Make sure we can step over fork without losing our breakpoint.
+gdb_test "next" ".*pthread_create \\(&thread, NULL, start, NULL\\);.*" "next over fork"
+
+gdb_test "continue" "Breakpoint 2, start.*" "get to the spawned thread"
+
+# Wrong:
+# * 2 LWP 4466 start (arg=0x0) at fork-child-threads.c:28
+# Correct:
+# * 3 Thread 0x40a00950 (LWP 5553) start (arg=0x0) at ../.././gdb/testsuite/gdb.threads/fork-child-threads.c:28
+# 2 Thread 0x2aaaaaac3000 (LWP 5552) 0x00000031674076dd in pthread_join (threadid=, thread_return=) at pthread_join.c:89
+
+gdb_test "info threads" " Thread .* Thread .*" "two threads found"
Index: print-threads.c
===================================================================
--- print-threads.c (nonexistent)
+++ print-threads.c (revision 816)
@@ -0,0 +1,58 @@
+#include
+#include
+#include
+#include
+
+void *thread_function(void *arg); /* Pointer to function executed by each thread */
+
+int slow = 0;
+
+#define NUM 5
+
+int main() {
+ int res;
+ pthread_t threads[NUM];
+ void *thread_result;
+ int args[NUM];
+ int i;
+
+ for (i = 0; i < NUM; i++)
+ {
+ args[i] = i;
+ res = pthread_create(&threads[i], NULL, thread_function, (void *)&args[i]);
+ }
+
+ for (i = 0; i < NUM; i++)
+ res = pthread_join(threads[i], &thread_result);
+
+ printf ("Done\n");
+
+ if (slow)
+ sleep (4);
+
+ exit(EXIT_SUCCESS);
+}
+
+void *thread_function(void *arg) {
+ int my_number = *(int *)arg;
+ int rand_num;
+
+ printf ("Print 1, thread %d\n", my_number);
+ sleep (1);
+
+ if (slow)
+ {
+ printf ("Print 2, thread %d\n", my_number);
+ sleep (1);
+ printf ("Print 3, thread %d\n", my_number);
+ sleep (1);
+ printf ("Print 4, thread %d\n", my_number);
+ sleep (1);
+ printf ("Print 5, thread %d\n", my_number);
+ sleep (1);
+ }
+
+ printf("Bye from %d\n", my_number);
+ pthread_exit(NULL);
+}
+
print-threads.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: pthread_cond_wait.exp
===================================================================
--- pthread_cond_wait.exp (nonexistent)
+++ pthread_cond_wait.exp (revision 816)
@@ -0,0 +1,73 @@
+# Copyright (C) 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This file verifies that GDB is able to compute a backtrace for a thread
+# being blocked on a call to pthread_cond_wait().
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile "pthread_cond_wait"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+runto_main
+
+gdb_test "break break_me" \
+ "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on break_me"
+
+gdb_test "continue" \
+ ".*Breakpoint 2, break_me ().*" \
+ "run to break_me"
+
+#
+# Backtrace all threads, find the one running noreturn, and
+# verify that we are able to get a sensible backtrace, including
+# the frame for the pthread_cond_wait() call.
+#
+# The string below will only match if the functions named
+# occur in a single thread's backtrace, in the given order.
+#
+
+global hex
+global decimal
+
+#
+# This is a "backtrace break" ("btb"):
+#
+set btb "\[^\r\n\]+\[\r\n\]+\#${decimal}\[ \t\]+${hex} in "
+
+# One of the threads is blocked on a call to pthread_cond_wait, and
+# we want to verify that we are able to get a sensible backtrace for
+# that thread. Because we don't know its thread ID, we can't switch
+# to it before doing the backtrace. So we get a backtrace for all
+# threads, and verify that one them returns the expected backtrace.
+gdb_test "thread apply all backtrace" \
+ "pthread_cond_wait${btb}cond_wait${btb}noreturn${btb}forever_pthread.*" \
+ "backtrace in blocked thread"
+
Index: bp_in_thread.exp
===================================================================
--- bp_in_thread.exp (nonexistent)
+++ bp_in_thread.exp (revision 816)
@@ -0,0 +1,49 @@
+# Copyright (C) 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# gdb 6.1.1 on AIX had a bug where the aix-threads code called
+# getthrds() incorrectly so that gdb lost track of breakpoints.
+# GDB reported a SIGTRAP signal in a random thread when hitting
+# a breakpoint.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile "bp_in_thread"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+runto_main
+
+gdb_test "break noreturn" \
+ "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on noreturn"
+
+# Run the program and make sure GDB reports that we stopped after
+# hitting breakpoint 1 in noreturn().
+
+gdb_test "continue" \
+ ".*Breakpoint 2, noreturn ().*" \
+ "run to noreturn"
+
Index: attachstop-mt.c
===================================================================
--- attachstop-mt.c (nonexistent)
+++ attachstop-mt.c (revision 816)
@@ -0,0 +1,56 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+/* This program is intended to be started outside of gdb, then
+ manually stopped via a signal. */
+
+#include
+#include
+#include
+#include
+
+/* Red Hat BZ PR 197584.c */
+
+void *func (void *arg)
+{
+ sleep (10000); /* Ridiculous time, but we will eventually kill it. */
+ sleep (10000); /* RHEL3U8 kernel-2.4.21-47.EL will cut the sleep time. */
+
+ return NULL; /* thread-sleep */
+}
+
+int main ()
+{
+ pthread_t t1,t2;
+ int ret;
+
+ ret = pthread_create (&t1, NULL, func, NULL);
+ if (ret)
+ fprintf(stderr, "pthread_create(): %s", strerror (ret));
+ ret = pthread_create (&t2, NULL, func, NULL);
+ if (ret)
+ fprintf(stderr, "pthread_create(): %s", strerror (ret));
+
+ ret = pthread_join (t1, NULL);
+ if (ret) /* first-join */
+ fprintf(stderr, "pthread_join(): %s", strerror (ret));
+ ret = pthread_join (t2, NULL);
+ if (ret)
+ fprintf(stderr, "pthread_join(): %s", strerror (ret));
+
+ return 0;
+}
attachstop-mt.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: switch-threads.c
===================================================================
--- switch-threads.c (nonexistent)
+++ switch-threads.c (revision 816)
@@ -0,0 +1,44 @@
+/* A minimal multi-threaded test case.
+
+ Copyright 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+
+void foo (void)
+{
+}
+
+void *thread_func (void *arg)
+{
+ int x;
+ for (x = 0; x < 10; x++)
+ foo ();
+ return 0;
+}
+
+int main()
+{
+ pthread_t thr;
+ void *ret;
+ int x;
+
+ pthread_create (&thr, NULL, thread_func, NULL);
+ pthread_join (thr, &ret);
+ for (x = 0; x < 10; x++)
+ foo ();
+}
switch-threads.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: hand-call-in-threads.exp
===================================================================
--- hand-call-in-threads.exp (nonexistent)
+++ hand-call-in-threads.exp (revision 816)
@@ -0,0 +1,160 @@
+# Copyright (C) 2004, 2007, 2008, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Test making hand function calls in multiple threads.
+
+set NR_THREADS 4
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile "hand-call-in-threads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}" "additional_flags=-DNR_THREADS=$NR_THREADS"]] != "" } {
+ return -1
+}
+
+# Some targets can't do function calls, so don't even bother with this
+# test.
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ continue
+}
+
+proc get_dummy_frame_number { } {
+ global gdb_prompt
+
+ send_gdb "bt\n"
+ gdb_expect {
+ -re "#(\[0-9\]*) *.*$gdb_prompt $"
+ {
+ return $expect_out(1,string)
+ }
+ -re "$gdb_prompt $"
+ {
+ return ""
+ }
+ timeout
+ {
+ return ""
+ }
+ }
+ return ""
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if { ![runto_main] } {
+ fail "Can't run to main"
+ return 0
+}
+
+gdb_test "break all_threads_running" \
+ "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on all_threads_running"
+
+gdb_test "break hand_call" \
+ "Breakpoint 3 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on hand_call"
+
+# Run the program and make sure GDB reports that we stopped after
+# hitting breakpoint 2 in all_threads_running().
+
+gdb_test "continue" \
+ ".*Breakpoint 2, all_threads_running ().*" \
+ "run to all_threads_running"
+
+# Before we start making hand function calls, turn on scheduler locking.
+
+gdb_test "set scheduler-locking on" "" "enable scheduler locking"
+gdb_test "show scheduler-locking" ".* locking scheduler .* is \"on\"." "show scheduler locking on"
+
+# Now hand-call a function in each thread, having the function
+# stop without returning.
+
+# Add one for the main thread.
+set total_nr_threads [expr $NR_THREADS + 1]
+
+# Thread numbering in gdb is origin-1, so begin numbering at 1.
+for { set i 1 } { $i <= $total_nr_threads } { incr i } {
+ set thread_nr $i
+ gdb_test "thread $thread_nr" "" "prepare to make hand call, thread $thread_nr"
+ gdb_test "call hand_call()" "Breakpoint 3, .*" "hand call, thread $thread_nr"
+}
+
+# Now have each hand-called function return.
+
+# Turn confirmation off for the "return" command.
+gdb_test "set confirm off" ""
+
+clear_xfail "*-*-*"
+
+for { set i 1 } { $i <= $total_nr_threads } { incr i } {
+ set thread_nr $i
+ gdb_test "thread $thread_nr" "" "prepare to discard hand call, thread $thread_nr"
+ set frame_number [get_dummy_frame_number]
+ if { "$frame_number" == "" } {
+ fail "dummy stack frame number, thread $thread_nr"
+ # Need something.
+ set frame_number 0
+ } else {
+ pass "dummy stack frame number, thread $thread_nr"
+ }
+ # Pop the dummy frame.
+ gdb_test "frame $frame_number" "" "setting frame, thread $thread_nr"
+ gdb_test "return" "" "discard hand call, thread $thread_nr"
+ # In case getting the dummy frame number failed, re-enable for next iter.
+ clear_xfail "*-*-*"
+}
+
+# Make sure all dummy frames got popped.
+
+gdb_test_multiple "maint print dummy-frames" "all dummies popped" {
+ -re ".*stack=.*$gdb_prompt $" {
+ fail "all dummies popped"
+ }
+ -re ".*$gdb_prompt $" {
+ pass "all dummies popped"
+ }
+}
+
+# Before we resume the full program, turn of scheduler locking.
+gdb_test "set scheduler-locking off" "" "disable scheduler locking"
+gdb_test "show scheduler-locking" ".* locking scheduler .* is \"off\"." "show scheduler locking off"
+
+# Continue one last time, the program should exit normally.
+#
+# ??? This currently doesn't work because gdb doesn't know how to singlestep
+# over reported breakpoints that weren't in the last thread to run.
+# Commented out until then.
+#
+# For reference sake ...
+# An alternative is to manually work around the issue by manually setting
+# the thread back to the first thread: the program is still at the
+# all_threads_running breakpoint, which wasn't the last thread to run,
+# and gdb doesn't know how to singlestep over reported breakpoints that
+# weren't in the last thread to run.
+#gdb_test "thread 1" "" "set thread to 1, prepare to resume"
+#
+#gdb_continue_to_end "hand-call-in-threads"
+
+return 0
Index: attach-stopped.exp
===================================================================
--- attach-stopped.exp (nonexistent)
+++ attach-stopped.exp (revision 816)
@@ -0,0 +1,158 @@
+# Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This test was created by modifying attach.exp.
+# This file was created by Jeff Johnston .
+# This file was updated by Jan Kratochvil .
+
+# This test only works on Linux
+if { ![isnative] || [is_remote host] || ![istarget *-linux*] } {
+ continue
+}
+
+set testfile "attach-stopped"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set escapedbinfile [string_to_regexp ${objdir}/${subdir}/${testfile}]
+
+#execute_anywhere "rm -f ${binfile}"
+remote_exec build "rm -f ${binfile}"
+# For debugging this test
+#
+#log_user 1
+
+proc corefunc { threadtype } {
+ global srcfile
+ global binfile
+ global escapedbinfile
+ global srcdir
+ global subdir
+ global gdb_prompt
+
+ if [get_compiler_info ${binfile}] {
+ return -1
+ }
+
+ # Start the program running and then wait for a bit, to be sure
+ # that it can be attached to.
+
+ set testpid [eval exec $binfile &]
+
+ # Avoid some race:
+ sleep 2
+
+ # Stop the program
+ remote_exec build "kill -s STOP ${testpid}"
+
+ # Start with clean gdb
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+
+ # Verify that we can attach to the stopped process.
+
+ set test "$threadtype: attach2 to stopped, after setting file"
+ gdb_test_multiple "attach $testpid" "$test" {
+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
+ pass "$test"
+ }
+ }
+
+ # ".*sleep.*clone.*" would fail on s390x as bt stops at START_THREAD there.
+ if {[string equal $threadtype threaded]} {
+ gdb_test "thread apply all bt" ".*sleep.*start_thread.*" "$threadtype: attach2 to stopped bt"
+ } else {
+ gdb_test "bt" ".*sleep.*main.*" "$threadtype: attach2 to stopped bt"
+ }
+ # This breakpoint is there for old/non-x86 kernels not restarting syscalls.
+ gdb_breakpoint [gdb_get_line_number "Second sleep"]
+ set test "$threadtype: attach2 continue"
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Continuing"
+ { pass "continue ($test)" }
+ timeout
+ { fail "continue ($test) (timeout)" }
+ }
+
+ # For this to work we must be sure to consume the "Continuing."
+ # message first, or GDB's signal handler may not be in place.
+ after 1000 {send_gdb "\003"}
+ set test "$threadtype: attach2 stop interrupt"
+ gdb_expect 10 {
+ -re "Program received signal SIGINT.*$gdb_prompt $"
+ {
+ pass $test
+ }
+ -re "Breakpoint \[0-9\].*$srcfile.*$gdb_prompt $"
+ {
+ pass $test
+ }
+ timeout
+ {
+ fail $test
+ }
+ }
+
+ gdb_exit
+
+ # Avoid some race:
+ sleep 2
+
+ # At this point, the process should be sleeping
+
+ if [catch {open /proc/${testpid}/status r} fileid2] {
+ set line2 "NOTFOUND"
+ } else {
+ gets $fileid2 line1;
+ gets $fileid2 line2;
+ close $fileid2;
+ }
+
+ set test "$threadtype: attach2, exit leaves process sleeping"
+ if {[string match "*(sleeping)*" $line2]} {
+ pass $test
+ } else {
+ fail $test
+ }
+
+ # Make sure we don't leave a process around to confuse
+ # the next test run (and prevent the compile by keeping
+ # the text file busy), in case the "set should_exit" didn't
+ # work.
+
+ remote_exec build "kill -9 ${testpid}"
+}
+
+# build the test case first without threads
+#
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested "attach-stopped.exp (unthreaded)"
+ return -1
+}
+
+corefunc nonthreaded
+
+# build the test case first without threads
+#
+if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DUSE_THREADS}] != "" } {
+ untested "attach-stopped.exp (threaded)"
+ return -1
+}
+
+corefunc threaded
+
+return 0
Index: thread_events.c
===================================================================
--- thread_events.c (nonexistent)
+++ thread_events.c (revision 816)
@@ -0,0 +1,55 @@
+/* Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ This file was written by Chris Demetriou (cgd@google.com). */
+
+/* Simple test to trigger thread events (thread start, thread exit). */
+
+#include
+#include
+#include
+
+static void *
+threadfunc (void *arg)
+{
+ printf ("in threadfunc\n");
+ return NULL;
+}
+
+static void
+after_join_func (void)
+{
+ printf ("finished\n");
+}
+
+int main (int argc, char *argv[])
+{
+ pthread_t thread;
+
+ if (pthread_create (&thread, NULL, threadfunc, NULL) != 0)
+ {
+ printf ("pthread_create failed\n");
+ exit (1);
+ }
+
+ if (pthread_join (thread, NULL) != 0)
+ {
+ printf ("pthread_join failed\n");
+ exit (1);
+ }
+
+ after_join_func ();
+ return 0;
+}
thread_events.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: pending-step.c
===================================================================
--- pending-step.c (nonexistent)
+++ pending-step.c (revision 816)
@@ -0,0 +1,62 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2002, 2003, 2004, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+
+void *thread_function(void *arg); /* Pointer to function executed by each thread */
+
+#define NUM 1
+
+unsigned int args[NUM+1];
+
+int main() {
+ int res;
+ pthread_t threads[NUM];
+ void *thread_result;
+ long i;
+
+ for (i = 1; i <= NUM; i++)
+ {
+ args[i] = 1;
+ res = pthread_create(&threads[i - 1],
+ NULL,
+ thread_function,
+ (void *) i);
+ }
+
+ /* schedlock.exp: last thread start. */
+ args[0] = 1;
+ thread_function ((void *) 0);
+
+ exit(EXIT_SUCCESS);
+}
+
+void *thread_function(void *arg) {
+ int my_number = (long) arg;
+ int *myp = (int *) &args[my_number];
+
+ /* Don't run forever. Run just short of it :) */
+ while (*myp > 0)
+ {
+ (*myp) ++; /* insert breakpoint here */
+ }
+
+ pthread_exit(NULL);
+}
pending-step.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: local-watch-wrong-thread.c
===================================================================
--- local-watch-wrong-thread.c (nonexistent)
+++ local-watch-wrong-thread.c (revision 816)
@@ -0,0 +1,89 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2002, 2003, 2004, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+*/
+
+#include
+#include
+#include
+
+unsigned int args[2];
+int trigger = 0;
+
+void *
+thread_function0 (void *arg)
+{
+ int my_number = (long) arg;
+ volatile int *myp = (volatile int *) &args[my_number];
+
+ while (*myp > 0)
+ {
+ (*myp) ++;
+ usleep (1); /* Loop increment 1. */
+ }
+
+ return NULL;
+}
+
+void *
+thread_function0_1 (void *arg)
+{
+ void *ret = thread_function0 (arg);
+
+ return ret; /* set breakpoint here */
+}
+
+void *
+thread_function1 (void *arg)
+{
+ int my_number = (long) arg;
+
+ volatile int *myp = (volatile int *) &args[my_number];
+
+ while (*myp > 0)
+ {
+ (*myp) ++;
+ usleep (1); /* Loop increment 2. */
+ }
+
+ return NULL;
+}
+
+int
+main ()
+{
+ int res;
+ pthread_t threads[2];
+ void *thread_result;
+ long i = 0;
+
+ args[i] = 1; /* Init value. */
+ res = pthread_create (&threads[i], NULL,
+ thread_function0_1,
+ (void *) i);
+
+ i++;
+ args[i] = 1; /* Init value. */
+ res = pthread_create(&threads[i], NULL,
+ thread_function1,
+ (void *) i);
+
+ pthread_join (threads[0], &thread_result);
+ pthread_join (threads[1], &thread_result);
+ exit(EXIT_SUCCESS);
+}
local-watch-wrong-thread.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: tls-nodebug.exp
===================================================================
--- tls-nodebug.exp (nonexistent)
+++ tls-nodebug.exp (revision 816)
@@ -0,0 +1,48 @@
+# tls.exp -- Expect script to test thread-local storage without debuginfo
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see . */
+
+set testfile tls-nodebug
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [istarget "*-*-linux"] then {
+ set target_cflags "-D_MIT_POSIX_THREADS"
+} else {
+ set target_cflags ""
+}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable []] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+# Formerly: Cannot access memory at address 0x0
+gdb_test "p thread_local" "= 42" "thread local storage"
+
+# Done!
+#
+gdb_exit
+
+return 0
Index: attach-into-signal.exp
===================================================================
--- attach-into-signal.exp (nonexistent)
+++ attach-into-signal.exp (revision 816)
@@ -0,0 +1,169 @@
+# Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This test was created by modifying attach-stopped.exp.
+# This file was created by Jan Kratochvil .
+
+# This test only works on Linux
+if { ![isnative] || [is_remote host] || ![istarget *-linux*] } {
+ continue
+}
+
+set testfile "attach-into-signal"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set escapedbinfile [string_to_regexp ${objdir}/${subdir}/${testfile}]
+
+remote_exec build "rm -f ${binfile}"
+# For debugging this test
+#
+#log_user 1
+
+proc corefunc { threadtype } {
+ global srcfile
+ global binfile
+ global escapedbinfile
+ global srcdir
+ global subdir
+ global gdb_prompt
+
+ if [get_compiler_info ${binfile}] {
+ return -1
+ }
+
+ # Start the program running and then wait for a bit, to be sure
+ # that it can be attached to.
+ # Statistically there is a better chance without giving process a nice.
+
+ set testpid [eval exec $binfile &]
+ exec sleep 2
+
+ # Run 2 passes of the test.
+ # The C file inferior stops pending its signals if a single one is lost,
+ # we test successful redelivery of the caught signal by the 2nd pass.
+
+ # linux-2.6.20.4.x86_64 had maximal attempt # 20 in 4 test runs.
+ set attempts 100
+ set attempt 1
+ set passes 1
+ while { $passes < 3 && $attempt <= $attempts } {
+ set stoppedtry 0
+ while { $stoppedtry < 10 } {
+ if [catch {open /proc/${testpid}/status r} fileid] {
+ set stoppedtry 10
+ break
+ }
+ gets $fileid line1;
+ gets $fileid line2;
+ close $fileid;
+
+ if {![string match "*(stopped)*" $line2]} {
+ # No PASS message as we may be looping in multiple attempts.
+ break
+ }
+ sleep 1
+ set stoppedtry [expr $stoppedtry + 1]
+ }
+ if { $stoppedtry >= 10 } {
+ verbose -log $line2
+ set test "$threadtype: process is still running on the attempt # $attempt of $attempts"
+ break
+ }
+
+ # Main test:
+ set test "$threadtype: attach (pass $passes), pending signal catch"
+ if {[gdb_test_multiple "attach $testpid" $test {
+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*Received Alarm clock.*$gdb_prompt $" {
+ # nonthreaded:
+ pass $test
+ verbose -log "$test succeeded on the attempt # $attempt of $attempts"
+ set passes [expr $passes + 1]
+ }
+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
+ # nonthreaded:
+ # We just lack the luck, we should try it again.
+ set attempt [expr $attempt + 1]
+ }
+ -re "Attaching to process $testpid.*Received Alarm clock.*$gdb_prompt $" {
+ # threaded:
+ pass $test
+ verbose -log "$test succeeded on the attempt # $attempt of $attempts"
+ set passes [expr $passes + 1]
+ }
+ -re "Attaching to process $testpid.*$gdb_prompt $" {
+ # threaded:
+ # We just lack the luck, we should try it again.
+ set attempt [expr $attempt - 1]
+ }
+ }] != 0 } {
+ break
+ }
+
+ gdb_test "detach" "Detaching from.*" ""
+ }
+ if {$passes < 3} {
+ if {$attempt > $attempts} {
+ unresolved $test
+ } else {
+ fail $test
+ }
+ }
+
+ # Exit and detach the process.
+
+ gdb_exit
+
+ # Make sure we don't leave a process around to confuse
+ # the next test run (and prevent the compile by keeping
+ # the text file busy), in case the "set should_exit" didn't
+ # work.
+
+ # Continue the program - some Linux kernels need it before -9 if the
+ # process is stopped.
+ remote_exec build "kill -s CONT ${testpid}"
+
+ remote_exec build "kill -9 ${testpid}"
+}
+
+# Start with clean gdb
+gdb_exit
+
+# build the test case first without threads
+#
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested "attach-into-signal.exp (unthreaded)"
+ return -1
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "set debug lin-lwp 1" "" ""
+
+corefunc nonthreaded
+
+# build the test case also with threads
+#
+if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DUSE_THREADS}] != "" } {
+ untested "attach-into-signal.exp (threaded)"
+ return -1
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "set debug lin-lwp 1" "" ""
+
+corefunc threaded
Index: step2.exp
===================================================================
--- step2.exp (nonexistent)
+++ step2.exp (revision 816)
@@ -0,0 +1,147 @@
+# step2.exp -- Expect script to test gdb step.c
+# Copyright (C) 1992, 1997, 2007, 2008, 2009, 2010
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file was written by Jeff Law. (law@cygnus.com)
+#
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set program_exited 0
+
+# A simple and crude test to see that we can step two threads independently
+proc test_multi_threaded_stepping {} {
+ global gdb_prompt
+ global hex
+ global srcfile
+ global decimal
+
+ # Set breakpoints in code that we know is executed in only
+ # thread of control.
+ gdb_test "break thread1" \
+ "Break.* at $hex: file .*$srcfile, line $decimal\\."
+ gdb_test "break thread2" \
+ "Break.* at $hex: file .*$srcfile, line $decimal\\."
+
+ # the order in which things happen is indeterminate. So we basically
+ # look for a set of events and note that each one happens and that
+ # all of the required events have happened when we're done.
+ #
+ # Right now we only verify that both threads start and that they
+ # both call pthread_cond_wait twice.
+ set thread1started 0
+ set thread1condwait 0
+ set thread2started 0
+ set thread2condwait 0
+
+ send_gdb "run\n"
+ gdb_expect {
+ -re "The program .* has been started already.*y or n. $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ -re ".*Breakpoint \[0-9\]+,.*thread1.* at .*$srcfile:.*\[\t \].*$gdb_prompt $" {
+ if { $thread1started != 0 } then {
+ fail "thread1 started"
+ return
+ } else {
+ set thread1started 1
+ pass "thread1 started"
+ }
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*Breakpoint \[0-9\]+,.*thread2.* at .*$srcfile:.*\[\t \].*$gdb_prompt $" {
+ if { $thread2started != 0 } then {
+ fail "thread2 started"
+ return
+ } else {
+ set thread2started 1
+ pass "thread2 started"
+ }
+ send_gdb "step\n"
+ exp_continue
+ }
+ -re ".*pthread_cond_wait.*cv_a.*$gdb_prompt" {
+ if { $thread1started == 0 } then {
+ fail "thread1 condwait"
+ return
+ }
+ if { $thread1condwait < 2 } then {
+ pass "thread1 condwait"
+ incr thread1condwait
+ }
+ if { $thread2condwait == 2 } then {
+ pass "multi threaded stepping"
+ return
+ }
+ send_gdb "step\n"
+ exp_continue
+ }
+
+ -re ".*pthread_cond_wait.*cv_b.*$gdb_prompt" {
+ if { $thread2started == 0 } then {
+ fail "thread2 condwait"
+ return
+ }
+ if { $thread2condwait < 2 } then {
+ pass "thread2 condwait"
+ incr thread2condwait
+ }
+ if { $thread1condwait == 2 } then {
+ pass "multi threaded stepping"
+ return
+ }
+ send_gdb "step\n"
+ exp_continue
+ }
+
+ -re "$gdb_prompt" {
+ send_gdb "step\n"
+ exp_continue
+ }
+ default { fail "multi threaded stepping" }
+ }
+}
+
+# Check to see if we have an executable to test. If not, then either we
+# haven't tried to compile one, or the compilation failed for some reason.
+# In either case, just notify the user and skip the tests in this file.
+
+set binfile "step"
+set srcfile "step.c"
+
+if ![file exists $objdir/$subdir/$binfile] then {
+ if $all_flag then {
+ warning "$binfile does not exist; tests suppressed."
+ }
+ return
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $objdir/$subdir/$binfile
+
+test_multi_threaded_stepping
Index: fork-child-threads.c
===================================================================
--- fork-child-threads.c (nonexistent)
+++ fork-child-threads.c (revision 816)
@@ -0,0 +1,50 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+
+static void *
+start (void *arg)
+{
+ assert (0);
+ return arg;
+}
+
+int main(void)
+{
+ pthread_t thread;
+ int i;
+
+ switch (fork ())
+ {
+ case -1:
+ assert (0);
+ default:
+ break;
+ case 0:
+ i = pthread_create (&thread, NULL, start, NULL);
+ assert (i == 0);
+ i = pthread_join (thread, NULL);
+ assert (i == 0);
+
+ assert (0);
+ }
+
+ return 0;
+}
fork-child-threads.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: execl.exp
===================================================================
--- execl.exp (nonexistent)
+++ execl.exp (revision 816)
@@ -0,0 +1,75 @@
+# Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Test handling of threads across an execl.
+
+
+# Original image, loads a thread library.
+set testfile "execl"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ return -1
+}
+
+# New image, that does not load a thread library.
+set testfile1 "execl1"
+set srcfile1 ${testfile1}.c
+set binfile1 ${objdir}/${subdir}/${testfile1}
+
+if {[gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" executable {debug}] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+runto_main
+
+gdb_test "b [gdb_get_line_number "breakpoint here"]" \
+ ".*Breakpoint .*execl.*" "set breakpoint at execl"
+
+gdb_test "continue" ".*breakpoint here.*" "continue to exec"
+
+gdb_test "info threads" ".*3 Thread.*2 Thread.*1 Thread.*" "info threads before exec"
+
+# When continuing from this point we'll hit the breakpoint in main()
+# again, this time in the exec'd process.
+gdb_test "continue" ".*Breakpoint 1, main.*" \
+ "continue across exec"
+
+gdb_test "info threads" ".*" "info threads after exec"
+
+set test "info threads after exec"
+gdb_test_multiple "info threads" "$test" {
+ -re "2 Thread .*$gdb_prompt $" {
+ # Old threads left behind.
+ fail "$test"
+ }
+ -re "4 Thread .*$gdb_prompt $" {
+ # New threads registered.
+ fail "$test"
+ }
+ -re "$gdb_prompt $" {
+ # Target doesn't register the main thread, pass for now.
+ pass "$test"
+ }
+}
+
+gdb_test "continue" ".*Program exited normally\\." \
+ "continue to end"
Index: current-lwp-dead.c
===================================================================
--- current-lwp-dead.c (nonexistent)
+++ current-lwp-dead.c (revision 816)
@@ -0,0 +1,88 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ Do not use threads as we need to exploit a bug in LWP code masked by the
+ threads code otherwise.
+
+ INFERIOR_PTID must point to exited LWP. Here we use the initial LWP as it
+ is automatically INFERIOR_PTID for GDB.
+
+ Finally we need to call target_resume (RESUME_ALL, ...) which we invoke by
+ NEW_THREAD_EVENT (called from the new LWP as initial LWP is exited now). */
+
+#define _GNU_SOURCE
+#include
+#include
+#include
+#include
+
+#include
+#ifdef __UCLIBC__
+#if !(defined(__UCLIBC_HAS_MMU__) || defined(__ARCH_HAS_MMU__))
+#define HAS_NOMMU
+#endif
+#endif
+
+#define STACK_SIZE 0x1000
+
+static int
+fn_return (void *unused)
+{
+ return 0; /* at-fn_return */
+}
+
+static int
+fn (void *unused)
+{
+ int i;
+ unsigned char *stack;
+ int new_pid;
+
+ i = sleep (1);
+ assert (i == 0);
+
+ stack = malloc (STACK_SIZE);
+ assert (stack != NULL);
+
+ new_pid = clone (fn_return, stack + STACK_SIZE, CLONE_FILES
+#if defined(__UCLIBC__) && defined(HAS_NOMMU)
+ | CLONE_VM
+#endif /* defined(__UCLIBC__) && defined(HAS_NOMMU) */
+ , NULL, NULL, NULL, NULL);
+ assert (new_pid > 0);
+
+ return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+ unsigned char *stack;
+ int new_pid;
+
+ stack = malloc (STACK_SIZE);
+ assert (stack != NULL);
+
+ new_pid = clone (fn, stack + STACK_SIZE, CLONE_FILES
+#if defined(__UCLIBC__) && defined(HAS_NOMMU)
+ | CLONE_VM
+#endif /* defined(__UCLIBC__) && defined(HAS_NOMMU) */
+ , NULL, NULL, NULL, NULL);
+ assert (new_pid > 0);
+
+ return 0;
+}
current-lwp-dead.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: gcore-thread.exp
===================================================================
--- gcore-thread.exp (nonexistent)
+++ gcore-thread.exp (revision 816)
@@ -0,0 +1,178 @@
+# Copyright 2002, 2003, 2004, 2007, 2008, 2009, 2010
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file was written by Michael Snyder (msnyder@redhat.com)
+# This is a test for the gdb command "generate-core-file".
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# Single-threaded test case
+set testfile "pthreads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/gcore-${testfile}
+
+if [istarget "*-*-linux"] then {
+ set target_cflags "-D_MIT_POSIX_THREADS"
+} else {
+ set target_cflags ""
+}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+# Now we can proceed with the real testing.
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# regexp for "horizontal" text (i.e. doesn't include newline or
+# carriage return)
+set horiz "\[^\n\r\]*"
+
+# regexp for newline
+set nl "\[\r\n\]+"
+
+set prev_timeout $timeout
+set timeout 30
+
+send_gdb "help gcore\n"
+gdb_expect {
+ -re "Undefined command: .gcore.*$gdb_prompt $" {
+ # gcore command not supported -- nothing to test here.
+ unsupported "gdb does not support gcore on this target"
+ return -1;
+ }
+ -re "Save a core file .*$gdb_prompt $" {
+ pass "help gcore"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "help gcore"
+ }
+ timeout {
+ fail "help gcore (timeout)"
+ }
+}
+
+if { ! [ runto_main ] } then {
+ untested gcore-thread.exp
+ return -1
+}
+
+send_gdb "info threads\n"
+gdb_expect {
+ -re ".* main .*$gdb_prompt $" {
+ # OK, threads are supported.
+ }
+ -re "${nl}$gdb_prompt $" {
+ unsupported "gdb does not support threads on this target"
+ return -1;
+ }
+}
+
+# Make sure thread 1 is running
+delete_breakpoints
+gdb_breakpoint "thread1"
+gdb_test "continue" "Continuing.*Breakpoint.* thread1 .*" "thread 1 is running"
+
+# Make sure thread 2 is running
+delete_breakpoints
+gdb_breakpoint "thread2"
+gdb_test "continue" "Continuing.*Breakpoint.* thread2 .*" "thread 2 is running"
+
+set escapedfilename [string_to_regexp ${objdir}/${subdir}/gcore.test]
+# Drop corefile
+gdb_test_multiple "gcore ${objdir}/${subdir}/gcore.test" \
+ "save a corefile" \
+{
+ -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" {
+ pass "save a corefile"
+ global core_supported
+ set core_supported 1
+ }
+ -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" {
+ unsupported "save a corefile"
+ global core_supported
+ set core_supported 0
+ }
+}
+
+global core_supported
+if {!$core_supported} {
+ return -1
+}
+
+# Now restart gdb and load the corefile.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+send_gdb "core ${objdir}/${subdir}/gcore.test\n"
+gdb_expect {
+ -re ".* is not a core dump:.*$gdb_prompt $" {
+ fail "re-load generated corefile (bad file format)"
+ # No use proceeding from here.
+ return;
+ }
+ -re ".*: No such file or directory.*$gdb_prompt $" {
+ fail "re-load generated corefile (file not found)"
+ # No use proceeding from here.
+ return;
+ }
+ -re ".*Couldn't find .* registers in core file.*$gdb_prompt $" {
+ fail "re-load generated corefile (incomplete note section)"
+ }
+ -re "Core was generated by .*$gdb_prompt $" {
+ pass "re-load generated corefile"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "re-load generated corefile"
+ }
+ timeout {
+ fail "re-load generated corefile (timeout)"
+ }
+}
+
+# FIXME: now what can we test about the thread state?
+# We do not know for certain that there should be at least
+# three threads, because who knows what kind of many-to-one
+# mapping various OS's may do? Let's assume that there must
+# be at least two threads:
+
+gdb_test "info threads" ".*${nl} 2 ${horiz}${nl}\\* 1 .*" \
+ "corefile contains at least two threads"
+
+# One thread in the corefile should be in the "thread2" function.
+
+gdb_test "info threads" ".* thread2 .*" \
+ "a corefile thread is executing thread2"
+
+# The thread2 thread should be marked as the current thread.
+
+gdb_test "info threads" ".*${nl}\\* ${horiz} thread2 .*" \
+ "thread2 is current thread in corefile"
+
+set timeout $prev_timeout
Index: bp_in_thread.c
===================================================================
--- bp_in_thread.c (nonexistent)
+++ bp_in_thread.c (revision 816)
@@ -0,0 +1,73 @@
+/* A small multi-threaded test case.
+
+ Copyright 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+
+void
+cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut)
+{
+ pthread_mutex_lock(mut);
+ pthread_cond_wait (cond, mut);
+ pthread_mutex_unlock (mut);
+}
+
+void
+noreturn (void)
+{
+ pthread_mutex_t mut;
+ pthread_cond_t cond;
+
+ pthread_mutex_init (&mut, NULL);
+ pthread_cond_init (&cond, NULL);
+
+ /* Wait for a condition that will never be signaled, so we effectively
+ block the thread here. */
+ cond_wait (&cond, &mut);
+}
+
+void *
+forever_pthread (void *unused)
+{
+ noreturn ();
+}
+
+void
+break_me (void)
+{
+ /* Just an anchor to help putting a breakpoint. */
+}
+
+int
+main (void)
+{
+ pthread_t forever;
+ const struct timespec ts = { 0, 10000000 }; /* 0.01 sec */
+
+ pthread_create (&forever, NULL, forever_pthread, NULL);
+ for (;;)
+ {
+ nanosleep (&ts, NULL);
+ break_me();
+ }
+
+ return 0;
+}
+
bp_in_thread.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: pthread_cond_wait.c
===================================================================
--- pthread_cond_wait.c (nonexistent)
+++ pthread_cond_wait.c (revision 816)
@@ -0,0 +1,73 @@
+/* A small multi-threaded test case.
+
+ Copyright 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+
+void
+cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut)
+{
+ pthread_mutex_lock(mut);
+ pthread_cond_wait (cond, mut);
+ pthread_mutex_unlock (mut);
+}
+
+void
+noreturn (void)
+{
+ pthread_mutex_t mut;
+ pthread_cond_t cond;
+
+ pthread_mutex_init (&mut, NULL);
+ pthread_cond_init (&cond, NULL);
+
+ /* Wait for a condition that will never be signaled, so we effectively
+ block the thread here. */
+ cond_wait (&cond, &mut);
+}
+
+void *
+forever_pthread (void *unused)
+{
+ noreturn ();
+}
+
+void
+break_me (void)
+{
+ /* Just an anchor to help putting a breakpoint. */
+}
+
+int
+main (void)
+{
+ pthread_t forever;
+ const struct timespec ts = { 0, 10000000 }; /* 0.01 sec */
+
+ pthread_create (&forever, NULL, forever_pthread, NULL);
+ for (;;)
+ {
+ nanosleep (&ts, NULL);
+ break_me();
+ }
+
+ return 0;
+}
+
pthread_cond_wait.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: tls-shared.exp
===================================================================
--- tls-shared.exp (nonexistent)
+++ tls-shared.exp (revision 816)
@@ -0,0 +1,111 @@
+# Copyright 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see . */
+
+# tls-shared.exp -- Expect script to test thread local storage in gdb, with
+# shared libraries.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile tls-main
+set libfile tls-shared
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+remote_exec build "rm -f ${binfile}"
+
+# get the value of gcc_compiled
+if [get_compiler_info ${binfile}] {
+ return -1
+}
+
+if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}.o" object {debug}] != "" } {
+ return -1
+}
+
+# Build the shared libraries this test case needs.
+#
+
+if {$gcc_compiled == 0} {
+ if [istarget "hppa*-hp-hpux*"] then {
+ set additional_flags "additional_flags=+z"
+ } elseif { [istarget "mips-sgi-irix*"] } {
+ # Disable SGI compiler's implicit -Dsgi
+ set additional_flags "additional_flags=-Usgi"
+ } else {
+ # don't know what the compiler is...
+ set additional_flags ""
+ }
+} else {
+ if { ([istarget "powerpc*-*-aix*"]
+ || [istarget "rs6000*-*-aix*"]) } {
+ set additional_flags ""
+ } else {
+ set additional_flags "additional_flags=-fpic"
+ }
+}
+
+set additional_flags "$additional_flags -shared"
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${libfile}.c" "${objdir}/${subdir}/${libfile}.so" executable [list debug $additional_flags "incdir=${objdir}"]] != ""} {
+ return -1
+}
+
+if { ($gcc_compiled
+&& ([istarget "powerpc*-*-aix*"]
+|| [istarget "rs6000*-*-aix*"] )) } {
+ set additional_flags "additional_flags=-L${objdir}/${subdir}"
+} elseif { [istarget "mips-sgi-irix*"] } {
+ set additional_flags "additional_flags=-rpath ${objdir}/${subdir}"
+} else {
+ set additional_flags ""
+}
+
+if {[gdb_compile_pthreads "${objdir}/${subdir}/${testfile}.o ${objdir}/${subdir}/${libfile}.so" "${binfile}" executable [list debug $additional_flags]] != ""} {
+ return -1
+}
+
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+gdb_test "print i_tls" "2" "print thread local storage variable"
+
+gdb_test "ptype i_tls" "int" "ptype of thread local storage variable"
+
+gdb_test "info address i_tls" \
+ "Symbol \\\"i_tls\\\" is a thread-local variable at offset 0x0 in the thread-local storage for .*tls-main.." \
+ "print storage info for thread local storage variable"
+
+set line_number [gdb_get_line_number "break here to check result"]
+
+gdb_test "break $line_number" \
+ "Breakpoint.*at.*file.*tls-main.c.*line ${line_number}." \
+ "break at and of main"
+gdb_test "continue" \
+ "main .* at .*:.*return 0.*break here to check result.*" \
+ "continue to break"
+# This is more of a gcc/glibc test, really.
+#
+gdb_test "print result" "3" "print result"
+
+
Index: attach-stopped.c
===================================================================
--- attach-stopped.c (nonexistent)
+++ attach-stopped.c (revision 816)
@@ -0,0 +1,50 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+/* This program is intended to be started outside of gdb, then
+ manually stopped via a signal. */
+
+#include
+#include
+#ifdef USE_THREADS
+#include
+#endif
+
+static void *func (void *arg)
+{
+ sleep (10000); /* Ridiculous time, but we will eventually kill it. */
+ sleep (10000); /* Second sleep. */
+ return NULL;
+}
+
+int main ()
+{
+
+#ifndef USE_THREADS
+
+ func (NULL);
+
+#else
+
+ pthread_t th;
+ pthread_create (&th, NULL, func, NULL);
+ pthread_join (th, NULL);
+
+#endif
+
+ return 0;
+}
attach-stopped.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: attach-into-signal.c
===================================================================
--- attach-into-signal.c (nonexistent)
+++ attach-into-signal.c (revision 816)
@@ -0,0 +1,67 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+#include
+#include
+#ifdef USE_THREADS
+#include
+#endif
+
+void action(int sig, siginfo_t * info, void *uc)
+{
+ raise (SIGALRM);
+}
+
+static void *func (void *arg)
+{
+ struct sigaction act;
+
+ memset (&act, 0, sizeof(struct sigaction));
+ act.sa_sigaction = action;
+ act.sa_flags = SA_RESTART;
+ sigaction (SIGALRM, &act, 0);
+
+ raise (SIGALRM);
+
+ /* We must not get past this point, either in a free standing or debugged
+ state. */
+
+ abort ();
+ /* NOTREACHED */
+ return NULL;
+}
+
+int main ()
+{
+
+#ifndef USE_THREADS
+
+ func (NULL);
+
+#else
+
+ pthread_t th;
+ pthread_create (&th, NULL, func, NULL);
+ pthread_join (th, NULL);
+
+#endif
+
+ return 0;
+}
attach-into-signal.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: threadapply.exp
===================================================================
--- threadapply.exp (nonexistent)
+++ threadapply.exp (revision 816)
@@ -0,0 +1,76 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# This test verifies that a macro using backtrace can be applied to all threads
+# and will continue for each thread even though an error may occur in
+# backtracing one of the threads.
+
+set testfile "threadapply"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+# Break after all threads have been started.
+set break_line [gdb_get_line_number "Break here"]
+gdb_test "b $break_line" ""
+gdb_test "continue"
+
+gdb_test_multiple "define backthread" "defining macro" {
+ -re "Type commands for definition of \"backthread\".\r\nEnd with a line saying just \"end\".\r\n>$" {
+ gdb_test_multiple "bt\np/x 20\nend" "macro details" {
+ -re "$gdb_prompt $" {
+ pass "macro details"
+ }
+ }
+ pass "defining macro"
+ }
+}
+
+# Cause backtraces to fail by setting a limit. This allows us to
+# verify that the macro can get past the backtrace error and perform
+# subsequent commands.
+gdb_test "set backtrace limit 3" ""
+gdb_test "thread apply all backthread" "Thread ..*\\\$\[0-9]+ = 0x14.*Thread ..*\\\$\[0-9]+ = 0x14.*Thread ..*\\\$\[0-9]+ = 0x14.*Thread ..*\\\$\[0-9]+ = 0x14.*Thread ..*\\\$\[0-9]+ = 0x14.*Thread ..*\\\$\[0-9]+ = 0x14"
+
+# Go into the thread_function to check that a simple "thread apply"
+# does not change the selected frame.
+gdb_test "step" "thread_function.*" "step to the thread_function"
+gdb_test "up" ".*in main.*" "go up in the stack frame"
+gdb_test "thread apply all print 1" "Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1.*Thread ..*\\\$\[0-9]+ = 1" "run a simple print command on all threads"
+gdb_test "down" "#0.*thread_function.*" "go down and check selected frame"
Index: execl.c
===================================================================
--- execl.c (nonexistent)
+++ execl.c (revision 816)
@@ -0,0 +1,56 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+/* Test handling thread control across an execl. */
+
+/* The original image loads a thread library and has several threads,
+ while the new image does not load a thread library. */
+
+#include
+#include
+#include
+#include
+#include
+
+void *
+thread_function (void *arg)
+{
+ while (1)
+ sleep (100);
+ return NULL;
+}
+
+int
+main (int argc, char* argv[])
+{
+ pthread_t thread1;
+ pthread_t thread2;
+ char *new_image;
+
+ pthread_create (&thread1, NULL, thread_function, NULL);
+ pthread_create (&thread2, NULL, thread_function, NULL);
+
+ new_image = malloc (strlen (argv[0]) + 2);
+ strcpy (new_image, argv[0]);
+ strcat (new_image, "1");
+
+ if (execl (new_image, new_image, NULL) == -1) /* set breakpoint here */
+ return 1;
+
+ return 0;
+}
execl.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: fork-thread-pending.exp
===================================================================
--- fork-thread-pending.exp (nonexistent)
+++ fork-thread-pending.exp (revision 816)
@@ -0,0 +1,128 @@
+# Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# There's no support for `set follow-fork-mode' in the remote
+# protocol.
+if { [is_remote target] } {
+ return 0
+}
+
+# Only GNU/Linux is known to support `set follow-fork-mode child'.
+#
+if { ! [istarget "*-*-linux*"] } {
+ return 0
+}
+
+set testfile fork-thread-pending
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+gdb_test "set follow-fork-mode child" "" "1, set follow-fork-mode child"
+gdb_test "catch fork" "Catchpoint \[0-9\]* \\(fork\\)" "1, insert fork catchpoint"
+gdb_breakpoint "start" "" "1, set breakpoint at start"
+
+gdb_test "continue" "Catchpoint.*" "1, get to the fork event"
+
+gdb_test "info threads" " Thread .* Thread .* Thread .* Thread .*" "1, multiple threads found"
+
+gdb_test "thread 2" "" "1, switched away from event thread"
+
+gdb_test "continue" "Not resuming.*" "1, refused to resume"
+
+set test "1, followed to the child, found one thread"
+gdb_test_multiple "info threads" "metest" {
+ -re " Thread .* Thread .*$gdb_prompt $" {
+ fail "$test"
+ }
+ -re " Thread .*$gdb_prompt $" {
+ pass "$test"
+ }
+ -re "$gdb_prompt $" {
+ fail "$test (unknown output)"
+ }
+ timeout {
+ fail "$test (timeout)"
+ }
+}
+
+gdb_test "continue" "Breakpoint 3, start.*" "1, get to the spawned thread in fork child"
+
+set test "1, followed to the child, found two threads"
+gdb_test_multiple "info threads" "$test" {
+ -re " Thread .* Thread .* Thread .*$gdb_prompt $" {
+ fail "$test"
+ }
+ -re " Thread .* Thread .*$gdb_prompt $" {
+ pass "$test"
+ }
+ -re "$gdb_prompt $" {
+ fail "$test (unknown output)"
+ }
+ timeout {
+ fail "$test (timeout)"
+ }
+}
+
+# Start over, but this time, don't switch away from the fork event thread.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+gdb_test "set follow-fork-mode child" "" "2, set follow-fork-mode child"
+gdb_test "catch fork" "Catchpoint \[0-9\]* \\(fork\\)" "2, insert fork catchpoint"
+gdb_breakpoint "start"
+
+gdb_test "continue" "Catchpoint.*" "2, get to the fork event"
+
+gdb_test "info threads" " Thread .* Thread .* Thread .* Thread .*" "2, multiple threads found"
+
+gdb_test "continue" "Breakpoint 3, start.*" "2, get to the spawned thread in fork child"
+
+set test "2, followed to the child, found two threads"
+gdb_test_multiple "info threads" "$test" {
+ -re " Thread .* Thread .* Thread .*$gdb_prompt $" {
+ fail "$test"
+ }
+ -re " Thread .* Thread .*$gdb_prompt $" {
+ pass "$test"
+ }
+ -re "$gdb_prompt $" {
+ fail "$test (unknown output)"
+ }
+ timeout {
+ fail "$test (timeout)"
+ }
+}
Index: watchthreads2.c
===================================================================
--- watchthreads2.c (nonexistent)
+++ watchthreads2.c (revision 816)
@@ -0,0 +1,115 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ Check that watchpoints get propagated to all existing threads when the
+ watchpoint is created.
+*/
+
+#include
+#include
+#include
+#include
+#include
+
+#ifndef NR_THREADS
+#define NR_THREADS 4
+#endif
+
+#ifndef X_INCR_COUNT
+#define X_INCR_COUNT 10
+#endif
+
+void *thread_function (void *arg); /* Function executed by each thread. */
+
+pthread_mutex_t x_mutex;
+int x;
+
+/* Used to hold threads back until watchthreads2.exp is ready. */
+int test_ready = 0;
+
+int
+main ()
+{
+ int res;
+ pthread_t threads[NR_THREADS];
+ int i;
+
+ pthread_mutex_init (&x_mutex, NULL);
+
+ for (i = 0; i < NR_THREADS; ++i)
+ {
+ res = pthread_create (&threads[i],
+ NULL,
+ thread_function,
+ (void *) (intptr_t) i);
+ if (res != 0)
+ {
+ fprintf (stderr, "error in thread %d create\n", i);
+ abort ();
+ }
+ }
+
+ for (i = 0; i < NR_THREADS; ++i)
+ {
+ res = pthread_join (threads[i], NULL);
+ if (res != 0)
+ {
+ fprintf (stderr, "error in thread %d join\n", i);
+ abort ();
+ }
+ }
+
+ exit (EXIT_SUCCESS);
+}
+
+/* Easy place for a breakpoint.
+ watchthreads2.exp uses this to track when all threads are running
+ instead of, for example, the program keeping track
+ because we don't need the program to know when all threads are running,
+ instead we need gdb to know when all threads are running.
+ There is a delay between when a thread has started and when the thread
+ has been registered with gdb. */
+
+void
+thread_started ()
+{
+}
+
+void *
+thread_function (void *arg)
+{
+ int i;
+
+ thread_started ();
+
+ /* Don't start incrementing X until watchthreads2.exp is ready. */
+ while (! test_ready)
+ usleep (1);
+
+ for (i = 0; i < X_INCR_COUNT; ++i)
+ {
+ pthread_mutex_lock (&x_mutex);
+ /* For debugging. */
+ printf ("Thread %ld changing x %d -> %d\n", (long) arg, x, x + 1);
+ /* The call to usleep is so that when the watchpoint triggers,
+ the pc is still on the same line. */
+ ++x; usleep (1); /* X increment. */
+ pthread_mutex_unlock (&x_mutex);
+ }
+
+ pthread_exit (NULL);
+}
watchthreads2.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: switch-threads.exp
===================================================================
--- switch-threads.exp (nonexistent)
+++ switch-threads.exp (revision 816)
@@ -0,0 +1,48 @@
+# Copyright (C) 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file was written by Daniel Jacobowitz .
+#
+# It tests that the correct thread is single-stepped. Prior to the
+# introduction of vCont, we didn't pass enough information to remote
+# multi-threaded stubs to reliably get this correct; gdbserver defaulted
+# to the first thread.
+
+# TODO: we should also test explicitly changing threads with the "thread"
+# command.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile "switch-threads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+runto_main
+
+gdb_breakpoint thread_func
+gdb_continue_to_breakpoint "continue to thread_func"
+gdb_test "next" ".*foo \\(\\);"
+
Index: thread-specific.exp
===================================================================
--- thread-specific.exp (nonexistent)
+++ thread-specific.exp (revision 816)
@@ -0,0 +1,114 @@
+# Copyright 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file was written by Daniel Jacobowitz .
+# It tests that the correct breakpoint is reported when we hit a
+# thread-specific breakpoint inserted for several threads.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "thread-specific"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+# Return a list of the valid thread IDs, with the initial thread first.
+proc get_thread_list { } {
+ global gdb_prompt
+ global expect_out
+
+ set thr_list ""
+
+ gdb_test_multiple "info threads" "get threads list" {
+ -re "info threads\r\n" {
+ exp_continue
+ }
+ -re "New Thread \[^\n\]*\n" {
+ exp_continue
+ }
+ -re "^\\* *(\[0-9\]*) Thread \[^\n\]*main\[^\n\]*\n" {
+ set thr_list "$expect_out(1,string) $thr_list"
+ exp_continue
+ }
+ -re "^ *(\[0-9\]*) Thread \[^\n\]*\n" {
+ lappend thr_list $expect_out(1,string)
+ exp_continue
+ }
+ -re ".*$gdb_prompt $" {
+ if { [llength $thr_list] != 0 } {
+ pass "get threads list"
+ } else {
+ fail "get threads list (no threads)"
+ }
+ }
+ }
+
+ return $thr_list
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+
+gdb_test "set print sevenbit-strings" ""
+gdb_test "set width 0" ""
+
+runto_main
+
+gdb_breakpoint [gdb_get_line_number "thread-specific.exp: last thread start"]
+gdb_continue_to_breakpoint "all threads started"
+
+set line [gdb_get_line_number "thread-specific.exp: thread loop"]
+set threads [get_thread_list]
+
+if {[llength $threads] == 0} {
+ # We have already issued a FAIL above.
+ return 1
+}
+
+gdb_test_multiple "break $line thread [lindex $threads 0]" \
+ "breakpoint $line main thread" {
+ -re "Breakpoint (\[0-9\]*) at.* file .*$srcfile, line.*$gdb_prompt $" {
+ set main_breakpoint $expect_out(1,string)
+ pass "breakpoint $line main thread"
+ }
+}
+
+foreach thread [lrange $threads 1 end] {
+ gdb_breakpoint "$line thread $thread"
+}
+
+gdb_test_multiple "continue" "continue to thread-specific breakpoint" {
+ -re "Breakpoint $main_breakpoint, .* at .*\r\n$gdb_prompt $" {
+ fail "continue to thread-specific breakpoint (wrong breakpoint)"
+ }
+ -re "Breakpoint .* at .*\r\n$gdb_prompt $" {
+ pass "continue to thread-specific breakpoint"
+ }
+}
+
+return 0
Index: thread_events.exp
===================================================================
--- thread_events.exp (nonexistent)
+++ thread_events.exp (revision 816)
@@ -0,0 +1,152 @@
+# Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file was written by Chris Demetriou (cgd@google.com).
+# It tests printing of thread event (start, exit) information, and
+# disabling of those messages.
+#
+# Note: the format of thread event messages (and also whether or not
+# messages are printed and can be disabled) is dependent on the target
+# thread support code.
+
+# This test has only been verified with Linux targets, and would need
+# to be generalized to support other targets
+if ![istarget *-*-linux*] then {
+ return
+}
+
+# When using gdbserver, even on Linux, we don't get notifications
+# about new threads. This is expected, so don't test for that.
+if [is_remote target] then {
+ return
+}
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "thread_events"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+proc gdb_test_thread_start {messages_enabled command pattern message} {
+ global gdb_prompt
+
+ if { $messages_enabled } {
+ set events_expected 1
+ } else {
+ set events_expected 0
+ }
+ set events_seen 0
+
+ return [gdb_test_multiple $command $message {
+ -re "\\\[New Thread \[^\]\]*\\\]\r\n" {
+ incr events_seen;
+ exp_continue;
+ }
+ -re "\[\r\n\]*($pattern)\[\r\n\]+$gdb_prompt $" {
+ if { $events_seen != $events_expected } {
+ fail "$message (saw $events_seen, expected $events_expected)"
+ } else {
+ pass "$message"
+ }
+ }
+ }]
+}
+
+proc gdb_test_thread_exit {messages_enabled command pattern message} {
+ global gdb_prompt
+
+ if { $messages_enabled } {
+ set events_expected 1
+ } else {
+ set events_expected 0
+ }
+ set events_seen 0
+
+ return [gdb_test_multiple $command $message {
+ -re "\\\[Thread \[^\]\]* exited\\\]\r\n" {
+ incr events_seen
+ exp_continue;
+ }
+ -re "\[\r\n\]*($pattern)\[\r\n\]+$gdb_prompt $" {
+ if { $events_seen != $events_expected } {
+ fail "$message (saw $events_seen, expected $events_expected)"
+ } else {
+ pass "$message"
+ }
+ }
+ }]
+}
+
+proc test_thread_messages {enabled} {
+ global srcdir subdir binfile srcfile
+
+ if { $enabled } {
+ set enabled_string "with messages enabled"
+ } else {
+ set enabled_string "with messages disabled"
+ }
+
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+
+ if { $enabled } {
+ gdb_test "set print thread-events on"
+ } else {
+ gdb_test "set print thread-events off"
+ }
+
+ # The initial thread may log a 'New Thread' message, but we don't
+ # check for it.
+ if ![runto_main] then {
+ fail "Can't run to main $enabled_string"
+ return 1
+ }
+
+ gdb_test "break threadfunc" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint at threadfunc $enabled_string"
+ gdb_test "break after_join_func" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint at after_join_func $enabled_string"
+
+ # continue to threadfunc breakpoint. A thread will start.
+ # Expect to see a thread start message, if messages are enabled.
+ gdb_test_thread_start $enabled "continue" \
+ ".*Breakpoint .*,.*threadfunc.*at.*$srcfile:.*" \
+ "continue to threadfunc $enabled_string"
+
+ # continue to after_join_func breakpoint. A thread will exit.
+ # Expect to see a thread exit message, if messages are enabled.
+ gdb_test_thread_exit $enabled "continue" \
+ ".*Breakpoint .*,.*after_join_func.*at.*$srcfile:.*" \
+ "continue to after_join_func $enabled_string"
+
+ delete_breakpoints
+
+ gdb_exit
+}
+
+test_thread_messages 0
+test_thread_messages 1
Index: tls-shared.c
===================================================================
--- tls-shared.c (nonexistent)
+++ tls-shared.c (revision 816)
@@ -0,0 +1,6 @@
+__thread int i_tls = 1;
+int foo ()
+{
+ return i_tls;
+}
+
tls-shared.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: local-watch-wrong-thread.exp
===================================================================
--- local-watch-wrong-thread.exp (nonexistent)
+++ local-watch-wrong-thread.exp (revision 816)
@@ -0,0 +1,122 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This test verifies that a local watchpoint isn't deleted when a
+# thread other than the thread the local watchpoint was set in stops
+# for a breakpoint.
+
+if [target_info exists gdb,no_hardware_watchpoints] {
+ return 0;
+}
+
+set testfile "local-watch-wrong-thread"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if {[gdb_compile_pthreads \
+ "${srcdir}/${subdir}/${srcfile}" \
+ "${binfile}" executable {debug} ] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set can-use-hw-watchpoints 1" "" ""
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return
+}
+
+set inc_line_1 [gdb_get_line_number "Loop increment 1"]
+set inc_line_2 [gdb_get_line_number "Loop increment 2"]
+set bkpt_here [gdb_get_line_number "set breakpoint here"]
+
+# Run to the loop within thread_function0, so we can set our local
+# watchpoint.
+gdb_test "break ${srcfile}:${inc_line_1}" \
+ "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on thread_function0"
+
+gdb_test "continue" \
+ ".*Breakpoint 2.*thread_function0.*" \
+ "continue to thread_function0"
+
+delete_breakpoints
+
+# Set the local watchpoint, and confirm that it traps as expected.
+gdb_test "watch *myp" \
+ "Hardware watchpoint 3\: \\*myp.*" \
+ "set local watchpoint on *myp"
+
+gdb_test "continue" \
+ "Hardware watchpoint.*Old value.*New value.*thread_function0.*" \
+ "local watchpoint triggers"
+
+delete_breakpoints
+
+# Recreate the watchpoint, but this time with a condition we know
+# won't trigger. This is so the watchpoint is inserted, and the
+# target reports events, but GDB doesn't stop for them. We want to
+# hit the breakpoints on the other thread, and make sure this
+# watchpoint isn't deleted then.
+gdb_test "watch *myp if trigger != 0" \
+ "Hardware watchpoint 4\: \\*myp.*" \
+ "set local watchpoint on *myp, with false conditional"
+
+# Run to a breakpoint on a different thread. The previous local
+# watchpoint should not be deleted with the standard 'the program has
+# left the block in which its expression is valid', because the
+# thread_function0 thread should still be running in the loop.
+gdb_test "break ${srcfile}:${inc_line_2}" \
+ "Breakpoint 5 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on the other thread"
+
+gdb_test "continue" \
+ "Breakpoint 5, thread_function1.*" \
+ "the other thread stopped on breakpoint"
+
+# Delete the new breakpoint, we don't need it anymore.
+gdb_test "delete 5" "" ""
+
+# Check if the local watchpoint hasn't been deleted (is still listed).
+# This is simpler to check than expecting 'the program has left ...',
+# and, is immune to string changes in that warning.
+gdb_test "info breakpoints" \
+ ".*4.*hw watchpoint.*keep.*y.*\\*myp.*" \
+ "local watchpoint is still in breakpoint list"
+
+# Make the watchpoint condition eval true.
+gdb_test "set trigger=1" "" "let local watchpoint trigger"
+
+gdb_test "continue" \
+ "Hardware watchpoint.*Old value.*New value.*thread_function0.*" \
+ "local watchpoint still triggers"
+
+# Confirm that the local watchpoint is indeed deleted when
+# thread_function0 returns.
+gdb_test "set *myp=0" "" "let thread_function0 return"
+
+gdb_test "break ${srcfile}:${bkpt_here}" \
+ "Breakpoint 6 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on thread_function0's caller"
+
+gdb_test "continue" \
+ ".*Watchpoint.*deleted.*" \
+ "local watchpoint automatically deleted"
Index: pending-step.exp
===================================================================
--- pending-step.exp (nonexistent)
+++ pending-step.exp (revision 816)
@@ -0,0 +1,95 @@
+# Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Test that a resume cancels a previously unfinished or unreported
+# single-step correctly.
+#
+# The test consists of several threads all running the same loop.
+# There is a breakpoint set in the loop, hence all threads may hit it.
+# The test then issues several "next" commands in a loop.
+#
+# scheduler-locking must be set to the default of "off".
+#
+# Here's what would happen in gdbserver:
+#
+# 1) We issue a "continue", and wait until a thread hits the
+# breakpoint. Could be any thread, but assume thread 1 hits it.
+#
+# 2) We issue a "next" --- this single-steps thread 1, and resumes all
+# other threads.
+#
+# 3) thread 2, due to scheduler-locking off, hits the breakpoint.
+# gdbserver stops all other threads by sending them SIGSTOPs.
+#
+# 4) While being stopped in step 3, thread 1 reports a SIGTRAP, that
+# corresponds to the finished single-step of step 2. gdbserver
+# leaves the SIGTRAP pending to report later.
+#
+# 5) We issue another "next" --- this requests thread 2 to
+# single-step, and all other threads to continue, including thread
+# 1. Before resuming any thread, gdbserver notices that it
+# remembers from step 4 a pending SIGTRAP to report for thread 1,
+# so reports it now.
+#
+# 6) From GDB's perpective, this SIGTRAP can't represent a finished
+# single-step, since thread 1 was not single-stepping (it was
+# continued in step 5). Neither does this SIGTRAP correspond to a
+# breakpoint hit. GDB reports to the user a spurious SIGTRAP.
+
+set testfile "pending-step"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+gdb_breakpoint [gdb_get_line_number "insert breakpoint here"]
+gdb_continue_to_breakpoint "continue to first breakpoint hit"
+
+set test "next in multiple threads with breakpoints"
+set iterations 20
+set ok 0
+for {set i 0} {$i < $iterations} {incr i} {
+ set ok 0
+ gdb_test_multiple "next" "$test" {
+ -re "SIGTRAP.*$gdb_prompt $" {
+ fail "$test (spurious SIGTRAP)"
+ }
+ -re "$gdb_prompt $" {
+ set ok 1
+ }
+ }
+
+ if { $ok == 0 } {
+ break
+ }
+}
+
+if { $ok } {
+ pass "$test"
+}
Index: step.c
===================================================================
--- step.c (nonexistent)
+++ step.c (revision 816)
@@ -0,0 +1,221 @@
+/* step.c for step.exp */
+#include
+#include
+#include
+#include
+#include
+
+void alarm_handler ();
+void alarm_handler1 ();
+void alarm_handler2 ();
+void thread1 ();
+void thread2 ();
+
+#define TIME_LIMIT 30
+
+
+int count1 = 0;
+int count2 = 0;
+
+pthread_t tid1, tid2;
+pthread_attr_t attr1, attr2;
+
+pthread_mutex_t mut;
+pthread_mutexattr_t mut_attr;
+
+pthread_condattr_t cv_attr_a, cv_attr_b;
+pthread_cond_t cv_a, cv_b;
+
+struct cv_struct
+ {
+ char a;
+ char b;
+ }
+test_struct;
+
+main ()
+{
+ /*init la struct */
+ test_struct.a = 0;
+ test_struct.b = 1;
+
+ /* create le mutex */
+ if (pthread_mutexattr_create (&mut_attr) == -1)
+ {
+ perror ("mutexattr_create");
+ exit (1);
+ }
+
+
+ if (pthread_mutex_init (&mut, mut_attr) == -1)
+ {
+ perror ("mutex_init");
+ exit (1);
+ }
+
+ /* create 2 cv */
+ if (pthread_condattr_create (&cv_attr_a) == -1)
+ {
+ perror ("condattr_create(1)");
+ exit (1);
+ }
+
+ if (pthread_cond_init (&cv_a, cv_attr_a) == -1)
+ {
+ perror ("cond_init(1)");
+ exit (1);
+ }
+
+ if (pthread_condattr_create (&cv_attr_b) == -1)
+ {
+ perror ("condattr_create(2)");
+ exit (1);
+ }
+
+ if (pthread_cond_init (&cv_b, cv_attr_b) == -1)
+ {
+ perror ("cond_init(2)");
+ exit (1);
+ }
+
+ /* create 2 threads of execution */
+ if (pthread_attr_create (&attr1) == -1)
+ {
+ perror ("attr_create(1)");
+ exit (1);
+ }
+
+ if (pthread_create (&tid1, attr1, thread1, &count1) == -1)
+ {
+ perror ("pthread_create(1)");
+ exit (1);
+ }
+
+ if (pthread_attr_create (&attr2) == -1)
+ {
+ perror ("attr_create(2)");
+ exit (1);
+ }
+
+ if (pthread_create (&tid2, attr2, thread2, &count2) == -1)
+ {
+ perror ("pthread_create(2)");
+ exit (1);
+ }
+
+ /* set alarm to print out data and exit */
+ signal (SIGALRM, alarm_handler);
+ alarm (TIME_LIMIT);
+
+ for (;;)
+ pause ();
+}
+
+void
+thread1 (count)
+ int *count;
+{
+ tid_t tid;
+
+ tid = getstid ();
+ printf ("Thread1 tid 0x%x (%d) \n", tid, tid);
+ printf ("Thread1 @tid=0x%x \n", &tid);
+ signal (SIGALRM, alarm_handler1);
+
+ for (;;)
+ {
+ if (pthread_mutex_lock (&mut) == -1)
+ {
+ perror ("pthread_mutex_lock(1)");
+ pthread_exit ((void *) 0);
+ }
+
+ while (test_struct.a == 0)
+ {
+ if (pthread_cond_wait (&cv_a, &mut) == -1)
+ {
+ perror ("pthread_cond_wait(1)");
+ pthread_exit ((void *) -1);
+ }
+ }
+
+ (*count)++;
+ printf ("*******thread1 count %d\n", *count);
+
+ test_struct.a = 0;
+
+ test_struct.b = 1;
+ pthread_cond_signal (&cv_b);
+
+ if (pthread_mutex_unlock (&mut) == -1)
+ {
+ perror ("pthread_mutex_unlock(1)");
+ pthread_exit ((void *) -1);
+ }
+ }
+}
+
+void
+thread2 (count)
+ int *count;
+{
+ tid_t tid;
+
+ tid = getstid ();
+ printf ("Thread2 tid 0x%x (%d) \n", tid, tid);
+ printf ("Thread1 @tid=0x%x \n", &tid);
+ signal (SIGALRM, alarm_handler2);
+
+ for (;;)
+ {
+ if (pthread_mutex_lock (&mut) == -1)
+ {
+ perror ("pthread_mutex_lock(2)");
+ pthread_exit ((void *) 0);
+ }
+
+ while (test_struct.b == 0)
+ {
+ if (pthread_cond_wait (&cv_b, &mut) == -1)
+ {
+ perror ("pthread_cond_wait(2)");
+ pthread_exit ((void *) -1);
+ }
+ }
+
+ (*count)++;
+ printf ("*******thread2 count %d\n", *count);
+
+ test_struct.b = 0;
+
+ test_struct.a = 1;
+ pthread_cond_signal (&cv_a);
+
+ if (pthread_mutex_unlock (&mut) == -1)
+ {
+ perror ("pthread_mutex_unlock(2)");
+ pthread_exit ((void *) -1);
+ }
+ }
+}
+
+
+void
+alarm_handler ()
+{
+ printf ("\tcount1 (%d) \n\tcount2 (%d)\n", count1, count2);
+ exit (0);
+}
+
+void
+alarm_handler1 ()
+{
+ printf ("ALARM thread 1\n");
+}
+
+void
+alarm_handler2 ()
+{
+ printf ("ALARM thread 2\n");
+ pthread_exit ((void *) 0);
+}
step.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: tls.exp
===================================================================
--- tls.exp (nonexistent)
+++ tls.exp (revision 816)
@@ -0,0 +1,308 @@
+# tls.exp -- Expect script to test thread-local storage
+# Copyright (C) 1992, 2003, 2007, 2008, 2009, 2010
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see . */
+
+set testfile tls
+set testfile2 tls2
+set srcfile ${testfile}.c
+set srcfile2 ${testfile2}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if [istarget "*-*-linux"] then {
+ set target_cflags "-D_MIT_POSIX_THREADS"
+} else {
+ set target_cflags ""
+}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile} ${srcdir}/${subdir}/${srcfile2}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+### Compute the value of the a_thread_local variable.
+proc compute_expected_value {value} {
+ set expected_value 0
+ set i 0
+ while { $i <= $value} {
+ incr expected_value $i
+ incr i
+ }
+ return $expected_value
+}
+
+### Get the value of the variable 'me' for the current thread.
+proc get_me_variable {tnum} {
+ global expect_out
+ global gdb_prompt
+ global decimal
+
+ set value_of_me -1
+ send_gdb "print me\n"
+ gdb_expect {
+ -re ".*= ($decimal).*\r\n$gdb_prompt $" {
+ set value_of_me $expect_out(1,string)
+ pass "$tnum thread print me"
+ }
+ -re "$gdb_prompt $" {
+ fail "$tnum thread print me"
+ }
+ timeout {
+ fail "$tnum thread print me (timeout)"
+ }
+ }
+ return ${value_of_me}
+}
+
+### Check the values of the thread local variables in the thread.
+### Also check that info address print the right things.
+proc check_thread_local {number} {
+ set me_variable [get_me_variable $number]
+ set expected_value [compute_expected_value ${me_variable}]
+
+ gdb_test "p a_thread_local" \
+ "= $expected_value" \
+ "${number} thread local storage"
+
+ gdb_test "p another_thread_local" \
+ "= $me_variable" \
+ "${number} another thread local storage"
+
+ gdb_test "info address a_thread_local" \
+ ".*a_thread_local.*a thread-local variable at offset.*" \
+ "${number} info address a_thread_local"
+
+ gdb_test "info address another_thread_local" \
+ ".*another_thread_local.*a thread-local variable at offset.*" \
+ "${number} info address another_thread_local"
+}
+
+### Select a particular thread.
+proc select_thread {thread} {
+ global gdb_prompt
+
+ send_gdb "thread $thread\n"
+ gdb_expect {
+ -re "\\\[Switching to thread .*\\\].*\r\n$gdb_prompt $" {
+ pass "selected thread: $thread"
+ }
+ -re "$gdb_prompt $" {
+ fail "selected thread: $thread"
+ }
+ timeout {
+ fail "selected thread: $thread (timeout)"
+ }
+ }
+}
+
+### Do a backtrace for the current thread, and check that the 'spin' routine
+### is in it. This means we have one of the threads we created, rather
+### than the main thread. Record the thread in the spin_threads
+### array. Also remember the level of the 'spin' routine in the backtrace, for
+### later use.
+proc check_thread_stack {number spin_threads spin_threads_level} {
+ global gdb_prompt
+ global expect_out
+ global decimal
+ global hex
+ upvar $spin_threads tarr
+ upvar $spin_threads_level tarrl
+
+ select_thread $number
+ send_gdb "where\n"
+ gdb_expect {
+ -re ".*(\[0-9\]+)\[ \t\]+$hex in spin \\(vp=(0x\[0-9a-f\]+).*\r\n$gdb_prompt $" {
+ if {[info exists tarr($number)]} {
+ fail "backtrace of thread number $number in spin"
+ } else {
+ pass "backtrace of thread number $number in spin"
+ set level $expect_out(1,string)
+ set tarrl($number) $level
+ set tarr($number) 1
+ }
+ }
+ -re ".*$gdb_prompt $" {
+ set tarr($number) 0
+ set tarrl($number) 0
+ pass "backtrace of thread number $number not relevant"
+ }
+ timeout {
+ fail "backtrace of thread number $number (timeout)"
+ }
+ }
+}
+
+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 a breakpoint at the "spin" routine to
+# test the thread local's value.
+#
+gdb_test "b [gdb_get_line_number "here we know tls value"]" \
+ ".*Breakpoint 2.*tls.*" "set breakpoint at all threads"
+
+# Set a bp at a point where we know all threads are alive.
+#
+gdb_test "b [gdb_get_line_number "still alive"]" \
+ ".*Breakpoint 3.*tls.*" "set breakpoint at synch point"
+
+# Set a bp at the end to see if all threads are finished.
+#
+gdb_test "b [gdb_get_line_number "before exit"]" \
+ ".*Breakpoint 4.*tls.*" "set breakpoint at exit"
+
+send_gdb "continue\n"
+gdb_expect {
+ -re ".*Program received signal SIGSEGV.*a_thread_local = 0;.*$gdb_prompt $" {
+ # This is the first symptom if the gcc and binutils versions
+ # in use support TLS, but the system glibc does not.
+ unsupported "continue to first thread: system does not support TLS"
+ return -1
+ }
+ -re ".*Program exited normally.*$gdb_prompt $" {
+ fail "continue to first thread: program runaway"
+ }
+ -re ".*Pass 0 done.*Pass 1 done.*$gdb_prompt $" {
+ fail "continue to first thread: program runaway 2"
+ }
+ -re ".*Breakpoint 2.*tls value.*$gdb_prompt $" {
+ pass "continue to first thread: get to thread"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "continue to first thread: no progress?"
+ }
+ timeout { fail "continue to first thread (timeout)" }
+}
+
+gdb_test "info thread" ".*Thread.*spin.*" \
+ "at least one th in spin while stopped at first th"
+
+check_thread_local "first"
+
+gdb_test "continue" ".*Breakpoint 2.*tls value.*" "continue to second thread"
+gdb_test "info thread" "Thread.*spin.*" \
+ "at least one th in spin while stopped at second th"
+
+check_thread_local "second"
+
+gdb_test "continue" ".*Breakpoint 2.*tls value.*" "continue to third thread"
+gdb_test "info thread" ".*Thread.*spin.*" \
+ "at least one th in spin while stopped at third th"
+
+check_thread_local "third"
+
+gdb_test "continue" ".*Breakpoint 3.*still alive.*" "continue to synch point"
+
+set no_of_threads 0
+send_gdb "info thread\n"
+gdb_expect {
+ -re "^info thread\[ \t\r\n\]+(\[0-9\]+) Thread.*$gdb_prompt $" {
+ set no_of_threads $expect_out(1,string)
+ pass "get number of threads"
+ }
+ -re "$gdb_prompt $" {
+ fail "get number of threads"
+ }
+ timeout {
+ fail "get number of threads (timeout)"
+ }
+}
+
+array set spin_threads {}
+unset spin_threads
+array set spin_threads_level {}
+unset spin_threads_level
+
+# For each thread check its backtrace to see if it is stopped at the
+# spin routine.
+for {set i 1} {$i <= $no_of_threads} {incr i} {
+ check_thread_stack $i spin_threads spin_threads_level
+}
+
+### Loop through the threads and check the values of the tls variables.
+### keep track of how many threads we find in the spin routine.
+set thrs_in_spin 0
+foreach i [array names spin_threads] {
+ if {$spin_threads($i) == 1} {
+ incr thrs_in_spin
+ select_thread $i
+ set level $spin_threads_level($i)
+ # We expect to be in sem_wait, but if the thread has not yet
+ # been scheduled, we might be in sem_post still. We could be at
+ # any intermediate point in spin, too, but that is much less
+ # likely.
+ gdb_test "up $level" ".*spin.*sem_(wait|post).*" "thread $i up"
+ check_thread_local $i
+ }
+}
+
+if {$thrs_in_spin == 0} {
+ fail "No thread backtrace reported spin (vsyscall kernel problem?)"
+}
+
+gdb_test "continue" ".*Breakpoint 4.*before exit.*" "threads exited"
+
+send_gdb "info thread\n"
+gdb_expect {
+ -re ".* 1 Thread.*2 Thread.*$gdb_prompt $" {
+ fail "Too many threads left at end"
+ }
+ -re ".*\\\* 1 Thread.*main.*$gdb_prompt $" {
+ pass "Expect only base thread at end"
+ }
+ -re ".*No stack.*$gdb_prompt $" {
+ fail "runaway at end"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "mess at end"
+ }
+ timeout { fail "at end (timeout)" }
+}
+
+# Start over and do some "info address" stuff
+#
+runto spin
+
+gdb_test "info address a_global" \
+ ".*a_global.*static storage at address.*" "info address a_global"
+
+setup_kfail "gdb/1294" "*-*-*"
+gdb_test "info address me" ".*me.*is a variable at offset.*" "info address me"
+
+
+# Test LOC_UNRESOLVED references resolving for `extern' TLS variables.
+
+gdb_test "p a_thread_local" " = \[0-9\]+"
+# Here it could crash with: Cannot access memory at address 0x0
+gdb_test "p file2_thread_local" " = \[0-9\]+"
+# Depending on the current lookup scope we get LOC_UNRESOLVED or LOC_COMPUTED
+# both printing:
+# Symbol "file2_thread_local" is a thread-local variable at offset 8 in the thread-local storage for `.../gdb.threads/tls'.
+gdb_test "info address file2_thread_local" "Symbol \"file2_thread_local\" is a thread-local variable.*"
+# Here it could also crash with: Cannot access memory at address 0x0
+gdb_test "p a_thread_local" " = \[0-9\]+" "p a_thread_local second time"
+gdb_test "info address a_thread_local" "Symbol \"a_thread_local\" is a thread-local variable.*"
+
+# Done!
+#
+gdb_exit
+
+return 0
Index: manythreads.c
===================================================================
--- manythreads.c (nonexistent)
+++ manythreads.c (revision 816)
@@ -0,0 +1,69 @@
+/* Manythreads test program.
+ Copyright 2004, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ Written by Jeff Johnston
+ Contributed by Red Hat
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+
+void *
+thread_function (void *arg)
+{
+ int x = * (int *) arg;
+
+ printf ("Thread <%d> executing\n", x);
+
+ return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+ pthread_attr_t attr;
+ pthread_t threads[256];
+ int args[256];
+ int i, j;
+
+ pthread_attr_init (&attr);
+
+#ifdef PTHREAD_STACK_MIN
+ pthread_attr_setstacksize (&attr, 2*PTHREAD_STACK_MIN);
+#endif
+
+ /* Create a ton of quick-executing threads, then wait for them to
+ complete. */
+ for (i = 0; i < 1000; ++i)
+ {
+ for (j = 0; j < 256; ++j)
+ {
+ args[j] = i * 1000 + j;
+ pthread_create (&threads[j], &attr, thread_function, &args[j]);
+ }
+
+ for (j = 0; j < 256; ++j)
+ {
+ pthread_join (threads[j], NULL);
+ }
+ }
+
+ pthread_attr_destroy (&attr);
+
+ return 0;
+}
manythreads.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: watchthreads.c
===================================================================
--- watchthreads.c (nonexistent)
+++ watchthreads.c (revision 816)
@@ -0,0 +1,80 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2002, 2003, 2004, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ This file is copied from schedlock.c. */
+
+#include
+#include
+#include
+#include
+
+void *thread_function (void *arg); /* Function executed by each thread. */
+
+#define NUM 5
+
+unsigned int args[NUM+1];
+
+int
+main ()
+{
+ int res;
+ pthread_t threads[NUM];
+ void *thread_result;
+ long i;
+
+ /* To keep the test determinative, initialize args first,
+ then start all the threads. Otherwise, the way watchthreads.exp
+ is written, we have to worry about things like threads[0] getting
+ to 29 hits of args[0] before args[1] gets changed. */
+
+ for (i = 0; i < NUM; i++)
+ {
+ /* The call to usleep is so that when the watchpoint triggers,
+ the pc is still on the same line. */
+ args[i] = 1; usleep (1); /* Init value. */
+ }
+
+ for (i = 0; i < NUM; i++)
+ {
+ res = pthread_create (&threads[i],
+ NULL,
+ thread_function,
+ (void *) i);
+ }
+
+ args[i] = 1;
+ thread_function ((void *) i);
+
+ exit (EXIT_SUCCESS);
+}
+
+void *
+thread_function (void *arg)
+{
+ int my_number = (long) arg;
+ int *myp = (int *) &args[my_number];
+
+ /* Don't run forever. Run just short of it :) */
+ while (*myp > 0)
+ {
+ (*myp) ++; usleep (1); /* Loop increment. */
+ }
+
+ pthread_exit (NULL);
+}
+
watchthreads.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: watchthreads-reorder.c
===================================================================
--- watchthreads-reorder.c (nonexistent)
+++ watchthreads-reorder.c (revision 816)
@@ -0,0 +1,364 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#define _GNU_SOURCE
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define gettid() syscall (__NR_gettid)
+
+/* Terminate always in the main task, it can lock up with SIGSTOPped GDB
+ otherwise. */
+#define TIMEOUT (gettid () == getpid() ? 10 : 15)
+
+static pid_t thread1_tid;
+static pthread_cond_t thread1_tid_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t thread1_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+
+static pid_t thread2_tid;
+static pthread_cond_t thread2_tid_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t thread2_tid_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+
+static pthread_mutex_t terminate_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+
+/* These variables must have lower in-memory addresses than thread1_rwatch and
+ thread2_rwatch so that they take their watchpoint slots. */
+
+static int unused1_rwatch;
+static int unused2_rwatch;
+
+static volatile int thread1_rwatch;
+static volatile int thread2_rwatch;
+
+/* Do not use alarm as it would create a ptrace event which would hang up us if
+ we are being traced by GDB which we stopped ourselves. */
+
+static void timed_mutex_lock (pthread_mutex_t *mutex)
+{
+ int i;
+ struct timespec start, now;
+
+ i = clock_gettime (CLOCK_MONOTONIC, &start);
+ assert (i == 0);
+
+ do
+ {
+ i = pthread_mutex_trylock (mutex);
+ if (i == 0)
+ return;
+ assert (i == EBUSY);
+
+ i = clock_gettime (CLOCK_MONOTONIC, &now);
+ assert (i == 0);
+ assert (now.tv_sec >= start.tv_sec);
+ }
+ while (now.tv_sec - start.tv_sec < TIMEOUT);
+
+ fprintf (stderr, "Timed out waiting for internal lock!\n");
+ exit (EXIT_FAILURE);
+}
+
+static void *
+thread1_func (void *unused)
+{
+ int i;
+ volatile int rwatch_store;
+
+ timed_mutex_lock (&thread1_tid_mutex);
+
+ /* THREAD1_TID_MUTEX must be already locked to avoid race. */
+ thread1_tid = gettid ();
+
+ i = pthread_cond_signal (&thread1_tid_cond);
+ assert (i == 0);
+ i = pthread_mutex_unlock (&thread1_tid_mutex);
+ assert (i == 0);
+
+ rwatch_store = thread1_rwatch;
+
+ /* Be sure the "T (tracing stop)" test can proceed for both threads. */
+ timed_mutex_lock (&terminate_mutex);
+ i = pthread_mutex_unlock (&terminate_mutex);
+ assert (i == 0);
+
+ return NULL;
+}
+
+static void *
+thread2_func (void *unused)
+{
+ int i;
+ volatile int rwatch_store;
+
+ timed_mutex_lock (&thread2_tid_mutex);
+
+ /* THREAD2_TID_MUTEX must be already locked to avoid race. */
+ thread2_tid = gettid ();
+
+ i = pthread_cond_signal (&thread2_tid_cond);
+ assert (i == 0);
+ i = pthread_mutex_unlock (&thread2_tid_mutex);
+ assert (i == 0);
+
+ rwatch_store = thread2_rwatch;
+
+ /* Be sure the "T (tracing stop)" test can proceed for both threads. */
+ timed_mutex_lock (&terminate_mutex);
+ i = pthread_mutex_unlock (&terminate_mutex);
+ assert (i == 0);
+
+ return NULL;
+}
+
+static const char *
+proc_string (const char *filename, const char *line)
+{
+ FILE *f;
+ static char buf[LINE_MAX];
+ size_t line_len = strlen (line);
+
+ f = fopen (filename, "r");
+ if (f == NULL)
+ {
+ fprintf (stderr, "fopen (\"%s\") for \"%s\": %s\n", filename, line,
+ strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+ while (errno = 0, fgets (buf, sizeof (buf), f))
+ {
+ char *s;
+
+ s = strchr (buf, '\n');
+ assert (s != NULL);
+ *s = 0;
+
+ if (strncmp (buf, line, line_len) != 0)
+ continue;
+
+ if (fclose (f))
+ {
+ fprintf (stderr, "fclose (\"%s\") for \"%s\": %s\n", filename, line,
+ strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+
+ return &buf[line_len];
+ }
+ if (errno != 0)
+ {
+ fprintf (stderr, "fgets (\"%s\": %s\n", filename, strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+ fprintf (stderr, "\"%s\": No line \"%s\" found.\n", filename, line);
+ exit (EXIT_FAILURE);
+}
+
+static unsigned long
+proc_ulong (const char *filename, const char *line)
+{
+ const char *s = proc_string (filename, line);
+ long retval;
+ char *end;
+
+ errno = 0;
+ retval = strtol (s, &end, 10);
+ if (retval < 0 || retval >= LONG_MAX || (end && *end))
+ {
+ fprintf (stderr, "\"%s\":\"%s\": %ld, %s\n", filename, line, retval,
+ strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+ return retval;
+}
+
+static void
+state_wait (pid_t process, const char *wanted)
+{
+ char *filename;
+ int i;
+ struct timespec start, now;
+ const char *state;
+
+ i = asprintf (&filename, "/proc/%lu/status", (unsigned long) process);
+ assert (i > 0);
+
+ i = clock_gettime (CLOCK_MONOTONIC, &start);
+ assert (i == 0);
+
+ do
+ {
+ state = proc_string (filename, "State:\t");
+ if (strcmp (state, wanted) == 0)
+ {
+ free (filename);
+ return;
+ }
+
+ if (sched_yield ())
+ {
+ perror ("sched_yield()");
+ exit (EXIT_FAILURE);
+ }
+
+ i = clock_gettime (CLOCK_MONOTONIC, &now);
+ assert (i == 0);
+ assert (now.tv_sec >= start.tv_sec);
+ }
+ while (now.tv_sec - start.tv_sec < TIMEOUT);
+
+ fprintf (stderr, "Timed out waiting for PID %lu \"%s\" (now it is \"%s\")!\n",
+ (unsigned long) process, wanted, state);
+ exit (EXIT_FAILURE);
+}
+
+static volatile pid_t tracer = 0;
+static pthread_t thread1, thread2;
+
+static void
+cleanup (void)
+{
+ printf ("Resuming GDB PID %lu.\n", (unsigned long) tracer);
+
+ if (tracer)
+ {
+ int i;
+ int tracer_save = tracer;
+
+ tracer = 0;
+
+ i = kill (tracer_save, SIGCONT);
+ assert (i == 0);
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ int standalone = 0;
+
+ if (argc == 2 && strcmp (argv[1], "-s") == 0)
+ standalone = 1;
+ else
+ assert (argc == 1);
+
+ setbuf (stdout, NULL);
+
+ timed_mutex_lock (&thread1_tid_mutex);
+ timed_mutex_lock (&thread2_tid_mutex);
+
+ timed_mutex_lock (&terminate_mutex);
+
+ i = pthread_create (&thread1, NULL, thread1_func, NULL);
+ assert (i == 0);
+
+ i = pthread_create (&thread2, NULL, thread2_func, NULL);
+ assert (i == 0);
+
+ if (!standalone)
+ {
+ tracer = proc_ulong ("/proc/self/status", "TracerPid:\t");
+ if (tracer == 0)
+ {
+ fprintf (stderr, "The testcase must be run by GDB!\n");
+ exit (EXIT_FAILURE);
+ }
+ if (tracer != getppid ())
+ {
+ fprintf (stderr, "The testcase parent must be our GDB tracer!\n");
+ exit (EXIT_FAILURE);
+ }
+ }
+
+ /* SIGCONT our debugger in the case of our crash as we would deadlock
+ otherwise. */
+
+ atexit (cleanup);
+
+ printf ("Stopping GDB PID %lu.\n", (unsigned long) tracer);
+
+ if (tracer)
+ {
+ i = kill (tracer, SIGSTOP);
+ assert (i == 0);
+ state_wait (tracer, "T (stopped)");
+ }
+
+ /* Threads are now waiting at timed_mutex_lock (thread1_tid_mutex) and so
+ they could not trigger the watchpoints before GDB gets unstopped later.
+ Threads get resumed at pthread_cond_wait below. Use `while' loops for
+ protection against spurious pthread_cond_wait wakeups. */
+
+ printf ("Waiting till the threads initialize their TIDs.\n");
+
+ while (thread1_tid == 0)
+ {
+ i = pthread_cond_wait (&thread1_tid_cond, &thread1_tid_mutex);
+ assert (i == 0);
+ }
+
+ while (thread2_tid == 0)
+ {
+ i = pthread_cond_wait (&thread2_tid_cond, &thread2_tid_mutex);
+ assert (i == 0);
+ }
+
+ printf ("Thread 1 TID = %lu, thread 2 TID = %lu, PID = %lu.\n",
+ (unsigned long) thread1_tid, (unsigned long) thread2_tid,
+ (unsigned long) getpid ());
+
+ printf ("Waiting till the threads get trapped by the watchpoints.\n");
+
+ if (tracer)
+ {
+ /* s390x-unknown-linux-gnu will fail with "R (running)". */
+
+ state_wait (thread1_tid, "T (tracing stop)");
+
+ state_wait (thread2_tid, "T (tracing stop)");
+ }
+
+ cleanup ();
+
+ printf ("Joining the threads.\n");
+
+ i = pthread_mutex_unlock (&terminate_mutex);
+ assert (i == 0);
+
+ i = pthread_join (thread1, NULL);
+ assert (i == 0);
+
+ i = pthread_join (thread2, NULL);
+ assert (i == 0);
+
+ printf ("Exiting.\n"); /* break-at-exit */
+
+ /* Just prevent compiler `warning: unusedX_rwatch defined but not used'. */
+ unused1_rwatch = 1;
+ unused2_rwatch = 2;
+
+ return EXIT_SUCCESS;
+}
watchthreads-reorder.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: execl1.c
===================================================================
--- execl1.c (nonexistent)
+++ execl1.c (revision 816)
@@ -0,0 +1,27 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+/* Test handling thread control across an execl. */
+
+/* New exec image that doesn't load any thread library. */
+
+int
+main (int argc, char* argv[])
+{
+ return 0;
+}
execl1.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: tls-main.c
===================================================================
--- tls-main.c (nonexistent)
+++ tls-main.c (revision 816)
@@ -0,0 +1,9 @@
+__thread int i_tls = 2;
+int main ()
+{
+ int result;
+ result = foo (); /* Call to foo should return 2, not 1. */
+ result ++;
+ return 0; /* break here to check result */
+}
+
tls-main.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: current-lwp-dead.exp
===================================================================
--- current-lwp-dead.exp (nonexistent)
+++ current-lwp-dead.exp (revision 816)
@@ -0,0 +1,36 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This only works with on Linux targets.
+if ![istarget *-*-linux*] then {
+ return
+}
+
+if { [prepare_for_testing current-lwp-dead.exp current-lwp-dead] } {
+ return -1
+}
+
+if {[runto_main] <= 0} {
+ untested current-lwp-dead.exp
+ return -1
+}
+
+gdb_breakpoint "fn_return"
+gdb_continue_to_breakpoint "fn_return" ".*at-fn_return.*"
Index: fork-thread-pending.c
===================================================================
--- fork-thread-pending.c (nonexistent)
+++ fork-thread-pending.c (revision 816)
@@ -0,0 +1,109 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define NUMTHREADS 10
+
+volatile int done = 0;
+
+static void *
+start (void *arg)
+{
+ while (!done)
+ usleep (100);
+ assert (0);
+ return arg;
+}
+
+void *
+thread_function (void *arg)
+{
+ int x = * (int *) arg;
+
+ printf ("Thread <%d> executing\n", x);
+
+ while (!done)
+ usleep (100);
+
+ return NULL;
+}
+
+void *
+thread_forker (void *arg)
+{
+ int x = * (int *) arg;
+ pid_t pid;
+ int rv;
+ int i;
+ pthread_t thread;
+
+ printf ("Thread forker <%d> executing\n", x);
+
+ switch ((pid = fork ()))
+ {
+ case -1:
+ assert (0);
+ default:
+ wait (&rv);
+ done = 1;
+ break;
+ case 0:
+ i = pthread_create (&thread, NULL, start, NULL);
+ assert (i == 0);
+ i = pthread_join (thread, NULL);
+ assert (i == 0);
+
+ assert (0);
+ }
+
+ return NULL;
+}
+
+int
+main (void)
+{
+ pthread_t threads[NUMTHREADS];
+ int args[NUMTHREADS];
+ int i, j;
+
+ /* Create a few threads that do mostly nothing, and then one that
+ forks. */
+ for (j = 0; j < NUMTHREADS - 1; ++j)
+ {
+ args[j] = j;
+ pthread_create (&threads[j], NULL, thread_function, &args[j]);
+ }
+
+ args[j] = j;
+ pthread_create (&threads[j], NULL, thread_forker, &args[j]);
+
+ for (j = 0; j < NUMTHREADS; ++j)
+ {
+ pthread_join (threads[j], NULL);
+ }
+
+ return 0;
+}
fork-thread-pending.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: thread-specific.c
===================================================================
--- thread-specific.c (nonexistent)
+++ thread-specific.c (revision 816)
@@ -0,0 +1,64 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+#include
+
+void *thread_function(void *arg);
+
+unsigned int args[1];
+
+int main() {
+ int res;
+ pthread_t threads[2];
+ void *thread_result;
+ long i = 1;
+
+ args[0] = 1;
+ res = pthread_create(&threads[0],
+ NULL,
+ thread_function,
+ (void *) 0);
+
+ /* thread-specific.exp: last thread start. */
+ args[1] = 1;
+
+ /* Don't run forever. Run just short of it :) */
+ while (i > 0)
+ {
+ /* thread-specific.exp: main loop. */
+ (i) ++;
+ }
+
+ exit(EXIT_SUCCESS);
+}
+
+void *thread_function(void *arg) {
+ int my_number = (long) arg;
+ int *myp = (int *) &args[my_number];
+
+ /* Don't run forever. Run just short of it :) */
+ while (*myp > 0)
+ {
+ /* thread-specific.exp: thread loop. */
+ (*myp) ++;
+ }
+
+ pthread_exit(NULL);
+}
thread-specific.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: multi-create.c
===================================================================
--- multi-create.c (nonexistent)
+++ multi-create.c (revision 816)
@@ -0,0 +1,91 @@
+/* Create threads from multiple threads in parallel.
+ Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+
+#define NUM_CREATE 1
+#define NUM_THREAD 8
+
+void *
+thread_function (void *arg)
+{
+ int x = * (int *) arg;
+
+ printf ("Thread <%d> executing\n", x);
+
+ return NULL;
+}
+
+void *
+create_function (void *arg)
+{
+ pthread_attr_t attr;
+ pthread_t threads[NUM_THREAD];
+ int args[NUM_THREAD];
+ int i = * (int *) arg;
+ int j;
+
+ pthread_attr_init (&attr); /* set breakpoint 1 here. */
+ pthread_attr_setstacksize (&attr, 2*PTHREAD_STACK_MIN);
+
+ /* Create a ton of quick-executing threads, then wait for them to
+ complete. */
+ for (j = 0; j < NUM_THREAD; ++j)
+ {
+ args[j] = i * 1000 + j;
+ pthread_create (&threads[j], &attr, thread_function, &args[j]);
+ }
+
+ for (j = 0; j < NUM_THREAD; ++j)
+ pthread_join (threads[j], NULL);
+
+ pthread_attr_destroy (&attr);
+
+ return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+ pthread_attr_t attr;
+ pthread_t threads[NUM_CREATE];
+ int args[NUM_CREATE];
+ int n, i;
+
+ pthread_attr_init (&attr);
+ pthread_attr_setstacksize (&attr, 2*PTHREAD_STACK_MIN);
+
+ for (n = 0; n < 100; ++n)
+ {
+ for (i = 0; i < NUM_CREATE; i++)
+ {
+ args[i] = i;
+ pthread_create (&threads[i], &attr, create_function, &args[i]);
+ }
+
+ create_function (&i);
+ for (i = 0; i < NUM_CREATE; i++)
+ pthread_join (threads[i], NULL);
+ }
+
+ pthread_attr_destroy (&attr);
+
+ return 0;
+}
multi-create.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: schedlock.c
===================================================================
--- schedlock.c (nonexistent)
+++ schedlock.c (revision 816)
@@ -0,0 +1,65 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2002, 2003, 2004, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+#include
+
+void *thread_function(void *arg); /* Pointer to function executed by each thread */
+
+#define NUM 1
+
+unsigned int args[NUM+1];
+
+int main() {
+ int res;
+ pthread_t threads[NUM];
+ void *thread_result;
+ long i;
+
+ for (i = 1; i <= NUM; i++)
+ {
+ args[i] = 1;
+ res = pthread_create(&threads[i - 1],
+ NULL,
+ thread_function,
+ (void *) i);
+ }
+
+ /* schedlock.exp: last thread start. */
+ args[0] = 1;
+ thread_function ((void *) 0);
+
+ exit(EXIT_SUCCESS);
+}
+
+void *thread_function(void *arg) {
+ int my_number = (long) arg;
+ int *myp = (int *) &args[my_number];
+
+ /* Don't run forever. Run just short of it :) */
+ while (*myp > 0)
+ {
+ /* schedlock.exp: main loop. */
+ (*myp) ++;
+ }
+
+ pthread_exit(NULL);
+}
+
schedlock.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: interrupted-hand-call.exp
===================================================================
--- interrupted-hand-call.exp (nonexistent)
+++ interrupted-hand-call.exp (revision 816)
@@ -0,0 +1,92 @@
+# Copyright (C) 2004, 2007, 2008, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Test recovering from a hand function call that gets interrupted
+# by a signal in another thread.
+
+set NR_THREADS 4
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile "interrupted-hand-call"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}" "additional_flags=-DNR_THREADS=$NR_THREADS"]] != "" } {
+ return -1
+}
+
+# Some targets can't do function calls, so don't even bother with this
+# test.
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ continue
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if { ![runto_main] } {
+ fail "Can't run to main"
+ return 0
+}
+
+gdb_test "break all_threads_running" \
+ "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on all_threads_running"
+
+# Run the program and make sure GDB reports that we stopped after
+# hitting breakpoint 2 in all_threads_running().
+
+gdb_test "continue" \
+ ".*Breakpoint 2, all_threads_running ().*" \
+ "run to all_threads_running"
+
+# NOTE: Don't turn on scheduler-locking here.
+# We want the main thread (hand_call_with_signal) and
+# thread 1 (sigabrt_handler) to both run.
+
+gdb_test "call hand_call_with_signal()" \
+ ".*in another thread.*" \
+ "hand-call interrupted by signal in another thread"
+
+# Verify dummy stack frame is still present.
+
+gdb_test "maint print dummy-frames" ".*stack=.*" "dummy stack frame present"
+
+# Continuing now should exit the hand-call and pop the dummy frame.
+
+gdb_test "continue" "" "finish hand-call"
+
+gdb_test_multiple "maint print dummy-frames" "dummy frame popped" {
+ -re ".*stack=.*$gdb_prompt $" {
+ fail "dummy frame popped"
+ }
+ -re ".*$gdb_prompt $" {
+ pass "dummy frame popped"
+ }
+}
+
+# Continue one last time, the program should exit normally.
+
+gdb_test "continue" "Program exited normally." \
+ "continue to program exit"
+
+return 0
Index: tls.c
===================================================================
--- tls.c (nonexistent)
+++ tls.c (revision 816)
@@ -0,0 +1,230 @@
+/* BeginSourceFile tls.c
+
+ This file creates and deletes threads. It uses thread local storage
+ variables too. */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define N_THREADS 3
+
+/* Uncomment to turn on debugging output */
+/*#define START_DEBUG*/
+
+/* Thread-local storage. */
+__thread int a_thread_local;
+__thread int another_thread_local;
+
+/* psymtabs->symtabs resolving check. */
+extern __thread int file2_thread_local;
+
+/* Global variable just for info addr in gdb. */
+int a_global;
+
+/* Print the results of thread-local storage. */
+int thread_local_val[ N_THREADS ];
+int another_thread_local_val[ N_THREADS ];
+
+/* Semaphores to make sure the threads are alive when we print the TLS
+ variables from gdb. */
+sem_t tell_main, tell_thread;
+
+
+void print_error ()
+{
+ switch (errno)
+ {
+ case EAGAIN:
+ fprintf (stderr, "EAGAIN\n");
+ break;
+ case EINTR:
+ fprintf (stderr, "EINTR\n");
+ break;
+ case EINVAL:
+ fprintf (stderr, "EINVAL\n");
+ break;
+ case ENOSYS:
+ fprintf (stderr, "ENOSYS\n");
+ break;
+ case ENOENT:
+ fprintf (stderr, "ENOENT\n");
+ break;
+ case EDEADLK:
+ fprintf (stderr, "EDEADLK\n");
+ break;
+ default:
+ fprintf (stderr, "Unknown error\n");
+ break;
+ }
+}
+
+/* Routine for each thread to run, does nothing. */
+void *spin( vp )
+ void * vp;
+{
+ int me = (long) vp;
+ int i;
+
+ /* Use a_global. */
+ a_global++;
+
+ a_thread_local = 0;
+ another_thread_local = me;
+ for( i = 0; i <= me; i++ ) {
+ a_thread_local += i;
+ }
+
+ another_thread_local_val[me] = another_thread_local;
+ thread_local_val[ me ] = a_thread_local; /* here we know tls value */
+
+ if (sem_post (&tell_main) == -1)
+ {
+ fprintf (stderr, "th %d post on sem tell_main failed\n", me);
+ print_error ();
+ return;
+ }
+#ifdef START_DEBUG
+ fprintf (stderr, "th %d post on tell main\n", me);
+#endif
+
+ while (1)
+ {
+#ifdef START_DEBUG
+ fprintf (stderr, "th %d start wait on tell_thread\n", me);
+#endif
+ if (sem_wait (&tell_thread) == 0)
+ break;
+
+ if (errno == EINTR)
+ {
+#ifdef START_DEBUG
+ fprintf (stderr, "th %d wait tell_thread got EINTR, rewaiting\n", me);
+#endif
+ continue;
+ }
+ else
+ {
+ fprintf (stderr, "th %d wait on sem tell_thread failed\n", me);
+ print_error ();
+ return;
+ }
+ }
+
+#ifdef START_DEBUG
+ fprintf (stderr, "th %d Wait on tell_thread\n", me);
+#endif
+
+}
+
+void
+function_referencing_file2_thread_local (void)
+{
+ file2_thread_local = file2_thread_local;
+}
+
+void
+do_pass()
+{
+ int i;
+ pthread_t t[ N_THREADS ];
+ int err;
+
+ for( i = 0; i < N_THREADS; i++)
+ {
+ thread_local_val[i] = 0;
+ another_thread_local_val[i] = 0;
+ }
+
+ if (sem_init (&tell_main, 0, 0) == -1)
+ {
+ fprintf (stderr, "tell_main semaphore init failed\n");
+ return;
+ }
+
+ if (sem_init (&tell_thread, 0, 0) == -1)
+ {
+ fprintf (stderr, "tell_thread semaphore init failed\n");
+ return;
+ }
+
+ /* 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 *) (long) i );
+ if( err != 0 ) {
+ fprintf(stderr, "Error in thread %d create\n", i );
+ }
+ }
+
+ for( i = 0; i < N_THREADS; i++ )
+ {
+ while (1)
+ {
+#ifdef START_DEBUG
+ fprintf (stderr, "main %d start wait on tell_main\n", i);
+#endif
+ if (sem_wait (&tell_main) == 0)
+ break;
+
+ if (errno == EINTR)
+ {
+#ifdef START_DEBUG
+ fprintf (stderr, "main %d wait tell_main got EINTR, rewaiting\n", i);
+#endif
+ continue;
+ }
+ else
+ {
+ fprintf (stderr, "main %d wait on sem tell_main failed\n", i);
+ print_error ();
+ return;
+ }
+ }
+ }
+
+#ifdef START_DEBUG
+ fprintf (stderr, "main done waiting on tell_main\n");
+#endif
+
+ i = 10; /* Here all threads should be still alive. */
+
+ for( i = 0; i < N_THREADS; i++ )
+ {
+ if (sem_post (&tell_thread) == -1)
+ {
+ fprintf (stderr, "main %d post on sem tell_thread failed\n", i);
+ print_error ();
+ return;
+ }
+#ifdef START_DEBUG
+ fprintf (stderr, "main %d post on tell_thread\n", i);
+#endif
+ }
+
+ for( i = 0; i < N_THREADS; i++ )
+ {
+ err = pthread_join(t[i], NULL );
+ if( err != 0 )
+ {
+ fprintf (stderr, "error in thread %d join\n", i );
+ }
+ }
+
+ i = 10; /* Null line for setting bpts on. */
+
+}
+
+int
+main()
+{
+ do_pass ();
+
+ return 0; /* Set breakpoint here before exit. */
+}
+
+/* EndSourceFile */
tls.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: thread-execl.c
===================================================================
--- thread-execl.c (nonexistent)
+++ thread-execl.c (revision 816)
@@ -0,0 +1,48 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+
+static const char *image;
+
+void *
+thread_execler (void *arg)
+{
+ /* Exec ourselves again. */
+ if (execl (image, image, NULL) == -1)
+ {
+ perror ("execl");
+ abort ();
+ }
+
+ return NULL;
+}
+
+int
+main (int argc, char **argv)
+{
+ pthread_t thread;
+
+ image = argv[0];
+
+ pthread_create (&thread, NULL, thread_execler, NULL);
+ pthread_join (thread, NULL);
+
+ return 0;
+}
thread-execl.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: threxit-hop-specific.exp
===================================================================
--- threxit-hop-specific.exp (nonexistent)
+++ threxit-hop-specific.exp (revision 816)
@@ -0,0 +1,59 @@
+# Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Test that GDB doesn't get stuck when thread hoping over a thread
+# specific breakpoint when the selected thread has gone away.
+
+set testfile "threxit-hop-specific"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+ executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_load ${binfile}
+
+runto_main
+
+# Get ourselves to the thread that exits
+gdb_breakpoint "thread_function"
+gdb_test "continue" ".*thread_function.*" "continue to thread start"
+
+# Set a thread specific breakpoint somewhere the main thread will pass
+# by, but make it specific to the thread that is going to exit. Step
+# over the pthread_exit call. GDB should still be able to step over
+# the thread specific breakpoint, and reach the other breakpoint,
+# which is not thread specific.
+set bpthrline [gdb_get_line_number "set thread specific breakpoint here"]
+gdb_test "break $bpthrline thread 2" \
+ "Breakpoint .*$srcfile.*$bpthrline.*" \
+ "set thread specific breakpoint"
+
+set bpexitline [gdb_get_line_number "set exit breakpoint here"]
+gdb_breakpoint "$bpexitline"
+
+gdb_test "next" \
+ ".*set exit breakpoint here.*" \
+ "get past the thread specific breakpoint"
+
+return 0
Index: linux-dp.exp
===================================================================
--- linux-dp.exp (nonexistent)
+++ linux-dp.exp (revision 816)
@@ -0,0 +1,391 @@
+# Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+#### Dining Philosophers, on LinuxThreads - Jim Blandy
+####
+#### At the moment, GDB's support for LinuxThreads is pretty
+#### idiosyncratic --- GDB's output doesn't look much like the output
+#### it produces for other thread implementations, messages appear at
+#### different times, etc. So these tests are specific to LinuxThreads.
+####
+#### However, if all goes well, Linux will soon have a libthread_db
+#### interface, and GDB will manage it the same way it does other
+#### libthread_db-based systems. Then, we can adjust this file to
+#### work with any such system.
+
+### Other things we ought to test:
+### stepping a thread while others are running
+### killing and restarting
+### quitting gracefully
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# This only works with Linux configurations.
+if ![istarget *-*-linux-gnu*] then {
+ return
+}
+
+set testfile "linux-dp"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug libs=-lpthread}] != ""} {
+ return -1
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+send_gdb "set print sevenbit-strings\n" ; gdb_expect -re "$gdb_prompt $"
+runto_main
+
+# There should be no threads initially.
+gdb_test "info threads" "" "info threads 1"
+
+# Try stepping over the thread creation function.
+gdb_breakpoint [gdb_get_line_number "linuxthreads.exp: create philosopher"]
+set expect_manager -1
+for {set i 0} {$i < 5} {incr i} {
+ gdb_continue_to_breakpoint "about to create philosopher: $i"
+ send_gdb "info threads\n"
+ set threads_before {}
+ gdb_expect {
+ -re "info threads\r\n" {
+ exp_continue
+ }
+ -re "^. +(\[0-9\]+ Thread \[-0-9a-fx\]+) \[^\n\]*\n" {
+ verbose -log "found thread $expect_out(1,string)" 2
+ lappend threads_before $expect_out(1,string)
+ exp_continue
+ }
+ -re "^\[^\n\]*\n" {
+ verbose -log "skipping line" 2
+ exp_continue -continue_timer
+ }
+ -re "^$gdb_prompt $" {
+ }
+ timeout {
+ fail "(timeout) info threads before: $i"
+ }
+ }
+ send_gdb "next\n"
+ set threads_created 0
+ gdb_expect {
+ -re "^next\r\n" {
+ exp_continue
+ }
+ -re "^ *\[_!\] \[0-9\]* \[_!\]\r\n" {
+ # Ignore program output.
+ exp_continue -continue_timer
+ }
+ -re "^\\\[New \[^\]\n\]+\\\]\[^\n\]+\n" {
+ incr threads_created
+ exp_continue
+ }
+ -re "^189\[^\n\]+\n" {
+ exp_continue
+ }
+ -re "^$gdb_prompt $" {
+ }
+ -re "Program received signal.*(Unknown signal|SIGUSR|Real-time event).*$gdb_prompt $" {
+ # It would be nice if we could catch the message that GDB prints
+ # when it first notices that the thread library doesn't support
+ # debugging, or if we could explicitly ask GDB somehow.
+ unsupported "This GDB does not support threads on this system."
+ return -1
+ }
+ -re "$gdb_prompt $" {
+ }
+ timeout {
+ fail "(timeout) create philosopher: $i"
+ }
+ }
+ if { $threads_created == 0 } {
+ # Not all targets announce new threads as they are created.
+ # For example, the GDB
+ # remote protocol target only finds out about threads when
+ # they actually report some event like a breakpoint hit,
+ # or when the user types 'info threads'.
+ unsupported "create philosopher: $i"
+ } elseif { $threads_created == 1 } {
+ if { $expect_manager < 0 } {
+ set expect_manager 0
+ }
+ pass "create philosopher: $i"
+ } elseif { !$i && $threads_created == 2 } {
+ # Two threads are created the first time in LinuxThreads,
+ # where the second is the manager thread. In NPTL, there is none.
+ set expect_manager 1
+ pass "create philosopher: $i"
+ } else {
+ fail "create philosopher: $i"
+ }
+
+ send_gdb "info threads\n"
+ set threads_after {}
+ gdb_expect {
+ -re "info threads\r\n" {
+ exp_continue
+ }
+ -re "^. +(\[0-9\]+ Thread \[-0-9a-fx\]+) \[^\n\]*\n" {
+ set name $expect_out(1,string)
+ for {set j 0} {$j != [llength $threads_before] } {incr j} {
+ if {$name == [lindex $threads_before $j]} {
+ set threads_before [lreplace $threads_before $j $j]
+ set name ""
+ break
+ }
+ }
+ if { $name != "" } {
+ lappend threads_after $name
+ }
+ exp_continue
+ }
+ -re "^\[^\n\]*\n" {
+ verbose -log "skipping line" 2
+ exp_continue -continue_timer
+ }
+ -re "^$gdb_prompt $" {
+ if { [llength $threads_before] != 0 } {
+ fail "info threads after: $i"
+ } elseif { !$i && [llength $threads_after] == 2 } {
+ set expect_manager 1
+ pass "info threads after: $i"
+ } elseif { [llength $threads_after] == 1 } {
+ if { $expect_manager < 0 } {
+ set expect_manager 0
+ }
+ pass "info threads after: $i"
+ } else {
+ fail "info threads after: $i"
+ }
+ }
+ timeout {
+ fail "(timeout) info threads after: $i"
+ }
+ }
+
+}
+
+set nthreads 6
+
+# Run until there are some threads.
+gdb_breakpoint [gdb_get_line_number "linuxthreads.exp: info threads 2"]
+gdb_continue_to_breakpoint "main thread's sleep"
+set info_threads_ptn ""
+for {set i $nthreads} {$i > 0} {incr i -1} {
+ append info_threads_ptn "$i Thread .*"
+}
+append info_threads_ptn "\[\r\n\]+$gdb_prompt $"
+set info_threads_manager_ptn "[expr $nthreads + 1] Thread .*$info_threads_ptn"
+
+gdb_test_multiple "info threads" "info threads 2" {
+ -re "$info_threads_manager_ptn" {
+ # We did see a manager thread. Check that against what we expected.
+ switch -exact -- $expect_manager {
+ -1 {
+ # We weren't sure whether to expect a manager thread.
+ pass "info threads 2"
+ }
+ 1 {
+ # We were expecting a manager thread.
+ pass "info threads 2"
+ }
+ 0 {
+ # We were not expecting to see the manager thread.
+ fail "info threads 2"
+ }
+ }
+ set expect_manager 1
+ incr nthreads
+ }
+ -re "$info_threads_ptn" {
+ # We did not see a manager thread. Check that against what we
+ # expected.
+ switch -exact -- $expect_manager {
+ -1 {
+ # We weren't sure whether to expect a manager thread.
+ # Don't expect it from here on out.
+ pass "info threads 2"
+ }
+ 1 {
+ # We were expecting a manager thread, but we didn't see one.
+ fail "info threads 2"
+ }
+ 0 {
+ # We were not expecting to see the manager thread.
+ pass "info threads 2"
+ }
+ }
+ set expect_manager 0
+ }
+}
+
+
+# Try setting a thread-specific breakpoint.
+gdb_breakpoint "print_philosopher thread 5"
+gdb_continue_to_breakpoint "thread 5's print"
+# When there is no debugging info available for the thread library,
+# the backtrace entry for philosopher's caller looks like:
+# #1 0x4001c548 in pthread_create () from /lib/libpthread.so.0
+# If you do have debug info, the output obviously depends more on the
+# exact library in use; under NPTL, you get:
+# #2 0x0012b7fc in start_thread (arg=0x21) at pthread_create.c:264
+gdb_test "where" "print_philosopher.*philosopher.* \(from .*libpthread\|at pthread_create\).*" \
+ "first thread-specific breakpoint hit"
+
+# Make sure it's catching the right thread. Try hitting the
+# breakpoint ten times, and make sure we don't get anyone else.
+set only_five 1
+for {set i 0} {$only_five > 0 && $i < 10} {incr i} {
+ gdb_continue_to_breakpoint "thread 5's print, pass: $i"
+ send_gdb "info threads\n"
+ gdb_expect {
+ -re "\\* 5 Thread .* print_philosopher .*\r\n$gdb_prompt $" {
+ # Okay this time.
+ }
+ -re ".*$gdb_prompt $" {
+ set only_five 0
+ }
+ timeout {
+ set only_five -1
+ }
+ }
+}
+
+set name "thread-specific breakpoint is thread-specific"
+if {$only_five == 1} { pass $name }
+if {$only_five == 0} { fail $name }
+if {$only_five == -1} { fail "$name (timeout)" }
+
+
+### Select a particular thread.
+proc select_thread {thread} {
+ global gdb_prompt
+
+ send_gdb "thread $thread\n"
+ gdb_expect {
+ -re "\\\[Switching to thread .*\\\].*\r\n$gdb_prompt $" {
+ pass "selected thread: $thread"
+ }
+ -re "$gdb_prompt $" {
+ fail "selected thread: $thread"
+ }
+ timeout {
+ fail "selected thread: $thread (timeout)"
+ }
+ }
+}
+
+### Select THREAD, check for a plausible backtrace, and make sure
+### we're actually selecting a different philosopher each time.
+### Return true if the thread had a stack which was not only
+### acceptable, but interesting. SEEN should be an array in which
+### SEEN(N) exists iff we have found philosopher number N before.
+
+set main_seen 0
+set manager_seen 0
+
+proc check_philosopher_stack {thread seen_name} {
+ global gdb_prompt
+ upvar $seen_name seen
+ global main_seen
+ global expect_manager manager_seen
+
+ set name "philosopher is distinct: $thread"
+ set interesting 0
+
+ select_thread $thread
+ send_gdb "where\n"
+ gdb_expect {
+ -re ".* in philosopher \\(data=(0x\[0-9a-f\]+).*\r\n$gdb_prompt $" {
+ set data $expect_out(1,string)
+ if {[info exists seen($data)]} {
+ fail $name
+ } else {
+ pass $name
+ set seen($data) yep
+ }
+ set interesting 1
+ }
+ -re ".* in __pthread_manager \\(.*$gdb_prompt $" {
+ if {$manager_seen == 1} {
+ fail "manager thread is distinct: $thread"
+ } else {
+ set manager_seen 1
+ pass "manager thread is distinct: $thread"
+ }
+ set interesting 1
+ }
+ -re "pthread_start_thread.*\r\n$gdb_prompt $" {
+ ## Maybe the thread hasn't started yet.
+ pass $name
+ }
+ -re ".* in main \\(.*$gdb_prompt $" {
+ if {$main_seen == 1} {
+ fail "main is distinct: $thread"
+ } else {
+ set main_seen 1
+ pass "main is distinct: $thread"
+ }
+ set interesting 1
+ }
+ -re " in \\?\\?.*\r\n$gdb_prompt $" {
+ ## Sometimes we can't get a backtrace. I'm going to call
+ ## this a pass, since we do verify that at least one
+ ## thread was interesting, so we can get more consistent
+ ## test suite totals. But in my heart, I think it should
+ ## be an xfail.
+ pass $name
+ }
+ -re "$gdb_prompt $" {
+ fail $name
+ }
+ timeout {
+ fail "$name (timeout)"
+ }
+ }
+
+ return $interesting
+}
+
+set any_interesting 0
+array set seen {}
+unset seen
+for {set i 1} {$i <= $nthreads} {incr i} {
+ if [check_philosopher_stack $i seen] {
+ set any_interesting 1
+ }
+}
+
+if {$any_interesting} {
+ pass "found an interesting thread"
+} else {
+ fail "found an interesting thread"
+}
+
+if {$manager_seen == $expect_manager} {
+ pass "manager thread found (not found) when expected"
+} else {
+ fail "manager thread found (not found) when expected"
+}
Index: staticthreads.exp
===================================================================
--- staticthreads.exp (nonexistent)
+++ staticthreads.exp (revision 816)
@@ -0,0 +1,101 @@
+# static.exp -- test script, for GDB, the GNU debugger.
+
+# Copyright 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Based on manythreads written by Jeff Johnston, contributed by Red
+# Hat.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "staticthreads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set static_flag "-static"
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+ executable \
+ [list debug "incdir=${objdir}" "additional_flags=${static_flag}" \
+ ]] != "" } {
+ return -1
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "set print sevenbit-strings" ""
+
+
+# See if the static multi-threaded program runs.
+
+runto_main
+gdb_test "break sem_post"
+set test "Continue to main's call of sem_post"
+gdb_test_multiple "continue" "$test" {
+ -re "Breakpoint .*, .*sem_post .*$gdb_prompt " {
+ pass "$test"
+ }
+ -re "Program received signal .*$gdb_prompt " {
+ kfail gdb/1328 "$test"
+ }
+}
+
+
+# See if handle SIG32 helps (a little) with a static multi-threaded
+# program.
+
+set sig "SIG32"
+
+# SIGRTMIN is 37 on hppa-linux and hpux
+if [istarget hppa*-*-*] {
+ set sig "SIG37"
+}
+
+rerun_to_main
+gdb_test "handle $sig nostop noprint pass"
+set test "Handle $sig helps"
+gdb_test "continue" " .*sem_post .*" "handle $sig helps"
+
+
+# See if info threads produces anything approaching a thread list.
+
+set test "info threads"
+gdb_test_multiple "info threads" "$test" {
+ -re " Thread .*$gdb_prompt " {
+ pass "$test"
+ }
+ -re "$gdb_prompt " {
+ kfail gdb/1328 "$test"
+ }
+}
+
+
+# Check that the program can be quit.
+
+set test "GDB exits with static thread program"
+gdb_test_multiple "quit" "$test" {
+ -re "Quit anyway\\? \\(y or n\\) $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ eof {
+ pass "$test"
+ }
+}
Index: watchthreads2.exp
===================================================================
--- watchthreads2.exp (nonexistent)
+++ watchthreads2.exp (revision 816)
@@ -0,0 +1,139 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Check that watchpoints get propagated to all existing threads when the
+# watchpoint is created.
+
+set NR_THREADS 4
+set X_INCR_COUNT 10
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# This test verifies that a watchpoint is detected in the proper thread
+# so the test is only meaningful on a system with hardware watchpoints.
+if [target_info exists gdb,no_hardware_watchpoints] {
+ return 0;
+}
+
+set testfile "watchthreads2"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}" "additional_flags=-DNR_THREADS=$NR_THREADS -DX_INCR_COUNT=$X_INCR_COUNT"]] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set can-use-hw-watchpoints 1" "" ""
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+gdb_test "break thread_started" \
+ "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on thread_started"
+
+# Run the program until all threads have hit thread_started.
+# We use this as the vehicle to determine when gdb is aware
+# of all threads (i.e. "info threads" would show all threads).
+
+set nr_started 0
+set message "run to thread_started"
+for { set i 0 } { $i < $NR_THREADS } { incr i } {
+ gdb_test_multiple "continue" $message {
+ -re ".*Breakpoint 2, thread_started ().*$gdb_prompt $" {
+ incr nr_started
+ }
+ timeout {
+ set i $NR_THREADS
+ }
+ }
+}
+if { $nr_started == $NR_THREADS } {
+ pass "all threads started"
+} else {
+ fail "all threads started"
+ # No point in continuing.
+ return -1
+}
+
+# Watch X, it will be modified by all threads.
+# We want this watchpoint to be set *after* all threads are running.
+gdb_test "watch x" "Hardware watchpoint 3: x"
+
+# Now that the watchpoint is set, we can let the threads increment X.
+gdb_test "set var test_ready = 1" ""
+
+# While debugging.
+#gdb_test "set debug infrun 1" ""
+
+set x_inc_line [gdb_get_line_number "X increment"]
+set x_thread_loc "thread_function \\\(arg=.*\\\) at .*watchthreads.c:$x_inc_line"
+
+# X is incremented under a mutex, so we should get NR_THREADS * X_INCR_COUNT
+# hits.
+set limit [expr $NR_THREADS*$X_INCR_COUNT]
+set x_count 0
+set done 0
+
+set message "x watch loop"
+
+for {set i 0} {!$done && $i < $limit} {incr i} {
+ set test_flag 0
+
+ gdb_test_multiple "continue" $message {
+ -re "(.*Hardware watchpoint.*)$gdb_prompt $" {
+ set string $expect_out(1,string)
+
+ if [regexp "Hardware watchpoint 3: x\[^\r\]*\r\[^\r\]*\r\[^\r\]*Old value = $x_count\[^\r\]*\r\[^\r\]*New value = [expr $x_count+1]\r" $string] {
+ incr x_count
+ set test_flag 1
+ } else {
+ # We test for new value = old value + 1 each iteration.
+ # This can fail due to gdb/10116.
+ # This is caught after the loop exits.
+ }
+ }
+ -re "The program is not being run.*$gdb_prompt $" {
+ fail "$message (program terminated)"
+ }
+ }
+
+ # If we fail above, don't bother continuing loop.
+ if { $test_flag == 0 } {
+ set done 1
+ }
+}
+
+if { $i == $limit } {
+ pass "all threads incremented x"
+} else {
+ kfail "gdb/10116" "gdb can drop watchpoints in multithreaded app"
+}
Index: thread_check.exp
===================================================================
--- thread_check.exp (nonexistent)
+++ thread_check.exp (revision 816)
@@ -0,0 +1,92 @@
+# Copyright (C) 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file was written by Manoj Iyer. (manjo@austin.ibm.com)
+# Test break points and single step on thread functions.
+#
+# Test Purpose:
+# - Test that breakpoints, continue in a threaded application works.
+# On powerpc64-unknown-linux-gnu system, running kernel version
+# 2.6.5-7.71-pseries64 this test is known to fail due to kernel bug
+# in ptrace system call.
+#
+# Test Strategy:
+# - thread_check.c creates 2 threads
+# - start gdb
+# - create 2 breakpoints #1 main() #2 tf() (the thread function)
+# - run gdb till #1 main() breakpoint is reached
+# - continue to breakpoint #2 tf()
+# - delete all breakpoints
+# - exit gdb.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "thread_check"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 1;
+}
+
+
+#
+# set breakpoint at thread fucntion tf
+#
+gdb_test "break tf" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint at tf"
+
+
+#
+#
+# continue to tf() breakpoint #2
+#
+gdb_test "continue" \
+ ".*Breakpoint 2,.*tf.*at.*$srcfile:.*" \
+ "continue to tf"
+
+#
+# backtrace from thread function.
+#
+gdb_test "backtrace" \
+ "#0 .*tf .*at .*$srcfile:.*" \
+ "backtrace from thread function"
+
+
+#
+# delete all breakpoints
+#
+delete_breakpoints
+
+#
+# exit gdb
+#
+gdb_exit
Index: thread-unwindonsignal.exp
===================================================================
--- thread-unwindonsignal.exp (nonexistent)
+++ thread-unwindonsignal.exp (revision 816)
@@ -0,0 +1,117 @@
+# Copyright (C) 2008, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Test use of unwindonsignal when a hand function call that gets interrupted
+# by a signal in another thread.
+
+set NR_THREADS 4
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set testfile "interrupted-hand-call"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}" "additional_flags=-DNR_THREADS=$NR_THREADS"]] != "" } {
+ return -1
+}
+
+# Some targets can't do function calls, so don't even bother with this
+# test.
+if [target_info exists gdb,cannot_call_functions] {
+ setup_xfail "*-*-*" 2416
+ fail "This target can not call functions"
+ continue
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if { ![runto_main] } {
+ fail "Can't run to main"
+ return 0
+}
+
+gdb_test "break all_threads_running" \
+ "Breakpoint 2 at .*: file .*${srcfile}, line .*" \
+ "breakpoint on all_threads_running"
+
+# Run the program and make sure GDB reports that we stopped after
+# hitting breakpoint 2 in all_threads_running().
+
+gdb_test "continue" \
+ ".*Breakpoint 2, all_threads_running ().*" \
+ "run to all_threads_running"
+
+# NOTE: Don't turn on scheduler-locking here.
+# We want the main thread (hand_call_with_signal) and
+# thread 1 (sigabrt_handler) to both run.
+
+# Do turn on unwindonsignal.
+# We want to test gdb handling of the current thread changing when
+# unwindonsignal is in effect.
+gdb_test "set unwindonsignal on" \
+ "" \
+ "setting unwindonsignal"
+gdb_test "show unwindonsignal" \
+ "Unwinding of stack .* is on." \
+ "showing unwindonsignal"
+
+gdb_test "call hand_call_with_signal()" \
+ "The program received a signal.*" \
+ "hand-call interrupted by signal in another thread"
+
+# Verify dummy stack frame is still present.
+# ??? Should unwindonsignal still apply even if the program stops
+# because of a signal in another thread?
+
+gdb_test "maint print dummy-frames" ".*stack=.*" "dummy stack frame present"
+
+# GDB 6.8 would perform the unwindonsignal, but on the thread that stopped,
+# not the thread with the hand-called function.
+# This is tested by verifying only one thread has main in its backtrace.
+
+gdb_test_multiple "thread apply all bt" "wrong thread not unwound" {
+ -re ".* in main .* in main .*$gdb_prompt $" {
+ fail "wrong thread not unwound"
+ }
+ -re ".* in main .*$gdb_prompt $" {
+ pass "wrong thread not unwound"
+ }
+}
+
+# Continuing now should exit the hand-call and pop the dummy frame.
+
+gdb_test "continue" "" "finish hand-call"
+
+gdb_test_multiple "maint print dummy-frames" "dummy frame popped" {
+ -re ".*stack=.*$gdb_prompt $" {
+ fail "dummy frame popped"
+ }
+ -re ".*$gdb_prompt $" {
+ pass "dummy frame popped"
+ }
+}
+
+# Continue one last time, the program should exit normally.
+
+gdb_test "continue" "Program exited normally." \
+ "continue to program exit"
+
+return 0
Index: killed.exp
===================================================================
--- killed.exp (nonexistent)
+++ killed.exp (revision 816)
@@ -0,0 +1,104 @@
+# Copyright 2002, 2003, 2005, 2007, 2008, 2009, 2010
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This is a regression test for gdb/568 in the sources.redhat.com
+# GNATS database. As of early June 2002, GDB could get sort of wedged
+# debugging the program `killed.c':
+#
+# $ $D6/gdb/gdb -nw killed
+# GNU gdb 2002-06-11-cvs
+# Copyright 2002 Free Software Foundation, Inc.
+# GDB is free software, covered by the GNU General Public License, and you are
+# welcome to change it and/or distribute copies of it under certain conditions.
+# Type "show copying" to see the conditions.
+# There is absolutely no warranty for GDB. Type "show warranty" for details.
+# This GDB was configured as "i686-pc-linux-gnu"...
+# (gdb) run
+# Starting program: /home/jimb/foo/play/killed
+# [New Thread 1024 (LWP 6487)]
+# [New Thread 2049 (LWP 6488)]
+# [New Thread 1026 (LWP 6489)]
+# Cannot find user-level thread for LWP 6487: generic error
+# (gdb) quit
+# The program is running. Exit anyway? (y or n) y
+# Cannot find thread 2049: generic error
+# (gdb) kill
+# Kill the program being debugged? (y or n) y
+# Cannot find thread 2049: generic error
+# (gdb) The program is running. Exit anyway? (y or n) y
+# Cannot find thread 2049: generic error
+# (gdb)
+# [7]+ Stopped $D6/gdb/gdb -nw killed
+# $ kill %7
+#
+# [7]+ Stopped $D6/gdb/gdb -nw killed
+# $ kill -9 %7
+#
+# [7]+ Stopped $D6/gdb/gdb -nw killed
+# $
+# [7]+ Killed $D6/gdb/gdb -nw killed
+# $
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "killed"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_run_cmd
+gdb_expect {
+ -re "$gdb_prompt $" {
+ pass "run program to completion"
+ }
+ timeout {
+ fail "run program to completion (timeout)"
+ }
+}
+
+# Try to quit.
+send_gdb "quit\n"
+gdb_expect {
+ -re "Quit anyway\\? \\(y or n\\) $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ eof {
+ pass "GDB exits after multi-threaded program exits messily"
+ }
+ -re "Cannot find thread ${decimal}: generic error\[\r\n\]*$gdb_prompt $" {
+ kfail "gdb/568" "GDB exits after multi-threaded program exits messily"
+ }
+ timeout {
+ fail "GDB exits after multi-threaded program exits messily (timeout)"
+ }
+}
Index: hand-call-in-threads.c
===================================================================
--- hand-call-in-threads.c (nonexistent)
+++ hand-call-in-threads.c (revision 816)
@@ -0,0 +1,127 @@
+/* Test case for hand function calls in multi-threaded program.
+
+ Copyright 2008, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+#include
+#include
+
+#ifndef NR_THREADS
+#define NR_THREADS 4
+#endif
+
+int thread_count;
+
+pthread_mutex_t thread_count_mutex;
+
+pthread_cond_t thread_count_condvar;
+
+void
+incr_thread_count (void)
+{
+ pthread_mutex_lock (&thread_count_mutex);
+ ++thread_count;
+ if (thread_count == NR_THREADS)
+ pthread_cond_signal (&thread_count_condvar);
+ pthread_mutex_unlock (&thread_count_mutex);
+}
+
+void
+cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut)
+{
+ pthread_mutex_lock (mut);
+ pthread_cond_wait (cond, mut);
+ pthread_mutex_unlock (mut);
+}
+
+void
+noreturn (void)
+{
+ pthread_mutex_t mut;
+ pthread_cond_t cond;
+
+ pthread_mutex_init (&mut, NULL);
+ pthread_cond_init (&cond, NULL);
+
+ /* Wait for a condition that will never be signaled, so we effectively
+ block the thread here. */
+ cond_wait (&cond, &mut);
+}
+
+void *
+forever_pthread (void *unused)
+{
+ incr_thread_count ();
+ noreturn ();
+}
+
+void
+hand_call (void)
+{
+}
+
+/* Wait until all threads are running. */
+
+void
+wait_all_threads_running (void)
+{
+ pthread_mutex_lock (&thread_count_mutex);
+ if (thread_count == NR_THREADS)
+ {
+ pthread_mutex_unlock (&thread_count_mutex);
+ return;
+ }
+ pthread_cond_wait (&thread_count_condvar, &thread_count_mutex);
+ if (thread_count == NR_THREADS)
+ {
+ pthread_mutex_unlock (&thread_count_mutex);
+ return;
+ }
+ pthread_mutex_unlock (&thread_count_mutex);
+ printf ("failed waiting for all threads to start\n");
+ abort ();
+}
+
+/* Called when all threads are running.
+ Easy place for a breakpoint. */
+
+void
+all_threads_running (void)
+{
+}
+
+int
+main (void)
+{
+ pthread_t forever[NR_THREADS];
+ int i;
+
+ pthread_mutex_init (&thread_count_mutex, NULL);
+ pthread_cond_init (&thread_count_condvar, NULL);
+
+ for (i = 0; i < NR_THREADS; ++i)
+ pthread_create (&forever[i], NULL, forever_pthread, NULL);
+
+ wait_all_threads_running ();
+ all_threads_running ();
+
+ return 0;
+}
+
hand-call-in-threads.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: tls-nodebug.c
===================================================================
--- tls-nodebug.c (nonexistent)
+++ tls-nodebug.c (revision 816)
@@ -0,0 +1,10 @@
+/* Test accessing TLS based variable without any debug info compiled. */
+
+#include
+
+__thread int thread_local = 42;
+
+int main(void)
+{
+ return 0;
+}
tls-nodebug.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: sigthread.exp
===================================================================
--- sigthread.exp (nonexistent)
+++ sigthread.exp (revision 816)
@@ -0,0 +1,55 @@
+# sigthread.exp -- Expect script to test thread and signal interaction
+# Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see . */
+
+set testfile sigthread
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+ executable { debug }] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+ fail "Can't run to main"
+ return 0
+}
+
+gdb_test "handle SIGUSR1 nostop noprint pass"
+gdb_test "handle SIGUSR2 nostop noprint pass"
+
+send_gdb "continue\n"
+gdb_expect {
+ -re "Continuing" {
+ pass "continue"
+ }
+ timeout {
+ fail "continue (timeout)"
+ }
+}
+
+# For this to work we must be sure to consume the "Continuing."
+# message first, or GDB's signal handler may not be in place.
+after 500 {send_gdb "\003"}
+
+# Make sure we do not get an internal error from hitting Control-C
+# while many signals are flying back and forth.
+gdb_test "" "Program received signal SIGINT.*" "stop with control-c"
Index: pthreads.exp
===================================================================
--- pthreads.exp (nonexistent)
+++ pthreads.exp (revision 816)
@@ -0,0 +1,329 @@
+# Copyright (C) 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008,
+# 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file was written by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# This only works with native configurations
+if ![isnative] then {
+ return
+}
+
+set testfile "pthreads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# regexp for "horizontal" text (i.e. doesn't include newline or
+# carriage return)
+set horiz "\[^\n\r\]*"
+
+if [istarget "*-*-linux"] then {
+ set target_cflags "-D_MIT_POSIX_THREADS"
+} else {
+ set target_cflags ""
+}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set print sevenbit-strings" ""
+#gdb_test "set print address off" ""
+gdb_test "set width 0" ""
+
+# We'll need this when we send_gdb a ^C to GDB. Need to do it before we
+# run the program and gdb starts saving and restoring tty states.
+# On Ultrix, we don't need it and it is really slow (because shell_escape
+# doesn't use vfork).
+if ![istarget "*-*-ultrix*"] then {
+ gdb_test "shell stty intr '^C'" ""
+}
+
+proc all_threads_running {} {
+ global gdb_prompt
+ global srcfile
+
+ # Reset all the counters to zero.
+ gdb_test "set var common_routine::hits=0" ""
+ gdb_test "set var common_routine::from_thread1=0" ""
+ gdb_test "set var common_routine::from_thread2=0" ""
+ gdb_test "set var common_routine::from_main=0" ""
+ gdb_test "set var common_routine::full_coverage=0" ""
+
+ # Disable all breakpoints.
+ gdb_test "disable" ""
+
+ # Set up a breakpoint that will cause us to stop when we have
+ # been called 15 times. This should be plenty of time to allow
+ # every thread to run at least once, since each thread sleeps for
+ # one second between calls to common_routine.
+ gdb_test "tbreak common_routine if hits >= 15" ""
+
+ # Start all the threads running again and wait for the inferior
+ # to stop. Since no other breakpoints are set at this time
+ # we should stop only when we have been previously called 15 times.
+
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Continuing.*common_routine.*at.*$srcfile.*$gdb_prompt $" {}
+ default {
+ fail "continue until common routine run 15 times"
+ return 0
+ }
+ timeout {
+ fail "continue until common routine run 15 times (timeout)"
+ return 0
+ }
+ }
+
+ # Check that we stopped when we actually expected to stop, by
+ # verifying that there have been 15 previous hits.
+
+ # NOTE: Because of synchronization behavior, it is possible for
+ # more than one thread to increment "hits" between one breakpoint
+ # trap and the next. So stopping after 16 or 17 hits should be
+ # considered acceptable.
+
+ send_gdb "p common_routine::hits\n"
+ gdb_expect {
+ -re ".*= 15\r\n$gdb_prompt $" {
+ pass "stopped before calling common_routine 15 times"
+ }
+ -re ".*= 16\r\n$gdb_prompt $" {
+ pass "stopped before calling common_routine 15 times (16 times)"
+ }
+ -re ".*= 17\r\n$gdb_prompt $" {
+ pass "stopped before calling common_routine 15 times (17 times)"
+ }
+ default {
+ fail "stopped before calling common_routine 15 times"
+ return 0
+ }
+ -re ".*$gdb_prompt $" {
+ fail "stopped before calling common_routine 15 times"
+ return 0
+ }
+ timeout {
+ fail "stopped before calling common_routine 15 times (timeout)"
+ return 0
+ }
+ }
+
+ # Also check that all of the threads have run, which will only be true
+ # if the full_coverage variable is set.
+
+ send_gdb "p common_routine::full_coverage\n"
+ gdb_expect {
+ -re ".* = 1.*$gdb_prompt $" {}
+ -re ".* = 0.*$gdb_prompt $" {
+ fail "some threads didn't run"
+ return 0
+ }
+ default {
+ fail "some threads didn't run"
+ return 0
+ }
+ timeout {
+ fail "some threads didn't run (timeout)"
+ return 0
+ }
+ }
+
+ # Looks fine, return success.
+ return 1
+}
+
+proc test_startup {} {
+ global srcdir srcfile gdb_prompt expect_out
+ global horiz
+ global main_id thread1_id thread2_id
+
+ # We should be able to do an info threads before starting any others.
+ send_gdb "info threads\n"
+ gdb_expect {
+ -re ".*Thread.*main.*$gdb_prompt $" {
+ pass "info threads"
+ }
+ -re "\r\n$gdb_prompt $" {
+ unsupported "gdb does not support pthreads for this machine"
+ return 0
+ }
+ }
+
+ # 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 .*$srcfile.*"
+ 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 .*$srcfile.*"
+ 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
+}
+
+proc check_control_c {} {
+ global gdb_prompt
+
+ # Verify that all threads are running.
+ if [all_threads_running] then {
+ pass "All threads running after startup"
+ }
+
+ # Send a continue followed by ^C to the process to stop it.
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Continuing." {
+ pass "Continue with all threads running"
+ }
+ timeout {
+ fail "Continue with all threads running (timeout)"
+ }
+ }
+ after 2000
+ send_gdb "\003"
+ set description "Stopped with a ^C"
+ gdb_expect {
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ pass $description
+ }
+ -re "Quit.*$gdb_prompt $" {
+ pass $description
+ }
+ timeout {
+ fail "$description (timeout)"
+ return 1;
+ }
+ }
+ gdb_test "bt" ""
+
+ # Verify that all threads can be run again after a ^C stop.
+ if [all_threads_running] then {
+ pass "All threads running after continuing from ^C stop"
+ }
+ return 0;
+}
+
+proc check_backtraces {} {
+ global gdb_prompt main_id thread1_id thread2_id
+
+ # Check that the "thread apply N backtrace" command works
+
+ gdb_test "thread apply $main_id backtrace" \
+ ".* 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
+ # three threads with a single gdb command
+
+ gdb_test "thread apply $main_id $thread1_id $thread2_id bt" \
+ ".* in main .* in thread1 .* in thread2.*" \
+ "apply backtrace command to all three threads"
+
+ # Check that we can do thread specific backtraces
+ # This also tests that we can do thread specific breakpoints.
+
+ gdb_test "break common_routine thread $thread2_id" \
+ "Breakpoint .* at 0x.* file .* line .*" \
+ "set break at common_routine in thread 2"
+
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Breakpoint .* common_routine \\(arg=2\\).*" {
+ pass "continue to bkpt at common_routine in thread 2"
+ send_gdb "backtrace\n"
+ gdb_expect {
+ -re "#0.*common_routine \\(arg=2\\).*#1.*thread2.*" {
+ pass "backtrace from thread 2 bkpt in common_routine"
+ }
+ default {
+ fail "backtrace from thread 2 bkpt in common_routine"
+ }
+ timeout {
+ fail "backtrace from thread 2 bkpt in common_routine (timeout)"
+ }
+ }
+ }
+ -re "Breakpoint .* common_routine \\(arg=0\\).*" {
+ fail "continue to bkpt at common_routine in thread 2 (arg=0)"
+ }
+ -re "Breakpoint .* common_routine \\(arg=1\\).*" {
+ fail "continue to bkpt at common_routine in thread 2 (arg=1)"
+ }
+ -re ".*$gdb_prompt" {
+ fail "continue to bkpt at common_routine in thread 2"
+ }
+ default {
+ fail "continue to bkpt at common_routine in thread 2 (default)"
+ }
+ timeout {
+ fail "continue to bkpt at common_routine in thread 2 (timeout)"
+ }
+ }
+}
+
+setup_xfail "alpha-*-osf*"
+if [runto_main] then {
+ clear_xfail "alpha-*-osf*"
+ if [test_startup] then {
+ if [check_control_c] then {
+ warning "Could not stop child with ^C; skipping rest of tests.\n"
+ return;
+ }
+ check_backtraces
+ }
+}
+clear_xfail "alpha-*-osf*"
Index: tls2.c
===================================================================
--- tls2.c (nonexistent)
+++ tls2.c (revision 816)
@@ -0,0 +1,25 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+extern __thread int a_thread_local;
+__thread int file2_thread_local;
+
+void
+function_referencing_a_thread_local (void)
+{
+ a_thread_local = a_thread_local;
+}
tls2.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: step.exp
===================================================================
--- step.exp (nonexistent)
+++ step.exp (revision 816)
@@ -0,0 +1,197 @@
+# step.exp -- Expect script to test gdb with step.c
+# Copyright (C) 1992, 1997, 2007, 2008, 2009, 2010
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file was written by Hiro Sugawara. (hiro@lynx.com)
+#
+# This test really needs some major surgery to be acceptable, but
+# I'm just about burnt out on lynx work, so I'm not doing it now.
+#
+# * The test has an indeterminate number of pass/fails
+# for each run (it runs a small group of tests until
+# it's timer kicks off). This is very bad for nightly
+# automated regression testing.
+#
+# * It tries to "step" from withint he prologue of a
+# function. This isn't support in gdb (it's going
+# to act like a continue).
+#
+# * This test rarely check that it stopped in sensible
+# places. (see previous bullet -- this test doesn't
+# catch the fact it continued rather than stepped)
+
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set program_exited 0
+
+proc set_bp { where } {
+ global gdb_prompt
+
+ send_gdb "break $where\n"
+ # The first regexp is what we get with -g, the second without -g.
+ gdb_expect {
+ -re "Break.* at .*: file .*, line \[0-9\]*.*$gdb_prompt $" {}
+ -re "Breakpoint \[0-9\]* at 0x\[0-9a-f\]*.*$gdb_prompt $" {}
+ -re "$gdb_prompt $" { fail "setting breakpoint at $where" ; return 0 }
+ timeout { fail "setting breakpoint at $where (timeout)" ; return 0 }
+ }
+ pass "set_bp"
+}
+
+proc step_it { cmd } {
+ global gdb_prompt
+ global program_exited
+
+ send_gdb "$cmd\n"
+ gdb_expect {
+ -re "0x\[0-9A-Fa-f\]* *in.*\r\n$gdb_prompt $" { pass "step_it"; return 0 }
+ -re "0x\[0-9A-Fa-f\]* *\[0-9\]*.*\r\n$gdb_prompt $" { pass "step_it"; return 1 }
+ -re "Program exited .*\n$gdb_prompt $" {
+ set program_exited 1
+ return -1
+ }
+ -re "$gdb_prompt $" { fail "single-stepping ($cmd).\n" ; return -1 }
+ timeout { fail "single-stepping ($cmd) timout.\n" ; return -1 }
+ }
+}
+
+proc step_inst {} {
+ step_it "stepi"
+}
+
+proc step_source {} {
+ step_it "step"
+}
+
+proc continue_all {} {
+ global gdb_prompt
+
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Breakpoint \[0-9\]*, thread\[0-9\]* .*$gdb_prompt $" {
+ pass "continue_all"
+ return 0
+ }
+ -re "Program exited .*\n$gdb_prompt $" {
+ set program_exited 1
+ return 1;
+ }
+ -re "$gdb_prompt $" { fail "continue" ; return -1 }
+ timeout { fail "continue (timeout)" ; return -1 }
+ }
+}
+
+proc check_threads { num_threads } {
+ global gdb_prompt
+
+ set curr_thread 0
+ send_gdb "info threads\n"
+ while { $num_threads > 0 } {
+ gdb_expect {
+ -re "\\* *\[0-9\]* process \[0-9\]* thread \[0-9\]* .*\n" {
+ incr curr_thread
+ set num_threads [expr $num_threads - 1]
+ }
+ -re " *\[0-9\]* process \[0-9\]* thread \[0-9\]* .*\n" {
+ set num_threads [expr $num_threads - 1]
+ }
+ -re "$gdb_prompt $" {
+ if { $num_threads < 0 } {
+ fail "check_threads (too many)" ; return -1
+ }
+ break
+ }
+ timeout { fail "check_threads (timeout)" ; return -1 }
+ }
+ }
+
+ if { $curr_thread == 0 } {
+ fail "check_threads (no current thread)\n"
+ return -1
+ }
+ if { $curr_thread > 1 } {
+ fail "check_threads (more than one current thread)\n"
+ return -1
+ }
+ return 0
+}
+
+proc test_cond_wait {} {
+ global program_exited
+
+ set_bp 135
+ runto 179
+ while { 1 } {
+ set stepi_counter 0
+ while { [step_inst] } {
+ if { $program_exited } { break }
+ incr stepi_counter
+ if { $stepi_counter > 30 } {
+ fail "too many stepi's per line\n"
+ return -1
+ }
+ }
+ if { $program_exited } { break }
+ step_source
+ if { $program_exited } { break }
+ continue_all
+ if { $program_exited } { break }
+ check_threads 3
+ }
+}
+
+proc do_tests {} {
+ global prms_id
+ global bug_id
+ global subdir
+ global objdir
+ global srcdir
+ global binfile
+ global gdb_prompt
+
+ set prms_id 0
+ set bug_id 0
+
+ # Start with a fresh gdb.
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $objdir/$subdir/$binfile
+
+ send_gdb "set width 0\n"
+ gdb_expect -re "$gdb_prompt $"
+
+ test_cond_wait
+}
+
+# Check to see if we have an executable to test. If not, then either we
+# haven't tried to compile one, or the compilation failed for some reason.
+# In either case, just notify the user and skip the tests in this file.
+
+set binfile "step"
+set srcfile "step.c"
+
+if ![file exists $objdir/$subdir/$binfile] then {
+ if $all_flag then {
+ warning "$binfile does not exist; tests suppressed."
+ }
+} else {
+ do_tests
+}
Index: interrupted-hand-call.c
===================================================================
--- interrupted-hand-call.c (nonexistent)
+++ interrupted-hand-call.c (revision 816)
@@ -0,0 +1,149 @@
+/* Test case for hand function calls interrupted by a signal in another thread.
+
+ Copyright 2008, 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifndef NR_THREADS
+#define NR_THREADS 4
+#endif
+
+pthread_t threads[NR_THREADS];
+
+/* Number of threads currently running. */
+int thread_count;
+
+pthread_mutex_t thread_count_mutex;
+
+pthread_cond_t thread_count_condvar;
+
+sig_atomic_t sigabrt_received;
+
+void
+incr_thread_count (void)
+{
+ pthread_mutex_lock (&thread_count_mutex);
+ ++thread_count;
+ if (thread_count == NR_THREADS)
+ pthread_cond_signal (&thread_count_condvar);
+ pthread_mutex_unlock (&thread_count_mutex);
+}
+
+void
+cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut)
+{
+ pthread_mutex_lock (mut);
+ pthread_cond_wait (cond, mut);
+ pthread_mutex_unlock (mut);
+}
+
+void
+noreturn (void)
+{
+ pthread_mutex_t mut;
+ pthread_cond_t cond;
+
+ pthread_mutex_init (&mut, NULL);
+ pthread_cond_init (&cond, NULL);
+
+ /* Wait for a condition that will never be signaled, so we effectively
+ block the thread here. */
+ cond_wait (&cond, &mut);
+}
+
+void *
+thread_entry (void *unused)
+{
+ incr_thread_count ();
+ noreturn ();
+}
+
+void
+sigabrt_handler (int signo)
+{
+ sigabrt_received = 1;
+}
+
+/* Helper to test a hand-call being "interrupted" by a signal on another
+ thread. */
+
+void
+hand_call_with_signal (void)
+{
+ const struct timespec ts = { 0, 10000000 }; /* 0.01 sec */
+
+ sigabrt_received = 0;
+ pthread_kill (threads[0], SIGABRT);
+ while (! sigabrt_received)
+ nanosleep (&ts, NULL);
+}
+
+/* Wait until all threads are running. */
+
+void
+wait_all_threads_running (void)
+{
+ pthread_mutex_lock (&thread_count_mutex);
+ if (thread_count == NR_THREADS)
+ {
+ pthread_mutex_unlock (&thread_count_mutex);
+ return;
+ }
+ pthread_cond_wait (&thread_count_condvar, &thread_count_mutex);
+ if (thread_count == NR_THREADS)
+ {
+ pthread_mutex_unlock (&thread_count_mutex);
+ return;
+ }
+ pthread_mutex_unlock (&thread_count_mutex);
+ printf ("failed waiting for all threads to start\n");
+ abort ();
+}
+
+/* Called when all threads are running.
+ Easy place for a breakpoint. */
+
+void
+all_threads_running (void)
+{
+}
+
+int
+main (void)
+{
+ int i;
+
+ signal (SIGABRT, sigabrt_handler);
+
+ pthread_mutex_init (&thread_count_mutex, NULL);
+ pthread_cond_init (&thread_count_condvar, NULL);
+
+ for (i = 0; i < NR_THREADS; ++i)
+ pthread_create (&threads[i], NULL, thread_entry, NULL);
+
+ wait_all_threads_running ();
+ all_threads_running ();
+
+ return 0;
+}
+
interrupted-hand-call.c
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: manythreads.exp
===================================================================
--- manythreads.exp (nonexistent)
+++ manythreads.exp (revision 816)
@@ -0,0 +1,175 @@
+# manythreads.exp -- Expect script to test stopping many threads
+# Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file was written by Jeff Johnston. (jjohnstn@redhat.com)
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "manythreads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "set print sevenbit-strings" ""
+runto_main
+
+# We'll need this when we send_gdb a ^C to GDB. Need to do it before we
+# run the program and gdb starts saving and restoring tty states.
+# On Ultrix, we don't need it and it is really slow (because shell_escape
+# doesn't use vfork).
+if ![istarget "*-*-ultrix*"] then {
+ gdb_test "shell stty intr '^C'" ""
+}
+
+set message "first continue"
+gdb_test_multiple "continue" "first continue" {
+ -re "error:.*$gdb_prompt $" {
+ fail "$message"
+ }
+ -re "Continuing" {
+ pass "$message"
+ }
+}
+
+# Wait one second. This is better than the TCL "after" command, because
+# we don't lose GDB's output while we do it.
+remote_expect host 1 { timeout { } }
+
+# Send a Ctrl-C and verify that we can do info threads and continue
+send_gdb "\003"
+set message "stop threads 1"
+gdb_test_multiple "" "stop threads 1" {
+ -re "\\\[New \[^\]\]*\\\]\r\n" {
+ exp_continue
+ }
+ -re "\\\[\[^\]\]* exited\\\]\r\n" {
+ exp_continue
+ }
+ -re "Thread \[^\n\]* executing\r\n" {
+ exp_continue
+ }
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ pass "$message"
+ }
+ timeout {
+ fail "$message (timeout)"
+ }
+}
+
+set cmd "info threads"
+set ok 0
+gdb_test_multiple $cmd $cmd {
+ -re " 1 Thread " {
+ set ok 1
+ exp_continue
+ }
+ -re ".*\r\n" {
+ # Eat this line and continue, to prevent the buffer overflowing.
+ exp_continue
+ }
+ -re "$gdb_prompt $" {
+ if { $ok } {
+ pass $cmd
+ } else {
+ fail $cmd
+ }
+ }
+}
+
+set message "second continue"
+gdb_test_multiple "continue" "second continue" {
+ -re "error:.*$gdb_prompt $" {
+ fail "$message"
+ }
+ -re "Continuing" {
+ pass "$message"
+ }
+}
+
+# Wait another second. If the program stops on its own, GDB has failed
+# to handle duplicate SIGINTs sent to multiple threads.
+set failed 0
+remote_expect host 1 {
+ -re "\\\[New \[^\]\]*\\\]\r\n" {
+ exp_continue -continue_timer
+ }
+ -re "\\\[\[^\]\]* exited\\\]\r\n" {
+ exp_continue -continue_timer
+ }
+ -re "Thread \[^\n\]* executing\r\n" {
+ exp_continue -continue_timer
+ }
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ if { $failed == 0 } {
+ fail "check for duplicate SIGINT"
+ }
+ send_gdb "continue\n"
+ set failed 1
+ exp_continue
+ }
+ timeout {
+ if { $failed == 0 } {
+ pass "check for duplicate SIGINT"
+ }
+ }
+}
+
+# Send another Ctrl-C and verify that we can do info threads and quit
+send_gdb "\003"
+set message "stop threads 2"
+gdb_test_multiple "" "stop threads 2" {
+ -re "\\\[New \[^\]\]*\\\]\r\n" {
+ exp_continue
+ }
+ -re "\\\[\[^\]\]* exited\\\]\r\n" {
+ exp_continue
+ }
+ -re "Thread \[^\n\]* executing\r\n" {
+ exp_continue
+ }
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ pass "$message"
+ }
+ timeout {
+ fail "$message (timeout)"
+ }
+}
+
+gdb_test_multiple "quit" "GDB exits after stopping multithreaded program" {
+ -re "Quit anyway\\? \\(y or n\\) $" {
+ send_gdb "y\n"
+ exp_continue
+ }
+ eof {
+ pass "GDB exits after stopping multithreaded program"
+ }
+ timeout {
+ fail "GDB exits after stopping multithreaded program (timeout)"
+ }
+}
+
Index: watchthreads-reorder.exp
===================================================================
--- watchthreads-reorder.exp (nonexistent)
+++ watchthreads-reorder.exp (revision 816)
@@ -0,0 +1,103 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Test GDB can cope with two watchpoints being hit by different threads at the
+# same time, GDB reports one of them and after "continue" to report the other
+# one GDB should not be confused by differently set watchpoints that time.
+# This is the goal of "reorder1". "reorder0" tests the basic functionality of
+# two watchpoints being hit at the same time, without reordering them during the
+# stop. The formerly broken functionality is due to the all-stop mode default
+# "show breakpoint always-inserted" being "off". Formerly the remembered hit
+# could be assigned during continuation of a thread with pending SIGTRAP to the
+# different/new watchpoint, just based on the watchpoint/debug register number.
+
+if {(![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"]
+ && ![istarget "ia64-*-*"])
+ || [target_info exists gdb,no_hardware_watchpoints]
+ || ![istarget *-*-linux*]} {
+ return 0
+}
+
+set testfile "watchthreads-reorder"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" ${binfile} executable [list debug additional_flags=-lrt]] != "" } {
+ return -1
+}
+
+foreach reorder {0 1} {
+
+ global pf_prefix
+ set prefix_test $pf_prefix
+ lappend pf_prefix "reorder$reorder:"
+
+ clean_restart $testfile
+
+ gdb_test "set can-use-hw-watchpoints 1"
+
+ if ![runto_main] {
+ return -1
+ }
+
+ # Use "rwatch" as "watch" would report the watchpoint changed just based on its
+ # read memory value during a stop by unrelated event. We are interested in not
+ # losing the hardware watchpoint trigger.
+
+ gdb_test "rwatch thread1_rwatch" "Hardware read watchpoint \[0-9\]+: thread1_rwatch"
+ set test "rwatch thread2_rwatch"
+ gdb_test_multiple $test $test {
+ -re "Target does not support this type of hardware watchpoint\\.\r\n$gdb_prompt $" {
+ # ppc64 supports at most 1 hw watchpoints.
+ unsupported $test
+ return
+ }
+ -re "Hardware read watchpoint \[0-9\]+: thread2_rwatch\r\n$gdb_prompt $" {
+ pass $test
+ }
+ }
+ gdb_breakpoint [gdb_get_line_number "break-at-exit"]
+
+ # The watchpoints can happen in arbitrary order depending on random:
+ # SEL: Found 2 SIGTRAP events, selecting #[01]
+ # As GDB contains no srand() on the specific host/OS it will behave always the
+ # same. Such order cannot be guaranteed for GDB in general.
+
+ gdb_test "continue" \
+ "Hardware read watchpoint \[0-9\]+: thread\[12\]_rwatch\r\n\r\nValue = 0\r\n0x\[0-9a-f\]+ in thread\[12\]_func .*" \
+ "continue a"
+
+ if $reorder {
+ # GDB orders watchpoints by their addresses so inserting new variables
+ # with lower addresses will shift the former watchpoints to higher
+ # debug registers.
+
+ gdb_test "rwatch unused1_rwatch" "Hardware read watchpoint \[0-9\]+: unused1_rwatch"
+ gdb_test "rwatch unused2_rwatch" "Hardware read watchpoint \[0-9\]+: unused2_rwatch"
+ }
+
+ gdb_test "continue" \
+ "Hardware read watchpoint \[0-9\]+: thread\[12\]_rwatch\r\n\r\nValue = 0\r\n0x\[0-9a-f\]+ in thread\[12\]_func .*" \
+ "continue b"
+
+ # While the debug output itself is not checked in this testcase one bug was
+ # found in the DEBUG_INFRUN code path.
+ gdb_test "set debug infrun 1"
+
+ gdb_continue_to_breakpoint "break-at-exit" ".*break-at-exit.*"
+
+ set pf_prefix $prefix_test
+}
Index: watchthreads.exp
===================================================================
--- watchthreads.exp (nonexistent)
+++ watchthreads.exp (revision 816)
@@ -0,0 +1,199 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# Check that GDB can support multiple watchpoints across threads.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# This test verifies that a watchpoint is detected in the proper thread
+# so the test is only meaningful on a system with hardware watchpoints.
+if [target_info exists gdb,no_hardware_watchpoints] {
+ return 0;
+}
+
+proc target_no_stopped_data { } {
+ return [istarget s390*-*-*]
+}
+
+set testfile "watchthreads"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "set can-use-hw-watchpoints 1" "" ""
+
+#
+# Run to `main' where we begin our tests.
+#
+
+if ![runto_main] then {
+ gdb_suppress_tests
+}
+
+set args_0 0
+set args_1 0
+
+# Watch values that will be modified by distinct threads.
+gdb_test "watch args\[0\]" "Hardware watchpoint 2: args\\\[0\\\]"
+gdb_test "watch args\[1\]" "Hardware watchpoint 3: args\\\[1\\\]"
+set hwwp_2_enabled 1
+set hwwp_3_enabled 1
+
+set init_line [gdb_get_line_number "Init value"]
+set inc_line [gdb_get_line_number "Loop increment"]
+set main_loc "main \\\(\\\) at .*watchthreads.c:$init_line"
+set thread0_loc "thread_function \\\(arg=0x0\\\) at .*watchthreads.c:$inc_line"
+set thread1_loc "thread_function \\\(arg=0x1\\\) at .*watchthreads.c:$inc_line"
+
+# Loop and continue to allow both watchpoints to be triggered.
+for {set i 0} {$i < 30} {incr i} {
+ set test_flag_0 0
+ set test_flag_1 0
+ set test_flag 0
+ gdb_test_multiple "continue" "threaded watch loop" {
+ -re "(.*Hardware watchpoint.*)$gdb_prompt $" {
+ # At least one hardware watchpoint was hit. Check if both were.
+ set string $expect_out(1,string)
+
+ if [regexp "Hardware watchpoint 2: args\\\[0\\\]\[^\r\]*\r\[^\r\]*\r\[^\r\]*Old value = $args_0\[^\r\]*\r\[^\r\]*New value = [expr $args_0+1]\r" $string] {
+ incr args_0
+ incr test_flag_0
+ }
+ if [regexp "Hardware watchpoint 3: args\\\[1\\\]\[^\r\]*\r\[^\r\]*\r\[^\r\]*Old value = $args_1\[^\r\]*\r\[^\r\]*New value = [expr $args_1+1]\r" $string] {
+ incr args_1
+ incr test_flag_1
+ }
+
+ set expected_loc "bogus location"
+ if { $test_flag_0 == 1 && $test_flag_1 == 0 && $args_0 == 1 } {
+ set expected_loc $main_loc
+ } elseif { $test_flag_0 == 0 && $test_flag_1 == 1 && $args_1 == 1 } {
+ set expected_loc $main_loc
+ } elseif { $test_flag_0 == 1 && $test_flag_1 == 0 } {
+ set expected_loc $thread0_loc
+ } elseif { $test_flag_0 == 0 && $test_flag_1 == 1 } {
+ set expected_loc $thread1_loc
+ } elseif { $test_flag_0 + $test_flag_1 == 2 } {
+ # On S/390, or any other system which can not report the
+ # stopped data address, it is OK to report two watchpoints
+ # at once in this test. Make sure the reported location
+ # corresponds to at least one of the watchpoints (and not,
+ # e.g., __nptl_create_event). On other systems, we should
+ # report the two watchpoints serially.
+ if { [target_no_stopped_data] } {
+ set expected_loc "($main_loc|$thread0_loc|$thread1_loc)"
+ }
+ }
+
+ if [ regexp "$expected_loc" $string ] {
+ set test_flag 1
+ } else {
+ fail "threaded watch loop"
+ }
+
+ # If one of the watchpoints is disabled, we'd better not stop there.
+ if { !$hwwp_2_enabled && $test_flag_0 } {
+ fail "disabled hw watchpoint 2 triggered"
+ }
+ if { !$hwwp_3_enabled && $test_flag_1 } {
+ fail "disabled hw watchpoint 3 triggered"
+ }
+
+ # If we get to 10 in one of the watched locations disable it so we
+ # see some of the other watched location.
+ # 10 is chosen so we're guaranteed to come through here.
+ if { $hwwp_2_enabled && $hwwp_3_enabled } {
+ if { $args_0 >= 10 && $hwwp_2_enabled } {
+ gdb_test "disable 2" ""
+ set hwwp_2_enabled 0
+ } elseif { $args_1 >= 10 && $hwwp_3_enabled } {
+ gdb_test "disable 3" ""
+ set hwwp_3_enabled 0
+ }
+ }
+ }
+ }
+
+ # If we fail above, don't bother continuing loop
+ if { $test_flag == 0 } {
+ set i 30;
+ }
+}
+
+# Print success message if loop succeeded.
+if { $test_flag == 1 } {
+ pass "threaded watch loop"
+}
+
+# Verify that we hit first watchpoint in main thread.
+set message "first watchpoint on args\[0\] hit"
+if { $args_0 > 0 } {
+ pass $message
+} else {
+ fail $message
+}
+
+# Verify that we hit second watchpoint in main thread.
+set message "first watchpoint on args\[1\] hit"
+if { $args_1 > 0 } {
+ pass $message
+} else {
+ fail $message
+}
+
+# Verify that we hit first watchpoint in child thread.
+set message "watchpoint on args\[0\] hit in thread"
+if { $args_0 > 1 } {
+ pass $message
+} else {
+ fail $message
+}
+
+# Verify that we hit second watchpoint in child thread.
+set message "watchpoint on args\[1\] hit in thread"
+if { $args_1 > 1 } {
+ pass $message
+} else {
+ fail $message
+}
+
+# Verify that all watchpoint hits are accounted for.
+set message "combination of threaded watchpoints = 30"
+if { [target_no_stopped_data] } {
+ # See above. If we allow two watchpoints to be hit at once, we
+ # may have more than 30 hits total.
+ set result [expr $args_0 + $args_1 >= 30]
+} else {
+ set result [expr $args_0 + $args_1 == 30]
+}
+if { $result } {
+ pass $message
+} else {
+ fail $message
+}