Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re: [RFA/RFC] thread local storage tests
@ 2003-02-08  5:41 Michael Elizabeth Chastain
  2003-02-08 16:50 ` Elena Zannoni
  0 siblings, 1 reply; 5+ messages in thread
From: Michael Elizabeth Chastain @ 2003-02-08  5:41 UTC (permalink / raw)
  To: ezannoni; +Cc: gdb-patches

Elena Z writes:

> What glibc(s) were you using?  It may also be due to slightly versions
> of binutils, even though, you are also using HEAD binutils, and it
> should work there.

glibc 2.2.93-5-rh, the vendor libc that comes with red hat linux 8.0.

My tables say: 'osversion=red-hat-8.0' and 'libc=vendor'.

> Do you have the gdb.logs for the cases that almost work?

Errr, I already moved them to /dev/null.  Damn.  But I can re-generate
them easily.

  ftp://ftp.shout.net/pub/users/mec/gdb/2003-02-07a-tls.tar.gz

The '7a' is because it's a different run than the tables that
I published.

Everything is in there.  There is one directory for each configuration
tested, with a 'gdb-test-run.xml', 'gdb.sum', 'gdb.log', and
'test.tar.gz'.  That last file is a tarball of the actual 'test'
directory which has the juicy executables.

Michael C


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFA/RFC] thread local storage tests
  2003-02-08  5:41 [RFA/RFC] thread local storage tests Michael Elizabeth Chastain
@ 2003-02-08 16:50 ` Elena Zannoni
  0 siblings, 0 replies; 5+ messages in thread
From: Elena Zannoni @ 2003-02-08 16:50 UTC (permalink / raw)
  To: Michael Elizabeth Chastain; +Cc: ezannoni, gdb-patches

Michael Elizabeth Chastain writes:
 > Elena Z writes:
 > 
 > > What glibc(s) were you using?  It may also be due to slightly versions
 > > of binutils, even though, you are also using HEAD binutils, and it
 > > should work there.
 > 
 > glibc 2.2.93-5-rh, the vendor libc that comes with red hat linux 8.0.
 > 
 > My tables say: 'osversion=red-hat-8.0' and 'libc=vendor'.
 > 

I think a more recent glibc is needed. :-( let me find out more.

 > > Do you have the gdb.logs for the cases that almost work?
 > 
 > Errr, I already moved them to /dev/null.  Damn.  But I can re-generate
 > them easily.
 > 
 >   ftp://ftp.shout.net/pub/users/mec/gdb/2003-02-07a-tls.tar.gz
 > 
 > The '7a' is because it's a different run than the tables that
 > I published.
 > 
 > Everything is in there.  There is one directory for each configuration
 > tested, with a 'gdb-test-run.xml', 'gdb.sum', 'gdb.log', and
 > 'test.tar.gz'.  That last file is a tarball of the actual 'test'
 > directory which has the juicy executables.
 > 

thanks, I'll take a look this evening.

elena


 > Michael C


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFA/RFC] thread local storage tests
  2003-02-08  1:32 Michael Elizabeth Chastain
@ 2003-02-08  4:35 ` Elena Zannoni
  0 siblings, 0 replies; 5+ messages in thread
From: Elena Zannoni @ 2003-02-08  4:35 UTC (permalink / raw)
  To: Michael Elizabeth Chastain; +Cc: ezannoni, gdb-patches

Michael Elizabeth Chastain writes:
 > http://www.shout.net/~mec/sunday/2003-02-07-tls/index.html
 > 
 > These tests use '__thread' which is available with gcc gcc-3_3-branch
 > and later.  So if you want to work on the test themselves you need
 > to grab a 3.3 or 3.4 compiler.
 > 
 > They also have problems even with those compilers.
 > 
 > Michael C

thanks, this is really useful.

Hmm, I suspected that. I was able to get them to run in the current
Redhat rawhide.

What glibc(s) were you using?  It may also be due to slightly versions
of binutils, even though, you are also using HEAD binutils, and it
should work there.

I don't know whether stabs has support for TLS, I doubt it.  In
dwarf2, if you use readelf -w, you should see, for the thread local
variables, a DW_OP_GNU_tls_push_address, in the debug info.

I ran into a compiler version that compiled the file happily, but
didn't produce the right information, It was marking the variale as a
regular static one.

On my system it refuses to compile it, I get the 2 unsupported
tests. At least something matches. :-(

Do you have the gdb.logs for the cases that almost work?


Elena





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [RFA/RFC] thread local storage tests
@ 2003-02-08  1:32 Michael Elizabeth Chastain
  2003-02-08  4:35 ` Elena Zannoni
  0 siblings, 1 reply; 5+ messages in thread
From: Michael Elizabeth Chastain @ 2003-02-08  1:32 UTC (permalink / raw)
  To: ezannoni, gdb-patches

http://www.shout.net/~mec/sunday/2003-02-07-tls/index.html

These tests use '__thread' which is available with gcc gcc-3_3-branch
and later.  So if you want to work on the test themselves you need
to grab a 3.3 or 3.4 compiler.

They also have problems even with those compilers.

Michael C


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [RFA/RFC] thread local storage tests
@ 2003-02-08  0:04 Elena Zannoni
  0 siblings, 0 replies; 5+ messages in thread
From: Elena Zannoni @ 2003-02-08  0:04 UTC (permalink / raw)
  To: gdb-patches


I am posting two tests for thread local storage, they work with the
latest and greatest combination of gcc, binutils, glibc.

On my old system (stock RH 7.2) they produce 2 unsupported results.

I suspect we'll have to go through a few iterations to get all the
possible error messages completely accounted for.

Hopefully somebody will be willing to give them a spin, and see what
happens on their system.

The files tls.exp and tls.c are modified versions of old HP tests that
were in the gdb.hp directory. Turns out they worked fine for us too,
the syntax is the same. I had to clean them up quite a bit, to
simplify and limit the scope of the test to TLS.  tls.c was used
also in another script to test other stuff. Maybe it's worth
resurrecting that too (we need more thread tests).

elena


* gdb.threads/tls.exp: New file. Based on gdb.hp/thr-stg.exp.
* gdb.threads/tls.c: New file. Evolved from gdb.hp/start-stop.c.
* gdb.threads/tls-shared.exp: New file.
* gdb.threads/tls-main.c: New file.
* gdb.threads/tls-shared.c: New file.




--- /dev/null	Thu Aug 30 16:30:55 2001
+++ tls.exp	Fri Feb  7 18:58:27 2003
@@ -0,0 +1,166 @@
+# tls.exp -- Expect script to test thread-local storage
+# Copyright (C) 1992, 2003 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
+
+set testfile tls
+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 [list debug "incdir=${objdir}"]] != "" } {
+    return -1
+}
+
+proc compute_expected_value {value} {
+    set expected_value 0
+    set i 0
+    while { $i < $value} {
+        incr expected_value $i
+        incr i
+    }
+    return $expected_value
+}
+
+proc get_global_variable { } {
+    global expect_out
+    global gdb_prompt
+    global decimal
+
+    set value_of_global -1
+    send_gdb "print a_global\n"
+    gdb_expect {
+	-re ".*= ($decimal).*\r\n$gdb_prompt $" {
+	    set value_of_global $expect_out(1,string)
+	    pass "print a_global"
+        }
+	-re "$gdb_prompt $" {
+	    fail "print a_global"
+	}
+	timeout {
+	    fail "print a_global (timeout)" 
+	}
+    }
+    return ${value_of_global}
+}
+
+proc check_thread_local {number} {
+    set global_variable [get_global_variable]
+    set expected_value [compute_expected_value ${global_variable}]
+    gdb_test "p a_thread_local" \
+	    "= $expected_value" \
+	    "${number} thread local storage"
+}
+
+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 bp at all threads"
+
+# Set a bp at the end to see if all threads are finished.
+#
+gdb_test "b [gdb_get_line_number "Dummy line"]" \
+         ".*Breakpoint 3.*tls.*" "set breakpoint at end"
+
+send_gdb "continue\n"
+gdb_expect {
+    -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 thread in spin: at first thread"
+
+check_thread_local "first"
+
+gdb_test "continue" ".*Breakpoint 2.*tls value.*" "continue to second thread"
+gdb_test "info thread" "Thread.*spin.*" \
+	"at least one thread in spin: at second thread"
+
+check_thread_local "second"
+
+gdb_test "continue" ".*Breakpoint 2.*tls value.*" "continue to third thread"
+gdb_test "info thread" ".*Thread.*spin.*" \
+	"at least one thread in spin: at third thread"
+
+check_thread_local "third"
+
+gdb_test "continue" ".*Breakpoint 3.*Dummy line.*" "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.*do_it.*$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.*" "i ad a_global"
+
+gdb_test "info address me"  ".*me.*is a variable at offset.*"  "i ad me"
+
+gdb_test "info address a_thread_local" \
+	".*a_thread_local.*a thread-local variable at offset.*" \
+	"i ad a_thread_local"
+
+# Done!
+#
+gdb_exit
+
+return 0



--- /dev/null	Thu Aug 30 16:30:55 2001
+++ tls.c	Fri Feb  7 18:58:27 2003
@@ -0,0 +1,160 @@
+/* BeginSourceFile tls.c
+
+  This file creates and deletes threads, so that gdb can be tested on
+  thread delete. It uses thread local storage variables too.
+
+  To compile:
+
+      cc -Ae +DA1.0 -g -o start_stop -lpthread tls.c
+
+  To run:
+  
+     start_stop     --normal run
+     start_stop 1 --waits in each thread to keep it alive.  */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <pthread.h>
+
+#define TRUE 1
+#define FALSE 0
+#define OUTER_LOOP_COUNT 3
+#define N_THREADS 3
+#define MAX_LOCAL_VAL 40
+
+/* Uncomment to turn on debugging output */
+/* #define START_DEBUG */
+
+/* True if waiting for attach.
+ */
+int wait_here;
+
+/* Thing to check for debugging purposes.
+*/
+int a_global = 0;
+
+/* Thread-local storage.
+ */
+__thread int a_thread_local;
+
+/* Check the results of thread-local storage.
+ */
+int thread_local_val[ N_THREADS ];
+
+/* Routine for each thread to run, does nothing.
+ */
+void *spin( vp )
+    void * vp;
+{
+    int me = (int) vp;
+    int i;
+    
+#ifdef START_DEBUG
+    printf( "== In thread %d\n", me );
+#endif
+
+    a_global++;
+
+    a_thread_local = 0;
+    for( i = 0; i < a_global; i++ ) {
+        a_thread_local += i;
+    }
+
+    thread_local_val[ me ] = a_thread_local; /* here we know tls value */
+
+#ifdef START_DEBUG
+    printf( "== Thread %d, a_thread_local is %d\n",
+            (int) vp, a_thread_local );
+#endif
+
+   if( wait_here ) {
+       /* Extend life of thread to extend life of thread-local var.
+        * This makes life easier for human debugging (though you'd
+        * probably want to make the delay longer).
+        */
+       sleep( 5 );
+   }
+}
+
+void
+do_pass( pass )
+    int pass;
+{
+    int i;
+    pthread_t t[ N_THREADS ];
+    int err;
+
+    for( i = 0; i < N_THREADS; i++) {
+        thread_local_val[i] = 0;
+    }
+   
+    /* Start N_THREADS threads, then join them so
+     * that they are terminated.
+     */
+    for( i = 0; i < N_THREADS; i++ ) {
+        err = pthread_create( &t[i], NULL, spin, (void *)i );
+        if( err != 0 ) {
+            printf( "== Start/stop, error in thread %d create\n", i );
+        }
+    }
+
+    for( i = 0; i < N_THREADS; i++ ) {
+        err = pthread_join(t[i], NULL );    /* Line 105 */
+        if( err != 0 ) {                    /* Line 106 */
+            printf( "== Start/stop, error in thread %d join\n", i );
+        }
+    }
+
+    i = 10;  /* Line 109.  Null line for setting bpts on. */
+
+#ifdef START_DEBUG
+    for( i = 0; i < N_THREADS; i++) {
+        printf( "   Local in thread %d was %d\n",
+                 i, thread_local_val[i]);
+    }
+    printf( "== Pass %d done\n", pass );
+#endif
+   
+}
+
+void
+do_it()
+{
+    /* We want to start some threads and then
+     * end them, and then do it again and again
+     */
+    int i;
+    int dummy;
+    
+    for( i = 0; i < OUTER_LOOP_COUNT; i++ ) {
+        do_pass( i );
+        dummy = i;      /* Dummy line for setting bps on */
+    }
+}
+
+main( argc, argv )
+int    argc;
+char **argv;
+{
+   wait_here = FALSE;
+   if((argc > 1) && (0 != argv )) {
+       if( 1 == atoi( argv[1] ) )
+           wait_here = TRUE;
+    }
+
+#ifdef START_DEBUG 
+    printf( "== Test starting\n" );
+#endif
+
+    do_it();
+    
+#ifdef START_DEBUG
+    printf( "== Test done\n" );
+#endif
+
+    return(0);
+}
+
+/* EndSourceFile */



--- /dev/null	Thu Aug 30 16:30:55 2001
+++ tls-shared.exp	Fri Feb  7 18:58:27 2003
@@ -0,0 +1,115 @@
+# Copyright 2003 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
+
+# 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]] != ""} {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+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 0 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"
+
+



--- /dev/null	Thu Aug 30 16:30:55 2001
+++ tls-shared.c	Fri Feb  7 18:58:27 2003
@@ -0,0 +1,6 @@
+__thread int i_tls = 1;
+int foo ()
+{
+  return i_tls;
+}
+



--- /dev/null	Thu Aug 30 16:30:55 2001
+++ tls-main.c	Fri Feb  7 18:58:26 2003
@@ -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 */
+}
+


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2003-02-08 16:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-08  5:41 [RFA/RFC] thread local storage tests Michael Elizabeth Chastain
2003-02-08 16:50 ` Elena Zannoni
  -- strict thread matches above, loose matches on Subject: below --
2003-02-08  1:32 Michael Elizabeth Chastain
2003-02-08  4:35 ` Elena Zannoni
2003-02-08  0:04 Elena Zannoni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox