--- Begin Message ---
- From: Vinay Sridhar <vinay at linux dot vnet dot ibm dot com>
- To: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- Cc: gdb-patches at sources dot redhat dot com, Daniel Jacobowitz <drow at false dot org>, luisgpm at linux dot vnet dot ibm dot com, uweigand at de dot ibm dot com
- Date: Wed, 27 Aug 2008 10:07:38 +0530
- Subject: Re: [patch] Re: Accessing tls variables across files causes a bug
- References: <1217480020.4755.1.camel@vinaysridhar.in.ibm.com> <20080802171807.GA2755@host0.dyn.jankratochvil.net> <1217925527.3658.41.camel@vinaysridhar.in.ibm.com> <20080805122118.GB17219@caradoc.them.org> <1218021410.13466.4.camel@vinaysridhar.in.ibm.com> <20080806114241.GA18923@host0.dyn.jankratochvil.net> <20080806151933.GA32530@host0.dyn.jankratochvil.net>
When can we expect these patches to go in?
Thanks,
Vinay
On Wed, 2008-08-06 at 17:19 +0200, Jan Kratochvil wrote:
> On Wed, 06 Aug 2008 13:42:41 +0200, Jan Kratochvil wrote:
> > Another possibility is that LOC_UNRESOLVED may no longer be needed for recent
> > gcc debuginfos always(?) containting `DW_AT_location's, therefore we would not
> > have to deal with `minimal_symbol's in this case at all.
>
> Attached.
>
> It has no regressions on x86_64, Fedora gcc-4.3.1-6.x86_64 (but gcc-4.3 has
> GDB regressions against gcc-4.1). Also tried there are no regressions by
> check//unix/-gstabs+ (although the three new TLS testcases FAIL there).
>
> I do not fully grok why psymtabs were created for DW_AT_type DIEs with no
> DW_AT_location. IMO (DW_AT_location || DW_AT_const_value) is the right
> condition (DW_AT_const_value requirement was found by a testsuite run).
>
>
> Regards,
> Jan
> plain text document attachment (gdb-remove-LOC_UNRESOLVED.patch)
> 2008-08-06 Jan Kratochvil <jan.kratochvil@redhat.com>
>
> Fix resolving external references to TLS variables.
> * ada-lang.c (ada_add_block_symbols): Remove LOC_UNRESOLVED.
> * ax-gdb.c (gen_var_ref): Likewise.
> * gen_var_ref (symbol_read_needs_frame, read_var_value): Likewise.
> * m2-exp.y (yylex): Likewise.
> * printcmd.c (address_info): Likewise.
> * symmisc.c (print_symbol, print_partial_symbols): Likewise.
> * symtab.h (enum address_class): Likewise.
> * tracepoint.c (collect_symbol, scope_info): Likewise.
> * mi/mi-cmd-stack.c (list_args_or_locals): Likewise.
> * stabsread.c (scan_file_globals): Complain even on LOC_STATIC symbols.
> Set such symbols to LOC_UNDEF instead of LOC_UNRESOLVED.
> * dwarf2read.c (struct partial_die_info): Remove the field HAS_TYPE.
> New field HAS_CONST_VALUE.
> (add_partial_symbol) <DW_TAG_variable>: HAS_TYPE condition removed.
> HAS_CONST_VALUE condition added. Comment updated.
> (read_partial_die) <DW_AT_type>: Case removed.
> (read_partial_die) <DW_AT_const_value>: New case.
> (new_symbol): Remove setting LOC_UNRESOLVED. Comment updated.
>
> 2008-08-06 Jan Kratochvil <jan.kratochvil@redhat.com>
>
> Update for removed LOC_UNRESOLVED, test resolving external references
> to TLS variables.
> * gdb.dwarf2/dw2-noloc.S: New variable "optloc".
> * gdb.dwarf2/dw2-noloc.exp: Test the new variable "optloc". Update the
> current message for the variable "noloc".
> * gdb.threads/tls.exp: New tests to print A_THREAD_LOCAL and
> FILE2_THREAD_LOCAL.
> (testfile2, srcfile2): New variables.
> * gdb.threads/tls.c (file2_thread_local)
> (function_referencing_file2_thread_local): New.
> * gdb.threads/tls2.c: New file.
>
> --- gdb/ada-lang.c 21 Jul 2008 16:47:10 -0000 1.151
> +++ gdb/ada-lang.c 6 Aug 2008 15:13:51 -0000
> @@ -5211,9 +5211,7 @@ ada_add_block_symbols (struct obstack *o
> SYMBOL_DOMAIN (sym), domain)
> && wild_match (name, name_len, SYMBOL_LINKAGE_NAME (sym)))
> {
> - if (SYMBOL_CLASS (sym) == LOC_UNRESOLVED)
> - continue;
> - else if (SYMBOL_IS_ARGUMENT (sym))
> + if (SYMBOL_IS_ARGUMENT (sym))
> arg_sym = sym;
> else
> {
> @@ -5236,17 +5234,14 @@ ada_add_block_symbols (struct obstack *o
> if (cmp == 0
> && is_name_suffix (SYMBOL_LINKAGE_NAME (sym) + name_len))
> {
> - if (SYMBOL_CLASS (sym) != LOC_UNRESOLVED)
> + if (SYMBOL_IS_ARGUMENT (sym))
> + arg_sym = sym;
> + else
> {
> - if (SYMBOL_IS_ARGUMENT (sym))
> - arg_sym = sym;
> - else
> - {
> - found_sym = 1;
> - add_defn_to_vec (obstackp,
> - fixup_symbol_section (sym, objfile),
> - block);
> - }
> + found_sym = 1;
> + add_defn_to_vec (obstackp,
> + fixup_symbol_section (sym, objfile),
> + block);
> }
> }
> }
> @@ -5284,17 +5279,14 @@ ada_add_block_symbols (struct obstack *o
> if (cmp == 0
> && is_name_suffix (SYMBOL_LINKAGE_NAME (sym) + name_len + 5))
> {
> - if (SYMBOL_CLASS (sym) != LOC_UNRESOLVED)
> + if (SYMBOL_IS_ARGUMENT (sym))
> + arg_sym = sym;
> + else
> {
> - if (SYMBOL_IS_ARGUMENT (sym))
> - arg_sym = sym;
> - else
> - {
> - found_sym = 1;
> - add_defn_to_vec (obstackp,
> - fixup_symbol_section (sym, objfile),
> - block);
> - }
> + found_sym = 1;
> + add_defn_to_vec (obstackp,
> + fixup_symbol_section (sym, objfile),
> + block);
> }
> }
> }
> --- gdb/ax-gdb.c 27 May 2008 19:29:51 -0000 1.44
> +++ gdb/ax-gdb.c 6 Aug 2008 15:13:53 -0000
> @@ -596,19 +596,6 @@ gen_var_ref (struct agent_expr *ax, stru
> value->kind = axs_lvalue_memory;
> break;
>
> - case LOC_UNRESOLVED:
> - {
> - struct minimal_symbol *msym
> - = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (var), NULL, NULL);
> - if (!msym)
> - error (_("Couldn't resolve symbol `%s'."), SYMBOL_PRINT_NAME (var));
> -
> - /* Push the address of the variable. */
> - ax_const_l (ax, SYMBOL_VALUE_ADDRESS (msym));
> - value->kind = axs_lvalue_memory;
> - }
> - break;
> -
> case LOC_COMPUTED:
> /* FIXME: cagney/2004-01-26: It should be possible to
> unconditionally call the SYMBOL_OPS method when available.
> --- gdb/dwarf2read.c 27 Jun 2008 17:56:47 -0000 1.267
> +++ gdb/dwarf2read.c 6 Aug 2008 15:14:01 -0000
> @@ -462,7 +462,7 @@ struct partial_die_info
> unsigned int has_children : 1;
> unsigned int is_external : 1;
> unsigned int is_declaration : 1;
> - unsigned int has_type : 1;
> + unsigned int has_const_value : 1;
> unsigned int has_specification : 1;
> unsigned int has_stmt_list : 1;
> unsigned int has_pc_info : 1;
> @@ -1988,18 +1988,17 @@ add_partial_symbol (struct partial_die_i
> Don't enter into the minimal symbol tables as there is
> a minimal symbol table entry from the ELF symbols already.
> Enter into partial symbol table if it has a location
> - descriptor or a type.
> - If the location descriptor is missing, new_symbol will create
> - a LOC_UNRESOLVED symbol, the address of the variable will then
> - be determined from the minimal symbol table whenever the variable
> - is referenced.
> + descriptor. It may have a type but still if it has neither
> + location descriptor nor it is a constant value it must be just an
> + `extern' declaration we are not interested in. Optimized out
> + variables will have a 0-length location descriptor.
> The address for the partial symbol table entry is not
> used by GDB, but it comes in handy for debugging partial symbol
> table building. */
>
> if (pdi->locdesc)
> addr = decode_locdesc (pdi->locdesc, cu);
> - if (pdi->locdesc || pdi->has_type)
> + if (pdi->locdesc || pdi->has_const_value)
> psym = add_psymbol_to_list (actual_name, strlen (actual_name),
> VAR_DOMAIN, LOC_STATIC,
> &objfile->global_psymbols,
> @@ -5837,8 +5836,8 @@ read_partial_die (struct partial_die_inf
> case DW_AT_declaration:
> part_die->is_declaration = DW_UNSND (&attr);
> break;
> - case DW_AT_type:
> - part_die->has_type = 1;
> + case DW_AT_const_value:
> + part_die->has_const_value = 1;
> break;
> case DW_AT_abstract_origin:
> case DW_AT_specification:
> @@ -7486,19 +7485,15 @@ new_symbol (struct die_info *die, struct
> }
> else
> {
> - /* We do not know the address of this symbol.
> - If it is an external symbol and we have type information
> - for it, enter the symbol as a LOC_UNRESOLVED symbol.
> - The address of the variable will then be determined from
> - the minimal symbol table whenever the variable is
> - referenced. */
> - attr2 = dwarf2_attr (die, DW_AT_external, cu);
> - if (attr2 && (DW_UNSND (attr2) != 0)
> - && dwarf2_attr (die, DW_AT_type, cu) != NULL)
> - {
> - SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
> - add_symbol_to_list (sym, &global_symbols);
> - }
> + /* We do not know the address of this symbol. If it is an
> + external symbol and we have type information
> + for it, we could enter the symbol as a LOC_UNRESOLVED symbol.
> + The address of the variable could then be determined from the
> + minimal symbol table whenever the variable is referenced.
> + Just it needs an exception in the code whenever we get
> + LOC_UNRESOLVED and some places miss it, fortunately recent GCC
> + puts DW_AT_location everywhere so this workaround is no longer
> + needed. */
> }
> break;
> case DW_TAG_formal_parameter:
> --- gdb/findvar.c 15 Jul 2008 17:53:11 -0000 1.115
> +++ gdb/findvar.c 6 Aug 2008 15:14:02 -0000
> @@ -371,7 +371,6 @@ symbol_read_needs_frame (struct symbol *
>
> case LOC_BLOCK:
> case LOC_CONST_BYTES:
> - case LOC_UNRESOLVED:
> case LOC_OPTIMIZED_OUT:
> return 0;
> }
> @@ -533,21 +532,6 @@ read_var_value (struct symbol *var, stru
> return 0;
> return SYMBOL_OPS (var)->read_variable (var, frame);
>
> - case LOC_UNRESOLVED:
> - {
> - struct minimal_symbol *msym;
> -
> - msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (var), NULL, NULL);
> - if (msym == NULL)
> - return 0;
> - if (overlay_debugging)
> - addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (msym),
> - SYMBOL_BFD_SECTION (msym));
> - else
> - addr = SYMBOL_VALUE_ADDRESS (msym);
> - }
> - break;
> -
> case LOC_OPTIMIZED_OUT:
> VALUE_LVAL (v) = not_lval;
> set_value_optimized_out (v, 1);
> --- gdb/m2-exp.y 27 May 2008 19:29:51 -0000 1.21
> +++ gdb/m2-exp.y 6 Aug 2008 15:14:02 -0000
> @@ -1059,7 +1059,6 @@ yylex ()
> error("internal: Undefined class in m2lex()");
>
> case LOC_LABEL:
> - case LOC_UNRESOLVED:
> error("internal: Unforseen case in m2lex()");
>
> default:
> --- gdb/printcmd.c 6 Jun 2008 20:58:08 -0000 1.127
> +++ gdb/printcmd.c 6 Aug 2008 15:14:05 -0000
> @@ -1169,30 +1169,6 @@ address_info (char *exp, int from_tty)
> }
> break;
>
> - case LOC_UNRESOLVED:
> - {
> - struct minimal_symbol *msym;
> -
> - msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym), NULL, NULL);
> - if (msym == NULL)
> - printf_filtered ("unresolved");
> - else
> - {
> - section = SYMBOL_BFD_SECTION (msym);
> - printf_filtered (_("static storage at address "));
> - load_addr = SYMBOL_VALUE_ADDRESS (msym);
> - fputs_filtered (paddress (load_addr), gdb_stdout);
> - if (section_is_overlay (section))
> - {
> - load_addr = overlay_unmapped_address (load_addr, section);
> - printf_filtered (_(",\n -- loaded at "));
> - fputs_filtered (paddress (load_addr), gdb_stdout);
> - printf_filtered (_(" in overlay section %s"), section->name);
> - }
> - }
> - }
> - break;
> -
> case LOC_OPTIMIZED_OUT:
> printf_filtered (_("optimized out"));
> break;
> --- gdb/stabsread.c 27 May 2008 19:29:51 -0000 1.108
> +++ gdb/stabsread.c 6 Aug 2008 15:14:08 -0000
> @@ -4501,7 +4501,7 @@ scan_file_globals (struct objfile *objfi
> }
>
> /* Change the storage class of any remaining unresolved globals to
> - LOC_UNRESOLVED and remove them from the chain. */
> + LOC_UNDEF and remove them from the chain. */
> for (hash = 0; hash < HASHSIZE; hash++)
> {
> sym = global_sym_chain[hash];
> @@ -4514,13 +4514,11 @@ scan_file_globals (struct objfile *objfi
> to address zero. */
> SYMBOL_VALUE_ADDRESS (prev) = 0;
>
> + SYMBOL_CLASS (prev) = LOC_UNDEF;
> /* Complain about unresolved common block symbols. */
> - if (SYMBOL_CLASS (prev) == LOC_STATIC)
> - SYMBOL_CLASS (prev) = LOC_UNRESOLVED;
> - else
> - complaint (&symfile_complaints,
> - _("%s: common block `%s' from global_sym_chain unresolved"),
> - objfile->name, DEPRECATED_SYMBOL_NAME (prev));
> + complaint (&symfile_complaints,
> + _("%s: common block `%s' from global_sym_chain unresolved"),
> + objfile->name, DEPRECATED_SYMBOL_NAME (prev));
> }
> }
> memset (global_sym_chain, 0, sizeof (global_sym_chain));
> --- gdb/symmisc.c 27 May 2008 19:29:51 -0000 1.53
> +++ gdb/symmisc.c 6 Aug 2008 15:14:09 -0000
> @@ -701,10 +701,6 @@ print_symbol (void *args)
> fprintf_filtered (outfile, "computed at runtime");
> break;
>
> - case LOC_UNRESOLVED:
> - fprintf_filtered (outfile, "unresolved");
> - break;
> -
> case LOC_OPTIMIZED_OUT:
> fprintf_filtered (outfile, "optimized out");
> break;
> @@ -837,9 +833,6 @@ print_partial_symbols (struct partial_sy
> case LOC_CONST_BYTES:
> fputs_filtered ("constant bytes", outfile);
> break;
> - case LOC_UNRESOLVED:
> - fputs_filtered ("unresolved", outfile);
> - break;
> case LOC_OPTIMIZED_OUT:
> fputs_filtered ("optimized out", outfile);
> break;
> --- gdb/symtab.h 27 May 2008 19:29:51 -0000 1.128
> +++ gdb/symtab.h 6 Aug 2008 15:14:12 -0000
> @@ -476,18 +476,6 @@ enum address_class
>
> LOC_CONST_BYTES,
>
> - /* Value is at fixed address, but the address of the variable has
> - to be determined from the minimal symbol table whenever the
> - variable is referenced.
> - This happens if debugging information for a global symbol is
> - emitted and the corresponding minimal symbol is defined
> - in another object file or runtime common storage.
> - The linker might even remove the minimal symbol if the global
> - symbol is never referenced, in which case the symbol remains
> - unresolved. */
> -
> - LOC_UNRESOLVED,
> -
> /* The variable does not actually exist in the program.
> The value is ignored. */
>
> --- gdb/tracepoint.c 25 Jul 2008 16:12:03 -0000 1.107
> +++ gdb/tracepoint.c 6 Aug 2008 15:14:14 -0000
> @@ -1289,10 +1289,6 @@ collect_symbol (struct collection_list *
> }
> add_memrange (collect, reg, offset, len);
> break;
> - case LOC_UNRESOLVED:
> - printf_filtered ("Don't know LOC_UNRESOLVED %s\n",
> - DEPRECATED_SYMBOL_NAME (sym));
> - break;
> case LOC_OPTIMIZED_OUT:
> printf_filtered ("%s has been optimized out of existence.\n",
> DEPRECATED_SYMBOL_NAME (sym));
> @@ -2457,17 +2453,6 @@ scope_info (char *args, int from_tty)
> printf_filtered ("a function at address ");
> printf_filtered ("%s", paddress (BLOCK_START (SYMBOL_BLOCK_VALUE (sym))));
> break;
> - case LOC_UNRESOLVED:
> - msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (sym),
> - NULL, NULL);
> - if (msym == NULL)
> - printf_filtered ("Unresolved Static");
> - else
> - {
> - printf_filtered ("static storage at address ");
> - printf_filtered ("%s", paddress (SYMBOL_VALUE_ADDRESS (msym)));
> - }
> - break;
> case LOC_OPTIMIZED_OUT:
> printf_filtered ("optimized out.\n");
> continue;
> --- gdb/mi/mi-cmd-stack.c 25 Jun 2008 15:15:42 -0000 1.41
> +++ gdb/mi/mi-cmd-stack.c 6 Aug 2008 15:14:15 -0000
> @@ -238,7 +238,6 @@ list_args_or_locals (int locals, int val
> case LOC_LABEL: /* local label */
> case LOC_BLOCK: /* local function */
> case LOC_CONST_BYTES: /* loc. byte seq. */
> - case LOC_UNRESOLVED: /* unresolved static */
> case LOC_OPTIMIZED_OUT: /* optimized out */
> print_me = 0;
> break;
> --- gdb/testsuite/gdb.dwarf2/dw2-noloc.S 1 Jan 2008 22:53:19 -0000 1.3
> +++ gdb/testsuite/gdb.dwarf2/dw2-noloc.S 6 Aug 2008 15:14:15 -0000
> @@ -69,6 +69,12 @@ func_cu1:
> .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */
> .byte 1 /* DW_AT_external */
>
> + .uleb128 5 /* Abbrev: DW_TAG_variable */
> + .ascii "optloc\0" /* DW_AT_name */
> + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */
> + .byte 1 /* DW_AT_external */
> + .byte 0 /* DW_AT_location: length */
> +
> .byte 0 /* End of children of CU */
>
> .Lcu1_end:
> @@ -140,6 +146,20 @@ func_cu1:
> .byte 0x0 /* Terminator */
> .byte 0x0 /* Terminator */
>
> + .uleb128 5 /* Abbrev code */
> + .uleb128 0x34 /* DW_TAG_variable */
> + .byte 0 /* has_children */
> + .uleb128 0x3 /* DW_AT_name */
> + .uleb128 0x8 /* DW_FORM_string */
> + .uleb128 0x49 /* DW_AT_type */
> + .uleb128 0x13 /* DW_FORM_ref4 */
> + .uleb128 0x3f /* DW_AT_external */
> + .uleb128 0xc /* DW_FORM_flag */
> + .uleb128 0x2 /* DW_AT_location */
> + .uleb128 0xa /* DW_FORM_block1 */
> + .byte 0x0 /* Terminator */
> + .byte 0x0 /* Terminator */
> +
> .byte 0x0 /* Terminator */
> .byte 0x0 /* Terminator */
>
> --- gdb/testsuite/gdb.dwarf2/dw2-noloc.exp 1 Jan 2008 22:53:19 -0000 1.3
> +++ gdb/testsuite/gdb.dwarf2/dw2-noloc.exp 6 Aug 2008 15:14:15 -0000
> @@ -45,4 +45,5 @@ gdb_start
> gdb_reinitialize_dir $srcdir/$subdir
> gdb_load ${binfile}
>
> -gdb_test "print noloc" "Address of symbol \"noloc\" is unknown." "print noloc"
> +gdb_test "print noloc" "No symbol \"noloc\" in current context." "print noloc"
> +gdb_test "print optloc" " = <value optimized out>" "print optloc"
> --- gdb/testsuite/gdb.threads/tls.c 29 Jul 2003 21:51:25 -0000 1.2
> +++ gdb/testsuite/gdb.threads/tls.c 6 Aug 2008 15:14:17 -0000
> @@ -20,6 +20,9 @@
> __thread int a_thread_local;
> __thread int another_thread_local;
>
> +/* psymtabs->symtabs resolving check. */
> +extern __thread int file2_thread_local;
> +
> /* Global variable just for info addr in gdb. */
> int a_global;
>
> @@ -119,6 +122,12 @@ void *spin( vp )
> }
>
> void
> +function_referencing_file2_thread_local (void)
> +{
> + file2_thread_local = file2_thread_local;
> +}
> +
> +void
> do_pass()
> {
> int i;
> --- gdb/testsuite/gdb.threads/tls.exp 6 Aug 2008 12:52:08 -0000 1.9
> +++ gdb/testsuite/gdb.threads/tls.exp 6 Aug 2008 15:14:17 -0000
> @@ -15,7 +15,9 @@
> # along with this program. If not, see <http://www.gnu.org/licenses/>. */
>
> set testfile tls
> +set testfile2 tls2
> set srcfile ${testfile}.c
> +set srcfile2 ${testfile2}.c
> set binfile ${objdir}/${subdir}/${testfile}
>
> if [istarget "*-*-linux"] then {
> @@ -24,7 +26,7 @@ if [istarget "*-*-linux"] then {
> set target_cflags ""
> }
>
> -if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
> +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile} ${srcdir}/${subdir}/${srcfile2}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
> return -1
> }
>
> @@ -284,6 +286,15 @@ gdb_test "info address a_global" \
> setup_kfail "gdb/1294" "*-*-*"
> gdb_test "info address me" ".*me.*is a variable at offset.*" "info address me"
>
> +
> +# Test LOC_UNRESOLVED references for the `extern' variables.
> +
> +gdb_test "p a_thread_local" " = \[0-9\]+"
> +# Here it could crash with: Cannot access memory at address 0x0
> +gdb_test "p file2_thread_local" " = \[0-9\]+"
> +# Here it could crash with: Cannot access memory at address 0x0
> +gdb_test "p a_thread_local" " = \[0-9\]+"
> +
> # Done!
> #
> gdb_exit
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ gdb/testsuite/gdb.threads/tls2.c 6 Aug 2008 15:14:17 -0000
> @@ -0,0 +1,28 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2008 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/>.
> +
> + Please email any bugs, comments, and/or additions to this file to:
> + bug-gdb@prep.ai.mit.edu */
> +
> +extern __thread int a_thread_local;
> +__thread int file2_thread_local;
> +
> +void
> +function_referencing_a_thread_local (void)
> +{
> + a_thread_local = a_thread_local;
> +}
--- End Message ---