Fix PR/18564 - regression in showing __thread so extern variable

Ensure tls variable address is not relocated, as the msym addr
is an offset in the thread local storage of the shared library/object.
This commit is contained in:
Philippe Waroquiers 2015-09-15 21:02:15 +02:00
parent e68fa6f076
commit 5382cfab61
8 changed files with 185 additions and 13 deletions

View File

@ -1,3 +1,10 @@
2015-09-15 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* 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-15 Pierre Langlois <pierre.langlois@arm.com>
* aarch64-tdep.c (decode_add_sub_imm): Use debug_printf.

View File

@ -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);

View File

@ -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))

View File

@ -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,

View File

@ -1,3 +1,9 @@
2015-09-15 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* 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.
2015-09-15 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.opt/solib-intra-step-lib.c: New file.

View File

@ -0,0 +1,19 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 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 <http://www.gnu.org/licenses/>. */
__thread void *so_extern;
__thread void *so_extern2;

View File

@ -0,0 +1,81 @@
# Copyright 2003-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 <http://www.gnu.org/licenses/>. */
# 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]
# 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 .*:.*break here to check result.*" \
"continue to break in tls_ptr called by main"
gdb_test "print so_extern == &so_extern" \
" = 1" \
"check so_extern address in main"
gdb_test "continue" \
"tls_ptr .* at .*:.*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 .*:.*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"
gdb_test "continue" \
"tls_ptr .* at .*:.*break here to check result.*" \
"continue to break in tls_ptr called at end of main"
gdb_test "print so_extern == &so_extern" \
" = 1" \
"check so_extern address at end of main"

View File

@ -0,0 +1,47 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 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 <http://www.gnu.org/licenses/>. */
#include <pthread.h>
extern __thread void *so_extern;
extern __thread void *so_extern2;
static void *
tls_ptr (void *p)
{
so_extern = &so_extern;
so_extern2 = &so_extern2; /* break here to check result */
}
int
main (void)
{
pthread_t threads[2];
tls_ptr (NULL);
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);
tls_ptr (NULL);
return 0;
}