From patchwork Sun Aug 30 11:34:47 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philippe Waroquiers X-Patchwork-Id: 8517 Received: (qmail 46518 invoked by alias); 30 Aug 2015 11:34:40 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 46508 invoked by uid 89); 30 Aug 2015 11:34:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=2.3 required=5.0 tests=BAYES_50, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=no version=3.3.2 X-HELO: mailsec104.isp.belgacom.be Received: from mailsec104.isp.belgacom.be (HELO mailsec104.isp.belgacom.be) (195.238.20.100) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 30 Aug 2015 11:34:36 +0000 X-Cloudmark-SP-Filtered: true X-Cloudmark-SP-Result: v=1.1 cv=q+I5ZojRYpfsGgKWd5b26Nq+BLH/ghHCO5xA85WVj4Q= c=1 sm=2 a=CCpqsmhAAAAA:8 a=mDV3o1hIAAAA:8 a=_Bz_Y4wqKfV15SW0hPkA:9 a=QEXdDO2ut3YA:10 a=VfvIVw1b5tMA:10 a=6Z8l80WxKdMA:10 a=bJB8NWJSjaNoXaxG:21 a=3I3F7cgVpnhq4rQ7:21 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2A1CwAO6eJV/+vP81FegxsfNWmCVbtCgXiCQ4M0AoEnOxIBAQEBAQEBgQpBBYQHBC87HQImAjs3CYgpAQiaN49jlH8ZgQmFToY4AYMEgzmBQwWVBD2FB4dtgUqMZEOER4NGg2wmgg8ND4FWPDOBBoFHAQEB Received: from 235.207-243-81.adsl-dyn.isp.belgacom.be (HELO soleil) ([81.243.207.235]) by relay.skynet.be with ESMTP/TLS/AES128-SHA; 30 Aug 2015 13:34:33 +0200 Message-ID: <1440934487.22248.9.camel@skynet.be> Subject: [PATCH] PR varobj/18564 regression in showing __thread so extern variable From: Philippe Waroquiers To: gdb-patches@sourceware.org Date: Sun, 30 Aug 2015 13:34:47 +0200 Mime-Version: 1.0 X-IsSubscribed: yes Hello, The below patch fixes the regression https://sourceware.org/bugzilla/show_bug.cgi?id=18564 introduced in https://sourceware.org/ml/gdb-patches/2014-02/msg00811.html Due to the regression, __thread variables in a shared lib (such as errno) cannot be printed. Thanks to Mark Wielaard that bisect the regression origin, and thanks to Tom Tromey, that helped investigating (after the end of the warranty of the 2014 patch :). The regression is caused by relocating the TLS offset. The fix (using MSYMBOL_VALUE_RAW_ADDRESS) is similar to what has been done in https://sourceware.org/ml/gdb-patches/2015-08/msg00803.html ([Cell/B.E.] Fix wrong relocation for TLS variable offset). Tested on x86/Debian8. Ok to commit ? Thanks Philippe 2015-09-?? Philippe Waroquiers * symtab.h (address_class): Document that TLS variables are handled by LOC_UNRESOLVED. * findvar.c (default_read_var_value): Don't relocate TLS variables. * printcmd.c (address_info): Don't relocate TLS variables. 2015-09-?? Philippe Waroquiers * gdb.threads/tls-so_extern.exp: New test file. * gdb.threads/tls-so_extern.c: New test file. * gdb.threads/tls-so_extern_main.c: New test file. diff --git a/gdb/findvar.c b/gdb/findvar.c index 1c077f7..fd1b9d7 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -739,14 +739,17 @@ default_read_var_value (struct symbol *var, const struct block *var_block, if (msym == NULL) error (_("No global symbol \"%s\"."), SYMBOL_LINKAGE_NAME (var)); - if (overlay_debugging) - addr = symbol_overlayed_address (BMSYMBOL_VALUE_ADDRESS (lookup_data.result), - MSYMBOL_OBJ_SECTION (lookup_data.result.objfile, - msym)); - else - addr = BMSYMBOL_VALUE_ADDRESS (lookup_data.result); - obj_section = MSYMBOL_OBJ_SECTION (lookup_data.result.objfile, msym); + /* Relocate address, unless there is no section or the variable is + a TLS variable. */ + if (obj_section == NULL + || (obj_section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0) + addr = MSYMBOL_VALUE_RAW_ADDRESS (msym); + else + addr = BMSYMBOL_VALUE_ADDRESS (lookup_data.result); + if (overlay_debugging) + addr = symbol_overlayed_address (addr, obj_section); + /* Determine address of TLS variable. */ if (obj_section && (obj_section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0) addr = target_translate_tls_address (obj_section->objfile, addr); diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 5729b24..823f27b 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -1376,16 +1376,19 @@ address_info (char *exp, int from_tty) else { section = MSYMBOL_OBJ_SECTION (msym.objfile, msym.minsym); - load_addr = BMSYMBOL_VALUE_ADDRESS (msym); if (section && (section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0) - printf_filtered (_("a thread-local variable at offset %s " - "in the thread-local storage for `%s'"), - paddress (gdbarch, load_addr), - objfile_name (section->objfile)); + { + load_addr = MSYMBOL_VALUE_RAW_ADDRESS (msym.minsym); + printf_filtered (_("a thread-local variable at offset %s " + "in the thread-local storage for `%s'"), + paddress (gdbarch, load_addr), + objfile_name (section->objfile)); + } else { + load_addr = BMSYMBOL_VALUE_ADDRESS (msym); printf_filtered (_("static storage at address ")); fputs_filtered (paddress (gdbarch, load_addr), gdb_stdout); if (section_is_overlay (section)) diff --git a/gdb/symtab.h b/gdb/symtab.h index c6f26e7..d4a8e5f 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -584,7 +584,13 @@ enum address_class not find it in the full symbol table. But a reference to an external symbol in a local block shadowing other definition requires full symbol without possibly having its address available for LOC_STATIC. Testcase - is provided as `gdb.dwarf2/dw2-unresolved.exp'. */ + is provided as `gdb.dwarf2/dw2-unresolved.exp'. + + This is also used for thread local storage (TLS) variables. In this case, + the address of the TLS variable must be determined when the variable is + referenced, from the MSYMBOL_VALUE_RAW_ADDRESS, which is the offset + of the TLS variable in the thread local storage of the shared + library/object. */ LOC_UNRESOLVED, diff --git a/gdb/testsuite/gdb.threads/tls-so_extern.c b/gdb/testsuite/gdb.threads/tls-so_extern.c new file mode 100644 index 0000000..1559de2 --- /dev/null +++ b/gdb/testsuite/gdb.threads/tls-so_extern.c @@ -0,0 +1 @@ +__thread void *so_extern; diff --git a/gdb/testsuite/gdb.threads/tls-so_extern.exp b/gdb/testsuite/gdb.threads/tls-so_extern.exp new file mode 100644 index 0000000..c4acb21 --- /dev/null +++ b/gdb/testsuite/gdb.threads/tls-so_extern.exp @@ -0,0 +1,70 @@ +# Copyright 2015-2015 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-so_extern.exp -- Expect script to test thread local storage in gdb, with +# a variable defined in a shared library. + +standard_testfile tls-so_extern_main.c +set libfile tls-so_extern +set srcfile_lib ${libfile}.c +set binfile_lib [standard_output_file ${libfile}.so] + +remote_exec build "rm -f ${binfile}" + +# get the value of gcc_compiled +if [get_compiler_info] { + return -1 +} + + +if { [gdb_compile_shlib_pthreads ${srcdir}/${subdir}/${srcfile_lib} ${binfile_lib} {debug}] != "" + || [gdb_compile_pthreads ${srcdir}/${subdir}/${srcfile} ${binfile} executable [list debug shlib=${binfile_lib}]] != ""} { + return -1 +} + + +clean_restart ${binfile} +gdb_load_shlibs ${binfile_lib} + +if ![runto_main] then { + fail "Can't run to main" + return 0 +} + +gdb_test "print so_extern" "0x0" "print thread local storage variable" + +gdb_test "ptype so_extern" "void \\*" "ptype of thread local storage variable" + +gdb_test "info address so_extern" \ + "Symbol \\\"so_extern\\\" is a thread-local variable at offset 0x0 in the thread-local storage for .*tls-so_extern.*" \ + "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-so_extern_main.c.*line ${line_number}." \ + "break in thread function" +gdb_test "continue" \ + "tls_ptr .* at .*:.*printf.*break here to check result.*" \ + "continue to break in a thread" +gdb_test "print so_extern == &so_extern" \ + " = 1" \ + "check so_extern address" +gdb_test "continue" \ + "tls_ptr .* at .*:.*printf.*break here to check result.*" \ + "continue to break in the other thread" +gdb_test "print so_extern == &so_extern" \ + " = 1" \ + "check so_extern address in other thread" diff --git a/gdb/testsuite/gdb.threads/tls-so_extern_main.c b/gdb/testsuite/gdb.threads/tls-so_extern_main.c new file mode 100644 index 0000000..5531fda --- /dev/null +++ b/gdb/testsuite/gdb.threads/tls-so_extern_main.c @@ -0,0 +1,21 @@ +#include +#include + +extern __thread void *so_extern; + +static void *tls_ptr(void *p) +{ + so_extern = &so_extern; + printf("address is %p\n", &so_extern); /* break here to check result */ +} + +int main() +{ + pthread_t threads[2]; + pthread_create (&threads[0], NULL, tls_ptr, NULL); + pthread_create (&threads[1], NULL, tls_ptr, NULL); + + pthread_join(threads[0], NULL); + pthread_join(threads[1], NULL); +} +