This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA/MI testsuite] Add pthreads tests


Keith Seitz writes:
 > Hi,
 > 
 > This is a first stab at some pthreads tests for MI. It mainly checks to 
 > see that the MI thread commands and the console agree about threads 
 > (gdb/669), but it also checks the syntax of MI thread commands and the 
 > like. It will add several new failures to the testsuite, since there are 
 > bugs! RFAs and RFCs on those to follow once these tests are committed.
 > 
 > The pthreads.c file was largely stolen from 
 > testsuite/gdb.thread/pthreads.c but modified to demonstrate gdb/669.
 > 

I wonder if we should name the file gdb669.exp. 

OK otherwise.

Elena


 > Keith
 > 
 > ChangeLog
 > 2002-09-10  Keith Seitz  <keiths@redhat.com>
 > 
 >         * configure.in: Add config header.
 >         Check for pthread.h.
 >         * configure: Regenerate.
 >         * config.in: New file.
 >         * mi-pthreads.exp: New file to test thread functionality.
 >         * pthreads.c: New file.
 > 
 > Patch
 > Index: testsuite/gdb.mi/config.in
 > ===================================================================
 > RCS file: testsuite/gdb.mi/config.in
 > diff -N testsuite/gdb.mi/config.in
 > *** testsuite/gdb.mi/config.in	1 Jan 1970 00:00:00 -0000
 > --- testsuite/gdb.mi/config.in	10 Sep 2002 23:12:35 -0000
 > ***************
 > *** 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
 > Index: testsuite/gdb.mi/configure.in
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/configure.in,v
 > retrieving revision 1.1
 > diff -p -r1.1 configure.in
 > *** testsuite/gdb.mi/configure.in	23 Feb 2000 00:25:43 -0000	1.1
 > --- testsuite/gdb.mi/configure.in	10 Sep 2002 23:12:35 -0000
 > *************** dnl any existing configure script.
 > *** 6,15 ****
 > --- 6,19 ----
 >   
 >   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)
 > Index: testsuite/gdb.mi/mi-pthreads.exp
 > ===================================================================
 > RCS file: testsuite/gdb.mi/mi-pthreads.exp
 > diff -N testsuite/gdb.mi/mi-pthreads.exp
 > *** testsuite/gdb.mi/mi-pthreads.exp	1 Jan 1970 00:00:00 -0000
 > --- testsuite/gdb.mi/mi-pthreads.exp	10 Sep 2002 23:12:35 -0000
 > ***************
 > *** 0 ****
 > --- 1,219 ----
 > + # 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
 > + }
 > + 
 > + 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 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.
 > + proc check_for_gdb669_bug {} {
 > +   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"
 > +   }
 > + }
 > + 
 > + # 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
 > + check_for_gdb669_bug
 > + 
 > + mi_gdb_exit
 > + 
 > Index: testsuite/gdb.mi/pthreads.c
 > ===================================================================
 > RCS file: testsuite/gdb.mi/pthreads.c
 > diff -N testsuite/gdb.mi/pthreads.c
 > *** testsuite/gdb.mi/pthreads.c	1 Jan 1970 00:00:00 -0000
 > --- testsuite/gdb.mi/pthreads.c	10 Sep 2002 23:12:35 -0000
 > ***************
 > *** 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 */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]