* configure.in: Add config header.
Check for pthread.h. * configure: Regenerate. * config.in: New file. * pthreads.c: New file. * mi-pthreads.exp: New file to test thread functionality. * gdb669.exp: New file.
This commit is contained in:
parent
94b66fa77d
commit
d1a2f20434
|
@ -1,3 +1,13 @@
|
|||
2002-09-24 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* configure.in: Add config header.
|
||||
Check for pthread.h.
|
||||
* configure: Regenerate.
|
||||
* config.in: New file.
|
||||
* pthreads.c: New file.
|
||||
* mi-pthreads.exp: New file to test thread functionality.
|
||||
* gdb669.exp: New file.
|
||||
|
||||
2002-09-17 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* mi-var-cmd.exp: Add tests to check when varobj pinned to a
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define if you have the <pthread.h> header file. */
|
||||
#undef HAVE_PTHREAD_H
|
|
@ -522,6 +522,7 @@ fi
|
|||
|
||||
|
||||
|
||||
|
||||
CC=${CC-cc}
|
||||
|
||||
ac_aux_dir=
|
||||
|
@ -571,7 +572,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
|
|||
fi
|
||||
|
||||
echo $ac_n "checking host system type""... $ac_c" 1>&6
|
||||
echo "configure:575: checking host system type" >&5
|
||||
echo "configure:576: checking host system type" >&5
|
||||
|
||||
host_alias=$host
|
||||
case "$host_alias" in
|
||||
|
@ -592,7 +593,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
|||
echo "$ac_t""$host" 1>&6
|
||||
|
||||
echo $ac_n "checking target system type""... $ac_c" 1>&6
|
||||
echo "configure:596: checking target system type" >&5
|
||||
echo "configure:597: checking target system type" >&5
|
||||
|
||||
target_alias=$target
|
||||
case "$target_alias" in
|
||||
|
@ -610,7 +611,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
|||
echo "$ac_t""$target" 1>&6
|
||||
|
||||
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
||||
echo "configure:614: checking build system type" >&5
|
||||
echo "configure:615: checking build system type" >&5
|
||||
|
||||
build_alias=$build
|
||||
case "$build_alias" in
|
||||
|
@ -633,6 +634,128 @@ test "$host_alias" != "$target_alias" &&
|
|||
program_prefix=${target_alias}-
|
||||
|
||||
|
||||
# Check for pthread.h
|
||||
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
|
||||
echo "configure:640: checking how to run the C preprocessor" >&5
|
||||
# On Suns, sometimes $CPP names a directory.
|
||||
if test -n "$CPP" && test -d "$CPP"; then
|
||||
CPP=
|
||||
fi
|
||||
if test -z "$CPP"; then
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
# This must be in double quotes, not single quotes, because CPP may get
|
||||
# substituted into the Makefile and "${CC-cc}" will confuse make.
|
||||
CPP="${CC-cc} -E"
|
||||
# On the NeXT, cc -E runs the code through the compiler's parser,
|
||||
# not just through cpp.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 655 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <assert.h>
|
||||
Syntax Error
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:661: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
else
|
||||
echo "$ac_err" >&5
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -rf conftest*
|
||||
CPP="${CC-cc} -E -traditional-cpp"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 672 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <assert.h>
|
||||
Syntax Error
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:678: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
else
|
||||
echo "$ac_err" >&5
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -rf conftest*
|
||||
CPP="${CC-cc} -nologo -E"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 689 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <assert.h>
|
||||
Syntax Error
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:695: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
else
|
||||
echo "$ac_err" >&5
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -rf conftest*
|
||||
CPP=/lib/cpp
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
rm -f conftest*
|
||||
ac_cv_prog_CPP="$CPP"
|
||||
fi
|
||||
CPP="$ac_cv_prog_CPP"
|
||||
else
|
||||
ac_cv_prog_CPP="$CPP"
|
||||
fi
|
||||
echo "$ac_t""$CPP" 1>&6
|
||||
|
||||
for ac_hdr in pthread.h
|
||||
do
|
||||
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
|
||||
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
|
||||
echo "configure:723: checking for $ac_hdr" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 728 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <$ac_hdr>
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:733: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_header_$ac_safe=yes"
|
||||
else
|
||||
echo "$ac_err" >&5
|
||||
echo "configure: failed program was:" >&5
|
||||
cat conftest.$ac_ext >&5
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_header_$ac_safe=no"
|
||||
fi
|
||||
rm -f conftest*
|
||||
fi
|
||||
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
|
||||
echo "$ac_t""yes" 1>&6
|
||||
ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
|
||||
cat >> confdefs.h <<EOF
|
||||
#define $ac_tr_hdr 1
|
||||
EOF
|
||||
|
||||
else
|
||||
echo "$ac_t""no" 1>&6
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
trap '' 1 2 15
|
||||
cat > confcache <<\EOF
|
||||
# This file is a shell script that caches the results of configure
|
||||
|
@ -696,19 +819,7 @@ fi
|
|||
|
||||
trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
|
||||
|
||||
# Transform confdefs.h into DEFS.
|
||||
# Protect against shell expansion while executing Makefile rules.
|
||||
# Protect against Makefile macro expansion.
|
||||
cat > conftest.defs <<\EOF
|
||||
s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
|
||||
s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
|
||||
s%\[%\\&%g
|
||||
s%\]%\\&%g
|
||||
s%\$%$$%g
|
||||
EOF
|
||||
DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
|
||||
rm -f conftest.defs
|
||||
|
||||
DEFS=-DHAVE_CONFIG_H
|
||||
|
||||
# Without the "./", some shells look in PATH for config.status.
|
||||
: ${CONFIG_STATUS=./config.status}
|
||||
|
@ -745,7 +856,7 @@ done
|
|||
|
||||
ac_given_srcdir=$srcdir
|
||||
|
||||
trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
||||
trap 'rm -fr `echo "Makefile config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
||||
EOF
|
||||
cat >> $CONFIG_STATUS <<EOF
|
||||
|
||||
|
@ -793,6 +904,7 @@ s%@build_alias@%$build_alias%g
|
|||
s%@build_cpu@%$build_cpu%g
|
||||
s%@build_vendor@%$build_vendor%g
|
||||
s%@build_os@%$build_os%g
|
||||
s%@CPP@%$CPP%g
|
||||
|
||||
CEOF
|
||||
EOF
|
||||
|
@ -888,6 +1000,113 @@ s%@top_srcdir@%$top_srcdir%g
|
|||
fi; done
|
||||
rm -f conftest.s*
|
||||
|
||||
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
|
||||
# NAME is the cpp macro being defined and VALUE is the value it is being given.
|
||||
#
|
||||
# ac_d sets the value in "#define NAME VALUE" lines.
|
||||
ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
|
||||
ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
|
||||
ac_dC='\3'
|
||||
ac_dD='%g'
|
||||
# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
|
||||
ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
|
||||
ac_uB='\([ ]\)%\1#\2define\3'
|
||||
ac_uC=' '
|
||||
ac_uD='\4%g'
|
||||
# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
|
||||
ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
|
||||
ac_eB='$%\1#\2define\3'
|
||||
ac_eC=' '
|
||||
ac_eD='%g'
|
||||
|
||||
if test "${CONFIG_HEADERS+set}" != set; then
|
||||
EOF
|
||||
cat >> $CONFIG_STATUS <<EOF
|
||||
CONFIG_HEADERS="config.h:config.in"
|
||||
EOF
|
||||
cat >> $CONFIG_STATUS <<\EOF
|
||||
fi
|
||||
for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
|
||||
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
|
||||
case "$ac_file" in
|
||||
*:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
|
||||
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
|
||||
*) ac_file_in="${ac_file}.in" ;;
|
||||
esac
|
||||
|
||||
echo creating $ac_file
|
||||
|
||||
rm -f conftest.frag conftest.in conftest.out
|
||||
ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
|
||||
cat $ac_file_inputs > conftest.in
|
||||
|
||||
EOF
|
||||
|
||||
# Transform confdefs.h into a sed script conftest.vals that substitutes
|
||||
# the proper values into config.h.in to produce config.h. And first:
|
||||
# Protect against being on the right side of a sed subst in config.status.
|
||||
# Protect against being in an unquoted here document in config.status.
|
||||
rm -f conftest.vals
|
||||
cat > conftest.hdr <<\EOF
|
||||
s/[\\&%]/\\&/g
|
||||
s%[\\$`]%\\&%g
|
||||
s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
|
||||
s%ac_d%ac_u%gp
|
||||
s%ac_u%ac_e%gp
|
||||
EOF
|
||||
sed -n -f conftest.hdr confdefs.h > conftest.vals
|
||||
rm -f conftest.hdr
|
||||
|
||||
# This sed command replaces #undef with comments. This is necessary, for
|
||||
# example, in the case of _POSIX_SOURCE, which is predefined and required
|
||||
# on some systems where configure will not decide to define it.
|
||||
cat >> conftest.vals <<\EOF
|
||||
s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
|
||||
EOF
|
||||
|
||||
# Break up conftest.vals because some shells have a limit on
|
||||
# the size of here documents, and old seds have small limits too.
|
||||
|
||||
rm -f conftest.tail
|
||||
while :
|
||||
do
|
||||
ac_lines=`grep -c . conftest.vals`
|
||||
# grep -c gives empty output for an empty file on some AIX systems.
|
||||
if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
|
||||
# Write a limited-size here document to conftest.frag.
|
||||
echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
|
||||
sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
|
||||
echo 'CEOF
|
||||
sed -f conftest.frag conftest.in > conftest.out
|
||||
rm -f conftest.in
|
||||
mv conftest.out conftest.in
|
||||
' >> $CONFIG_STATUS
|
||||
sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
|
||||
rm -f conftest.vals
|
||||
mv conftest.tail conftest.vals
|
||||
done
|
||||
rm -f conftest.vals
|
||||
|
||||
cat >> $CONFIG_STATUS <<\EOF
|
||||
rm -f conftest.frag conftest.h
|
||||
echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
|
||||
cat conftest.in >> conftest.h
|
||||
rm -f conftest.in
|
||||
if cmp -s $ac_file conftest.h 2>/dev/null; then
|
||||
echo "$ac_file is unchanged"
|
||||
rm -f conftest.h
|
||||
else
|
||||
# Remove last slash and all that follows it. Not all systems have dirname.
|
||||
ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
|
||||
if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
|
||||
# The file is in a subdirectory.
|
||||
test ! -d "$ac_dir" && mkdir "$ac_dir"
|
||||
fi
|
||||
rm -f $ac_file
|
||||
mv conftest.h $ac_file
|
||||
fi
|
||||
fi; done
|
||||
|
||||
EOF
|
||||
cat >> $CONFIG_STATUS <<EOF
|
||||
|
||||
|
|
|
@ -6,10 +6,14 @@ dnl any existing configure script.
|
|||
|
||||
AC_PREREQ(2.5)
|
||||
AC_INIT(mi-basics.exp)
|
||||
AC_CONFIG_HEADER(config.h:config.in)
|
||||
|
||||
CC=${CC-cc}
|
||||
AC_SUBST(CC)
|
||||
AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/../../..)
|
||||
AC_CANONICAL_SYSTEM
|
||||
|
||||
# Check for pthread.h
|
||||
AC_CHECK_HEADERS(pthread.h)
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
# Copyright 2002 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# bug-gdb@prep.ai.mit.edu
|
||||
|
||||
# This file checks for the bug gdb/669, where the console
|
||||
# command "info threads" and the MI command "-thread-list-ids"
|
||||
# return different threads in the system.
|
||||
|
||||
# This only works with native configurations
|
||||
if {![isnative]} {
|
||||
return
|
||||
}
|
||||
|
||||
load_lib mi-support.exp
|
||||
set MIFLAGS "-i=mi"
|
||||
|
||||
gdb_exit
|
||||
if {[mi_gdb_start]} {
|
||||
continue
|
||||
}
|
||||
|
||||
# The procs below are all stolen from mi-pthreads.exp. Any updates
|
||||
# should also be made to the procs there.
|
||||
|
||||
proc get_mi_thread_list {name} {
|
||||
global expect_out
|
||||
|
||||
# MI will return a list of thread ids:
|
||||
#
|
||||
# -thread-list-ids
|
||||
# ^done,thread-ids=[thread-id="1",thread-id="2",...],number-of-threads="N"
|
||||
# (gdb)
|
||||
mi_gdb_test "-thread-list-ids" \
|
||||
{\^done,thread-ids={(thread-id="[0-9]+"(,)?)+},number-of-threads="[0-9]+"} \
|
||||
"-thread_list_ids ($name)"
|
||||
|
||||
set thread_list {}
|
||||
if {![regexp {thread-ids=\{(thread-id="[0-9]+"(,)?)*\}} $expect_out(buffer) threads]} {
|
||||
fail "finding threads in MI output ($name)"
|
||||
} else {
|
||||
pass "finding threads in MI output ($name)"
|
||||
|
||||
# Make list of console threads
|
||||
set start [expr {[string first \{ $threads] + 1}]
|
||||
set end [expr {[string first \} $threads] - 1}]
|
||||
set threads [string range $threads $start $end]
|
||||
foreach thread [split $threads ,] {
|
||||
if {[scan $thread {thread-id="%d"} num]} {
|
||||
lappend thread_list $num
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $thread_list
|
||||
}
|
||||
|
||||
# Check that MI and the console know of the same threads.
|
||||
# Appends NAME to all test names.
|
||||
proc check_mi_and_console_threads {name} {
|
||||
global expect_out
|
||||
|
||||
mi_gdb_test "-thread-list-ids" \
|
||||
{\^done,thread-ids={(thread-id="[0-9]+"(,)*)+},number-of-threads="[0-9]+"} \
|
||||
"-thread-list-ids ($name)"
|
||||
set mi_output $expect_out(buffer)
|
||||
|
||||
# GDB will return a list of thread ids and some more info:
|
||||
#
|
||||
# (gdb)
|
||||
# -interpreter-exec console "info threads"
|
||||
# ~" 4 Thread 2051 (LWP 7734) 0x401166b1 in __libc_nanosleep () at __libc_nanosleep:-1"
|
||||
# ~" 3 Thread 1026 (LWP 7733) () at __libc_nanosleep:-1"
|
||||
# ~" 2 Thread 2049 (LWP 7732) 0x401411f8 in __poll (fds=0x804bb24, nfds=1, timeout=2000) at ../sysdeps/unix/sysv/linux/poll.c:63"
|
||||
# ~"* 1 Thread 1024 (LWP 7731) main (argc=1, argv=0xbfffdd94) at ../../../src/gdb/testsuite/gdb.mi/pthreads.c:160"
|
||||
# FIXME: kseitz/2002-09-05: Don't use the hack-cli method.
|
||||
mi_gdb_test "info threads" \
|
||||
{.*(~".*"[\r\n]*)+.*} \
|
||||
"info threads ($name)"
|
||||
set console_output $expect_out(buffer)
|
||||
|
||||
# Make a list of all known threads to console (gdb's thread IDs)
|
||||
set console_thread_list {}
|
||||
foreach line [split $console_output \n] {
|
||||
if {[string index $line 0] == "~"} {
|
||||
# This is a line from the console; trim off "~", " ", "*", and "\""
|
||||
set line [string trim $line ~\ \"\*]
|
||||
if {[scan $line "%d" id] == 1} {
|
||||
lappend console_thread_list $id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Now find the result string from MI
|
||||
set mi_result ""
|
||||
foreach line [split $mi_output \n] {
|
||||
if {[string range $line 0 4] == "^done"} {
|
||||
set mi_result $line
|
||||
}
|
||||
}
|
||||
if {$mi_result == ""} {
|
||||
fail "finding MI result string ($name)"
|
||||
} else {
|
||||
pass "finding MI result string ($name)"
|
||||
}
|
||||
|
||||
# Finally, extract the thread ids and compare them to the console
|
||||
set num_mi_threads_str ""
|
||||
if {![regexp {number-of-threads="[0-9]+"} $mi_result num_mi_threads_str]} {
|
||||
fail "finding number of threads in MI output ($name)"
|
||||
} else {
|
||||
pass "finding number of threads in MI output ($name)"
|
||||
|
||||
# Extract the number of threads from the MI result
|
||||
if {![scan $num_mi_threads_str {number-of-threads="%d"} num_mi_threads]} {
|
||||
fail "got number of threads from MI ($name)"
|
||||
} else {
|
||||
pass "got number of threads from MI ($name)"
|
||||
|
||||
# Check if MI and console have same number of threads
|
||||
if {$num_mi_threads != [llength $console_thread_list]} {
|
||||
fail "console and MI have same number of threads ($name)"
|
||||
} else {
|
||||
pass "console and MI have same number of threads ($name)"
|
||||
|
||||
# Get MI thread list
|
||||
set mi_thread_list [get_mi_thread_list $name]
|
||||
|
||||
# Check if MI and console have the same threads
|
||||
set fails 0
|
||||
foreach ct [lsort $console_thread_list] mt [lsort $mi_thread_list] {
|
||||
if {$ct != $mt} {
|
||||
incr fails
|
||||
}
|
||||
}
|
||||
if {$fails > 0} {
|
||||
fail "MI and console have same threads ($name)"
|
||||
|
||||
# Send a list of failures to the log
|
||||
send_log "Console has thread ids: $console_thread_list\n"
|
||||
send_log "MI has thread ids: $mi_thread_list\n"
|
||||
} else {
|
||||
pass "MI and console have same threads ($name)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Start here
|
||||
#
|
||||
set testfile "pthreads"
|
||||
set srcfile "$testfile.c"
|
||||
set binfile "$objdir/$subdir/$testfile"
|
||||
|
||||
set options [list debug incdir=$subdir]
|
||||
if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $options]
|
||||
!= "" } {
|
||||
gdb_suppress_entire_file \
|
||||
"Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
mi_gdb_reinitialize_dir $srcdir/$subdir
|
||||
mi_gdb_load $binfile
|
||||
|
||||
mi_run_to_main
|
||||
check_mi_and_console_threads "at main"
|
||||
|
||||
for {set i 0} {$i < 4} {incr i} {
|
||||
mi_next "next, try $i"
|
||||
check_mi_and_console_threads "try $i"
|
||||
}
|
||||
|
||||
mi_gdb_exit
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
# Copyright 2002 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# Please email any bugs, comments, and/or additions to this file to:
|
||||
# bug-gdb@prep.ai.mit.edu
|
||||
|
||||
# This file tests MI thread commands.
|
||||
# Specifically, we are testing the MI command set and the console (in MI)
|
||||
# command set ("interpreter-exec") and that the commands that are executed
|
||||
# via these command pathways are properly executed. Console commands
|
||||
# executed via MI should use MI output wrappers, MI event handlers, etc.
|
||||
|
||||
# This only works with native configurations
|
||||
if {![isnative]} {
|
||||
return
|
||||
}
|
||||
|
||||
load_lib mi-support.exp
|
||||
set MIFLAGS "-i=mi"
|
||||
|
||||
gdb_exit
|
||||
if {[mi_gdb_start]} {
|
||||
continue
|
||||
}
|
||||
|
||||
# The procs below dealing with parsing cli/mi output for the threadlist
|
||||
# is duplicated in gdb669.exp. Any changes here will probably need to
|
||||
# be made there as well.
|
||||
|
||||
proc get_mi_thread_list {name} {
|
||||
global expect_out
|
||||
|
||||
# MI will return a list of thread ids:
|
||||
#
|
||||
# -thread-list-ids
|
||||
# ^done,thread-ids=[thread-id="1",thread-id="2",...],number-of-threads="N"
|
||||
# (gdb)
|
||||
mi_gdb_test "-thread-list-ids" \
|
||||
{\^done,thread-ids={(thread-id="[0-9]+"(,)?)+},number-of-threads="[0-9]+"} \
|
||||
"-thread_list_ids ($name)"
|
||||
|
||||
set thread_list {}
|
||||
if {![regexp {thread-ids=\{(thread-id="[0-9]+"(,)?)*\}} $expect_out(buffer) threads]} {
|
||||
fail "finding threads in MI output ($name)"
|
||||
} else {
|
||||
pass "finding threads in MI output ($name)"
|
||||
|
||||
# Make list of console threads
|
||||
set start [expr {[string first \{ $threads] + 1}]
|
||||
set end [expr {[string first \} $threads] - 1}]
|
||||
set threads [string range $threads $start $end]
|
||||
foreach thread [split $threads ,] {
|
||||
if {[scan $thread {thread-id="%d"} num]} {
|
||||
lappend thread_list $num
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $thread_list
|
||||
}
|
||||
|
||||
# Check that MI and the console know of the same threads.
|
||||
# Appends NAME to all test names.
|
||||
proc check_mi_and_console_threads {name} {
|
||||
global expect_out
|
||||
|
||||
mi_gdb_test "-thread-list-ids" \
|
||||
{\^done,thread-ids={(thread-id="[0-9]+"(,)*)+},number-of-threads="[0-9]+"} \
|
||||
"-thread-list-ids ($name)"
|
||||
set mi_output $expect_out(buffer)
|
||||
|
||||
# GDB will return a list of thread ids and some more info:
|
||||
#
|
||||
# (gdb)
|
||||
# -interpreter-exec console "info threads"
|
||||
# ~" 4 Thread 2051 (LWP 7734) 0x401166b1 in __libc_nanosleep () at __libc_nanosleep:-1"
|
||||
# ~" 3 Thread 1026 (LWP 7733) () at __libc_nanosleep:-1"
|
||||
# ~" 2 Thread 2049 (LWP 7732) 0x401411f8 in __poll (fds=0x804bb24, nfds=1, timeout=2000) at ../sysdeps/unix/sysv/linux/poll.c:63"
|
||||
# ~"* 1 Thread 1024 (LWP 7731) main (argc=1, argv=0xbfffdd94) at ../../../src/gdb/testsuite/gdb.mi/pthreads.c:160"
|
||||
# FIXME: kseitz/2002-09-05: Don't use the hack-cli method.
|
||||
mi_gdb_test "info threads" \
|
||||
{.*(~".*"[\r\n]*)+.*} \
|
||||
"info threads ($name)"
|
||||
set console_output $expect_out(buffer)
|
||||
|
||||
# Make a list of all known threads to console (gdb's thread IDs)
|
||||
set console_thread_list {}
|
||||
foreach line [split $console_output \n] {
|
||||
if {[string index $line 0] == "~"} {
|
||||
# This is a line from the console; trim off "~", " ", "*", and "\""
|
||||
set line [string trim $line ~\ \"\*]
|
||||
if {[scan $line "%d" id] == 1} {
|
||||
lappend console_thread_list $id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Now find the result string from MI
|
||||
set mi_result ""
|
||||
foreach line [split $mi_output \n] {
|
||||
if {[string range $line 0 4] == "^done"} {
|
||||
set mi_result $line
|
||||
}
|
||||
}
|
||||
if {$mi_result == ""} {
|
||||
fail "finding MI result string ($name)"
|
||||
} else {
|
||||
pass "finding MI result string ($name)"
|
||||
}
|
||||
|
||||
# Finally, extract the thread ids and compare them to the console
|
||||
set num_mi_threads_str ""
|
||||
if {![regexp {number-of-threads="[0-9]+"} $mi_result num_mi_threads_str]} {
|
||||
fail "finding number of threads in MI output ($name)"
|
||||
} else {
|
||||
pass "finding number of threads in MI output ($name)"
|
||||
|
||||
# Extract the number of threads from the MI result
|
||||
if {![scan $num_mi_threads_str {number-of-threads="%d"} num_mi_threads]} {
|
||||
fail "got number of threads from MI ($name)"
|
||||
} else {
|
||||
pass "got number of threads from MI ($name)"
|
||||
|
||||
# Check if MI and console have same number of threads
|
||||
if {$num_mi_threads != [llength $console_thread_list]} {
|
||||
fail "console and MI have same number of threads ($name)"
|
||||
} else {
|
||||
pass "console and MI have same number of threads ($name)"
|
||||
|
||||
# Get MI thread list
|
||||
set mi_thread_list [get_mi_thread_list $name]
|
||||
|
||||
# Check if MI and console have the same threads
|
||||
set fails 0
|
||||
foreach ct [lsort $console_thread_list] mt [lsort $mi_thread_list] {
|
||||
if {$ct != $mt} {
|
||||
incr fails
|
||||
}
|
||||
}
|
||||
if {$fails > 0} {
|
||||
fail "MI and console have same threads ($name)"
|
||||
|
||||
# Send a list of failures to the log
|
||||
send_log "Console has thread ids: $console_thread_list\n"
|
||||
send_log "MI has thread ids: $mi_thread_list\n"
|
||||
} else {
|
||||
pass "MI and console have same threads ($name)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# This procedure tests the various thread commands in MI.
|
||||
proc check_mi_thread_command_set {} {
|
||||
|
||||
mi_runto done_making_threads
|
||||
|
||||
set thread_list [get_mi_thread_list "in check_mi_thread_command_set"]
|
||||
|
||||
mi_gdb_test "-thread-select" \
|
||||
{\^error,msg="mi_cmd_thread_select: USAGE: threadnum."} \
|
||||
"check_mi_thread_command_set: -thread-select"
|
||||
|
||||
mi_gdb_test "-thread-select 123456789" \
|
||||
{\^error,msg="Thread ID 123456789 not known\."} \
|
||||
"check_mi_thread_command_set: -thread-select 123456789"
|
||||
|
||||
foreach thread $thread_list {
|
||||
mi_gdb_test "-thread-select $thread" \
|
||||
"\\^done,new-thread-id=\"$thread\",frame={.*},line=\"(-)?\[0-9\]+\",file=\".*\"" \
|
||||
"check_mi_thread_command_set: -thread-select $thread"
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Start here
|
||||
#
|
||||
set testfile "pthreads"
|
||||
set srcfile "$testfile.c"
|
||||
set binfile "$objdir/$subdir/$testfile"
|
||||
|
||||
set options [list debug incdir=$subdir]
|
||||
if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $options]
|
||||
!= "" } {
|
||||
gdb_suppress_entire_file \
|
||||
"Testcase compile failed, so all tests in this file will automatically fail."
|
||||
}
|
||||
|
||||
mi_gdb_reinitialize_dir $srcdir/$subdir
|
||||
mi_gdb_load $binfile
|
||||
|
||||
check_mi_thread_command_set
|
||||
|
||||
mi_gdb_exit
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_PTHREAD_H
|
||||
|
||||
/* Don't even try to compile. In fact, cause a syntax error that we can
|
||||
look for as a compiler error message and know that we have no pthread
|
||||
support. In that case we can just suppress the test completely. */
|
||||
|
||||
#error "no posix threads support"
|
||||
|
||||
#else
|
||||
|
||||
/* OK. We have the right header. If we try to compile this and fail, then
|
||||
there is something wrong and the user should know about it so the testsuite
|
||||
should issue an ERROR result.. */
|
||||
|
||||
#ifdef __linux__
|
||||
#define _MIT_POSIX_THREADS 1 /* GNU/Linux (or at least RedHat 4.0)
|
||||
needs this */
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
/* 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
|
||||
|
||||
void *
|
||||
routine (void *arg)
|
||||
{
|
||||
sleep (9);
|
||||
printf ("hello thread\n");
|
||||
}
|
||||
|
||||
/* Marker function for the testsuite */
|
||||
void
|
||||
done_making_threads (void)
|
||||
{
|
||||
/* Nothing */
|
||||
};
|
||||
|
||||
void
|
||||
create_thread (void)
|
||||
{
|
||||
pthread_t tid;
|
||||
|
||||
if (pthread_create (&tid, PTHREAD_CREATE_NULL_ARG2, routine, (void *) 0xfeedface))
|
||||
{
|
||||
perror ("pthread_create 1");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Create a few threads */
|
||||
for (i = 0; i < 5; i++)
|
||||
create_thread ();
|
||||
done_making_threads ();
|
||||
|
||||
printf ("hello\n");
|
||||
printf ("hello\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ifndef HAVE_PTHREAD_H */
|
Loading…
Reference in New Issue