Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Kevin Buettner <kevinb@redhat.com>
To: gdb-patches@sourceware.org
Cc: Kevin Buettner <kevinb@redhat.com>
Subject: [PATCH v6 09/11] New test - gdb.base/tls-multiobj.exp
Date: Fri,  4 Apr 2025 16:37:40 -0700	[thread overview]
Message-ID: <20250404234324.1931302-10-kevinb@redhat.com> (raw)
In-Reply-To: <20250404234324.1931302-1-kevinb@redhat.com>

This test exercises GDB's internal TLS support when both the main
program and several shared libraries have TLS variables.  It also
tests existing (non-internal) TLS support too.

It tests using two compilation scenarios, "default", in which
libpthread is not linked with the program and libraries as well
as one which does use libpthread.

It tests link map address to module id mapping code in GDB
in addition to the ability of GDB to traverse TLS data structures
with several libraries in play.
---
 gdb/testsuite/gdb.base/tls-multiobj.c   |  89 +++++++++
 gdb/testsuite/gdb.base/tls-multiobj.exp | 230 ++++++++++++++++++++++++
 gdb/testsuite/gdb.base/tls-multiobj1.c  |  26 +++
 gdb/testsuite/gdb.base/tls-multiobj2.c  |  26 +++
 gdb/testsuite/gdb.base/tls-multiobj3.c  |  26 +++
 5 files changed, 397 insertions(+)
 create mode 100644 gdb/testsuite/gdb.base/tls-multiobj.c
 create mode 100644 gdb/testsuite/gdb.base/tls-multiobj.exp
 create mode 100644 gdb/testsuite/gdb.base/tls-multiobj1.c
 create mode 100644 gdb/testsuite/gdb.base/tls-multiobj2.c
 create mode 100644 gdb/testsuite/gdb.base/tls-multiobj3.c

diff --git a/gdb/testsuite/gdb.base/tls-multiobj.c b/gdb/testsuite/gdb.base/tls-multiobj.c
new file mode 100644
index 00000000000..10e67da54d8
--- /dev/null
+++ b/gdb/testsuite/gdb.base/tls-multiobj.c
@@ -0,0 +1,89 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2024 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/>.  */
+
+__thread int tls_main_tbss_1;
+__thread int tls_main_tbss_2;
+__thread int tls_main_tdata_1 = 96;
+__thread int tls_main_tdata_2 = 97;
+
+extern __thread int tls_lib1_tbss_1;
+extern __thread int tls_lib1_tbss_2;
+extern __thread int tls_lib1_tdata_1;
+extern __thread int tls_lib1_tdata_2;
+
+extern __thread int tls_lib2_tbss_1;
+extern __thread int tls_lib2_tbss_2;
+extern __thread int tls_lib2_tdata_1;
+extern __thread int tls_lib2_tdata_2;
+
+extern __thread int tls_lib3_tbss_1;
+extern __thread int tls_lib3_tbss_2;
+extern __thread int tls_lib3_tdata_1;
+extern __thread int tls_lib3_tdata_2;
+
+extern void lib1_func ();
+extern void lib2_func ();
+extern void lib3_func ();
+
+volatile int data;
+
+void
+use_it (int a)
+{
+  data = a;
+}
+
+int
+main (int argc, char **argv)
+{
+  use_it (-1);
+
+  tls_main_tbss_1 = 51;	/* main-breakpoint-1 */
+  tls_main_tbss_2 = 52;
+  tls_main_tdata_1 = 53;
+  tls_main_tdata_2 = 54;
+
+  tls_lib1_tbss_1 = 151;
+  tls_lib1_tbss_2 = 152;
+  tls_lib1_tdata_1 = 153;
+  tls_lib1_tdata_2 = 154;
+
+  tls_lib2_tbss_1 = 251;
+  tls_lib2_tbss_2 = 252;
+  tls_lib2_tdata_1 = 253;
+  tls_lib2_tdata_2 = 254;
+
+  tls_lib3_tbss_1 = 351;
+  tls_lib3_tbss_2 = 352;
+  tls_lib3_tdata_1 = 353;
+  tls_lib3_tdata_2 = 354;
+
+  lib1_func ();
+  lib2_func ();
+  lib3_func ();
+
+  /* Attempt to keep variables in the main program from being optimized
+     away.  */
+  use_it (tls_main_tbss_1);
+  use_it (tls_main_tbss_2);
+  use_it (tls_main_tdata_1);
+  use_it (tls_main_tdata_2);
+
+  use_it (100);		/* main-breakpoint-2 */
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/tls-multiobj.exp b/gdb/testsuite/gdb.base/tls-multiobj.exp
new file mode 100644
index 00000000000..a78db1460e9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/tls-multiobj.exp
@@ -0,0 +1,230 @@
+# Copyright 2024 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.
+
+# Using different compilation/linking scenarios, attempt to access
+# thread-local variables in a non-threaded program using multiple
+# shared objects.
+
+source $srcdir/$subdir/tls-common.exp.tcl
+
+standard_testfile
+
+set lib1src "${srcdir}/${subdir}/${testfile}1.c"
+set lib2src "${srcdir}/${subdir}/${testfile}2.c"
+set lib3src "${srcdir}/${subdir}/${testfile}3.c"
+
+set lib1obj [standard_output_file "${testfile}1-lib.so"]
+set lib2obj [standard_output_file "${testfile}2-lib.so"]
+set lib3obj [standard_output_file "${testfile}3-lib.so"]
+
+proc do_tests {force_internal_tls {do_kfail_tls_access 0}} {
+    clean_restart $::binfile
+    if ![runto_main] {
+	return
+    }
+
+    if $force_internal_tls {
+	gdb_test_no_output "maint set force-internal-tls-address-lookup on"
+    }
+
+    if { $do_kfail_tls_access && [istarget "*-*-linux*"] } {
+	# Turn off do_kfail_tls_access when libthread_db is loaded. 
+	# This can happen for the default case when testing x86_64
+	# w/ -m32 using glibc versions 2.34 or newer.
+	gdb_test_multiple "maint check libthread-db" "Check for loaded libthread_db" {
+	    -re -wrap "libthread_db integrity checks passed." {
+		set do_kfail_tls_access 0
+		pass $gdb_test_name
+	    }
+	    -re -wrap "No libthread_db loaded" {
+		pass $gdb_test_name
+	    }
+	}
+	# Also turn off do_kfail_tls_access when connected to a
+	# gdbserver and we observe that accessing a TLS variable
+	# works.
+	if [target_is_gdbserver] {
+	    gdb_test_multiple "print tls_main_tbss_1" \
+		"Check TLS accessibility when connected to a gdbserver" {
+		-re -wrap "= 0" {
+		    set do_kfail_tls_access 0
+		    pass $gdb_test_name
+		}
+		-re -wrap "Remote target failed to process qGetTLSAddr request" {
+		    pass $gdb_test_name
+		}
+	    }
+	}
+    }
+
+    gdb_breakpoint [gdb_get_line_number "main-breakpoint-1"]
+    gdb_continue_to_breakpoint "main-breakpoint-1"
+
+    set t $do_kfail_tls_access
+    set m "tls not available"
+    with_test_prefix "before assignments" {
+	gdb_test_with_kfail "print tls_main_tbss_1" ".* = 0" $t $m
+	gdb_test_with_kfail "print tls_main_tbss_2" ".* = 0" $t $m
+	gdb_test_with_kfail "print tls_main_tdata_1" ".* = 96" $t $m
+	gdb_test_with_kfail "print tls_main_tdata_2" ".* = 97" $t $m
+
+	gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 0" $t $m
+	gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 0" $t $m
+	gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 196" $t $m
+	gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 197" $t $m
+
+	gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 0" $t $m
+	gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 0" $t $m
+	gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 296" $t $m
+	gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 297" $t $m
+
+	gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 0" $t $m
+	gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 0" $t $m
+	gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 396" $t $m
+	gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 397" $t $m
+    }
+
+    gdb_breakpoint [gdb_get_line_number "main-breakpoint-2"]
+    gdb_continue_to_breakpoint "main-breakpoint-2"
+
+    with_test_prefix "after assignments" {
+	gdb_test_with_kfail "print tls_main_tbss_1" ".* = 51" $t $m
+	gdb_test_with_kfail "print tls_main_tbss_2" ".* = 52" $t $m
+	gdb_test_with_kfail "print tls_main_tdata_1" ".* = 53" $t $m
+	gdb_test_with_kfail "print tls_main_tdata_2" ".* = 54" $t $m
+
+	gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 151" $t $m
+	gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 152" $t $m
+	gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 153" $t $m
+	gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 154" $t $m
+
+	gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 251" $t $m
+	gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 252" $t $m
+	gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 253" $t $m
+	gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 254" $t $m
+
+	gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 351" $t $m
+	gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 352" $t $m
+	gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 353" $t $m
+	gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 354" $t $m
+    }
+
+    set corefile ${::binfile}.core
+    set core_supported 0
+    if { ![is_remote host] } {
+	set core_supported [gdb_gcore_cmd $corefile "save corefile"]
+    }
+
+    # Finish test early if no core file was made.
+    if !$core_supported {
+	return
+    }
+
+    clean_restart $::binfile
+
+    set core_loaded [gdb_core_cmd $corefile "load corefile"]
+    if { $core_loaded == -1 } {
+	return
+    }
+
+    with_test_prefix "core file" {
+	if $force_internal_tls {
+	    gdb_test_no_output "maint set force-internal-tls-address-lookup on"
+	}
+
+	gdb_test_with_kfail "print tls_main_tbss_1" ".* = 51" $t $m
+	gdb_test_with_kfail "print tls_main_tbss_2" ".* = 52" $t $m
+	gdb_test_with_kfail "print tls_main_tdata_1" ".* = 53" $t $m
+	gdb_test_with_kfail "print tls_main_tdata_2" ".* = 54" $t $m
+
+	gdb_test_with_kfail "print tls_lib1_tbss_1" ".* = 151" $t $m
+	gdb_test_with_kfail "print tls_lib1_tbss_2" ".* = 152" $t $m
+	gdb_test_with_kfail "print tls_lib1_tdata_1" ".* = 153" $t $m
+	gdb_test_with_kfail "print tls_lib1_tdata_2" ".* = 154" $t $m
+
+	gdb_test_with_kfail "print tls_lib2_tbss_1" ".* = 251" $t $m
+	gdb_test_with_kfail "print tls_lib2_tbss_2" ".* = 252" $t $m
+	gdb_test_with_kfail "print tls_lib2_tdata_1" ".* = 253" $t $m
+	gdb_test_with_kfail "print tls_lib2_tdata_2" ".* = 254" $t $m
+
+	gdb_test_with_kfail "print tls_lib3_tbss_1" ".* = 351" $t $m
+	gdb_test_with_kfail "print tls_lib3_tbss_2" ".* = 352" $t $m
+	gdb_test_with_kfail "print tls_lib3_tdata_1" ".* = 353" $t $m
+	gdb_test_with_kfail "print tls_lib3_tdata_2" ".* = 354" $t $m
+    }
+}
+
+if { [gdb_compile_shlib $lib1src $lib1obj {debug}] != "" } {
+    untested "failed to compile shared object"
+    return -1
+}
+if { [gdb_compile_shlib $lib2src $lib2obj {debug}] != "" } {
+    untested "failed to compile shared object"
+    return -1
+}
+if { [gdb_compile_shlib $lib3src $lib3obj {debug}] != "" } {
+    untested "failed to compile shared object"
+    return -1
+}
+
+# Certain linux target architectures implement support for internal
+# TLS lookup which is used when thread stratum support (via
+# libthread_db) is missing or when the linux-only GDB maintenance
+# setting 'force-internal-tls-address-lookup' is 'on'.  Thus for some
+# of the testing scenarios, such as statically linked executables,
+# this internal support will be used.  Set 'do_kfail_tls_access' to 1
+# for those architectures which don't implement internal tls support.
+if {[istarget *-*-linux*]
+    && ![is_any_target {*}$internal_tls_linux_targets]} {
+    set do_kfail_tls_access 1
+} elseif {[istarget *-*-linux*] && [is_x86_like_target]} {
+    # This covers the case of x86_64 with -m32:
+    set do_kfail_tls_access 1
+} else {
+    set do_kfail_tls_access 0
+}
+
+set binprefix $binfile
+
+with_test_prefix "default" {
+    set binfile $binprefix-default
+    if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
+                        [list debug shlib=${lib1obj} \
+			            shlib=${lib2obj} \
+				    shlib=${lib3obj}]] != "" } {
+	untested "failed to compile"
+    } else {
+	foreach_with_prefix force_internal_tls $internal_tls_iters {
+	    # Depending on glibc version, it might not be appropriate
+	    # for do_kfail_tls_access to be set here.  That will be
+	    # handled in 'do_tests', disabling it if necessary.
+	    # 
+	    # Specifically, glibc versions 2.34 and later have the
+	    # thread library (and libthread_db availability) in
+	    # programs not linked against libpthread.so
+	    do_tests $force_internal_tls $do_kfail_tls_access
+	}
+    }
+}
+
+with_test_prefix "pthreads" {
+    set binfile $binprefix-pthreads
+    if	{ [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
+				 [list debug shlib=${lib1obj} \
+					     shlib=${lib2obj} \
+					     shlib=${lib3obj}]] != "" } {
+	untested "failed to compile"
+    } else {
+	foreach_with_prefix force_internal_tls $internal_tls_iters {
+	    do_tests $force_internal_tls
+	}
+    }
+}
diff --git a/gdb/testsuite/gdb.base/tls-multiobj1.c b/gdb/testsuite/gdb.base/tls-multiobj1.c
new file mode 100644
index 00000000000..86e72228b1b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/tls-multiobj1.c
@@ -0,0 +1,26 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2024 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/>.  */
+
+__thread int tls_lib1_tbss_1;
+__thread int tls_lib1_tbss_2;
+__thread int tls_lib1_tdata_1 = 196;
+__thread int tls_lib1_tdata_2 = 197;
+
+void
+lib1_func ()
+{
+}
diff --git a/gdb/testsuite/gdb.base/tls-multiobj2.c b/gdb/testsuite/gdb.base/tls-multiobj2.c
new file mode 100644
index 00000000000..cea07092a5d
--- /dev/null
+++ b/gdb/testsuite/gdb.base/tls-multiobj2.c
@@ -0,0 +1,26 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2024 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/>.  */
+
+__thread int tls_lib2_tbss_1;
+__thread int tls_lib2_tbss_2;
+__thread int tls_lib2_tdata_1 = 296;
+__thread int tls_lib2_tdata_2 = 297;
+
+void
+lib2_func ()
+{
+}
diff --git a/gdb/testsuite/gdb.base/tls-multiobj3.c b/gdb/testsuite/gdb.base/tls-multiobj3.c
new file mode 100644
index 00000000000..bb0f2395fbf
--- /dev/null
+++ b/gdb/testsuite/gdb.base/tls-multiobj3.c
@@ -0,0 +1,26 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2024 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/>.  */
+
+__thread int tls_lib3_tbss_1;
+__thread int tls_lib3_tbss_2;
+__thread int tls_lib3_tdata_1 = 396;
+__thread int tls_lib3_tdata_2 = 397;
+
+void
+lib3_func ()
+{
+}
-- 
2.48.1


  parent reply	other threads:[~2025-04-04 23:46 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-04 23:37 [PATCH v6 00/11] GDB-internal TLS support for Linux targets Kevin Buettner
2025-04-04 23:37 ` [PATCH v6 01/11] Don't attempt to find TLS address when target has no registers Kevin Buettner
2025-04-04 23:37 ` [PATCH v6 02/11] Allow TLS access to work in gdb.server/no-thread-db.exp Kevin Buettner
2025-04-04 23:37 ` [PATCH v6 03/11] Track and fetch TLS module ids for MUSL and GLIBC Kevin Buettner
2025-04-04 23:37 ` [PATCH v6 04/11] Implement internal TLS address lookup for select Linux targets Kevin Buettner
2025-04-04 23:37 ` [PATCH v6 05/11] Internal TLS support for aarch64, x86_64, riscv, ppc64, and s390x Kevin Buettner
2025-04-04 23:37 ` [PATCH v6 06/11] Internal, but disabled, TLS support for i386 Kevin Buettner
2025-04-04 23:37 ` [PATCH v6 07/11] Delete disabled i386 internal TLS support Kevin Buettner
2025-04-04 23:37 ` [PATCH v6 08/11] New test - gdb.base/tls-nothreads.exp Kevin Buettner
2025-04-04 23:37 ` Kevin Buettner [this message]
2025-04-04 23:37 ` [PATCH v6 10/11] New test - gdb.base/tls-dlobj.exp Kevin Buettner
2025-04-04 23:37 ` [PATCH v6 11/11] Add TLS NEWS entry and document 'set force-internal-tls-address-lookup' command Kevin Buettner
2025-04-18 18:36 ` [PATCH v6 00/11] GDB-internal TLS support for Linux targets Kevin Buettner
2025-04-22 15:03   ` Tom Tromey
2025-04-23 14:12   ` Luis Machado
2025-04-23 22:14     ` Kevin Buettner
2025-04-24  6:34       ` Luis Machado

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250404234324.1931302-10-kevinb@redhat.com \
    --to=kevinb@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox