From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29725 invoked by alias); 21 Jan 2007 16:55:02 -0000 Received: (qmail 29661 invoked by uid 22791); 21 Jan 2007 16:55:00 -0000 X-Spam-Check-By: sourceware.org Received: from nevyn.them.org (HELO nevyn.them.org) (66.93.172.17) by sourceware.org (qpsmtpd/0.31.1) with ESMTP; Sun, 21 Jan 2007 16:54:54 +0000 Received: from drow by nevyn.them.org with local (Exim 4.63) (envelope-from ) id 1H8fxz-0003GN-Mt; Sun, 21 Jan 2007 11:54:51 -0500 Date: Sun, 21 Jan 2007 16:55:00 -0000 From: Daniel Jacobowitz To: Jan Kratochvil Cc: gdb-patches@sourceware.org Subject: Re: [PATCH] Follow specific symbol's DW_AT_decl_file Message-ID: <20070121165451.GA12463@nevyn.them.org> Mail-Followup-To: Jan Kratochvil , gdb-patches@sourceware.org References: <20070111223940.GA8958@host0.dyn.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20070111223940.GA8958@host0.dyn.jankratochvil.net> User-Agent: Mutt/1.5.13 (2006-08-11) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-01/txt/msg00434.txt.bz2 On Thu, Jan 11, 2007 at 11:39:41PM +0100, Jan Kratochvil wrote: > Hi, > > Debby Townsend : > ------------------------------------------------------------------------------ > Both the "info variable" and the "list" command, when given the name > of an external variable which is defined in an #include'd file, list > the incorrect file-name. In the case of "list" the line number is > extrapolated correctly; but the wrong source file is listed. > > The problem does not occur for functions defined in the same > #include'd file. > ------------------------------------------------------------------------------ > > > The regression-smelling parts of the patch are about the file located in > various directories, currently the patch fills in `symtab->dirname' from the > main file of CU (Compilation Unit) - the non-primary filenames were not (much > or at all?) used so far. They were used for line numbers within functions - list.exp is a similar test. I think what you've got is fine. I ended up rewriting the patch, based on your version. Originally, I was worried about adding another pointer to "struct symbol"; the comment at top of the structure is: /* This structure is space critical. See space comments at the top. */ So I wrote an implementation that used an on-the-side hash table. But in the end, it was a bit slower, and most symbols needed one. Even with -readnow the memory increase was only 3%, so it will be less than that in practice. So I went back to doing it in the symbol after all :-) The other changes I made were to move the index handling into dwarf2read.c, since the concept of a file index is dwarf specific, and to move the test into gdb.base, since in theory other debug formats could get it right. I tested this on x86_64-pc-linux-gnu and committed it. -- Daniel Jacobowitz CodeSourcery 2007-01-21 Jan Kratochvil Daniel Jacobowitz * buildsym.c (end_symtab): Use preallocated symtab if available. Fill in SYMBOL_SYMTAB. * buildsym.h (struct subfile): Add symtab member. * dwarf2read.c (struct dwarf2_cu): Add line_header. (struct file_entry): Add symtab. (free_cu_line_header): New function. (read_file_scope): Use it. Save line_header in the cu. Process lines before DIEs. (add_file_name): Initialize new symtab member. (dwarf_decode_lines): Create symtabs for included files. (new_symbol): Set SYMBOL_SYMTAB. * symtab.c (lookup_symbol): Use SYMBOL_SYMTAB. (search_symbols): Likewise. * symtab.h (struct symbol): Add symtab member. (SYMBOL_SYMTAB): Define. 2007-01-21 Jan Kratochvil Daniel Jacobowitz * gdb.base/included.c, gdb.base/included.exp, gdb.base/included.h: New files. Index: buildsym.c =================================================================== RCS file: /cvs/src/src/gdb/buildsym.c,v retrieving revision 1.45 diff -u -p -r1.45 buildsym.c --- buildsym.c 9 Jan 2007 17:58:50 -0000 1.45 +++ buildsym.c 21 Jan 2007 16:42:09 -0000 @@ -959,7 +959,10 @@ end_symtab (CORE_ADDR end_addr, struct o } /* Now, allocate a symbol table. */ - symtab = allocate_symtab (subfile->name, objfile); + if (subfile->symtab == NULL) + symtab = allocate_symtab (subfile->name, objfile); + else + symtab = subfile->symtab; /* Fill in its components. */ symtab->blockvector = blockvector; @@ -1048,6 +1051,26 @@ end_symtab (CORE_ADDR end_addr, struct o symtab->primary = 1; } + /* Default any symbols without a specified symtab to the primary + symtab. */ + if (blockvector) + { + int block_i; + + for (block_i = 0; block_i < BLOCKVECTOR_NBLOCKS (blockvector); block_i++) + { + struct block *block = BLOCKVECTOR_BLOCK (blockvector, block_i); + struct symbol *sym; + struct dict_iterator iter; + + for (sym = dict_iterator_first (BLOCK_DICT (block), &iter); + sym != NULL; + sym = dict_iterator_next (&iter)) + if (SYMBOL_SYMTAB (sym) == NULL) + SYMBOL_SYMTAB (sym) = symtab; + } + } + last_source_file = NULL; current_subfile = NULL; pending_macros = NULL; Index: buildsym.h =================================================================== RCS file: /cvs/src/src/gdb/buildsym.h,v retrieving revision 1.15 diff -u -p -r1.15 buildsym.h --- buildsym.h 9 Jan 2007 17:58:50 -0000 1.15 +++ buildsym.h 21 Jan 2007 16:42:09 -0000 @@ -70,6 +70,7 @@ struct subfile enum language language; char *producer; char *debugformat; + struct symtab *symtab; }; EXTERN struct subfile *subfiles; Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.211 diff -u -p -r1.211 dwarf2read.c --- dwarf2read.c 9 Jan 2007 17:58:50 -0000 1.211 +++ dwarf2read.c 21 Jan 2007 16:42:10 -0000 @@ -341,6 +341,9 @@ struct dwarf2_cu partial symbol tables do not have dependencies. */ htab_t dependencies; + /* Header data from the line table, during full symbol processing. */ + struct line_header *line_header; + /* Mark used when releasing cached dies. */ unsigned int mark : 1; @@ -432,6 +435,7 @@ struct line_header unsigned int mod_time; unsigned int length; int included_p; /* Non-zero if referenced by the Line Number Program. */ + struct symtab *symtab; /* The associated symbol table, if any. */ } *file_names; /* The start and end of the statement program following this @@ -2754,6 +2758,15 @@ initialize_cu_func_list (struct dwarf2_c } static void +free_cu_line_header (void *arg) +{ + struct dwarf2_cu *cu = arg; + + free_line_header (cu->line_header); + cu->line_header = NULL; +} + +static void read_file_scope (struct die_info *die, struct dwarf2_cu *cu) { struct objfile *objfile = cu->objfile; @@ -2823,18 +2836,9 @@ read_file_scope (struct die_info *die, s initialize_cu_func_list (cu); - /* Process all dies in compilation unit. */ - if (die->child != NULL) - { - child_die = die->child; - while (child_die && child_die->tag) - { - process_die (child_die, cu); - child_die = sibling_die (child_die); - } - } - - /* Decode line number information if present. */ + /* Decode line number information if present. We do this before + processing child DIEs, so that the line header table is available + for DW_AT_decl_file. */ attr = dwarf2_attr (die, DW_AT_stmt_list, cu); if (attr) { @@ -2842,12 +2846,23 @@ read_file_scope (struct die_info *die, s line_header = dwarf_decode_line_header (line_offset, abfd, cu); if (line_header) { - make_cleanup ((make_cleanup_ftype *) free_line_header, - (void *) line_header); + cu->line_header = line_header; + make_cleanup (free_cu_line_header, cu); dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL); } } + /* Process all dies in compilation unit. */ + if (die->child != NULL) + { + child_die = die->child; + while (child_die && child_die->tag) + { + process_die (child_die, cu); + child_die = sibling_die (child_die); + } + } + /* Decode macro information, if present. Dwarf 2 macro information refers to information in the line number info statement program header, so we can only read it if we've read the header @@ -6457,6 +6472,7 @@ add_file_name (struct line_header *lh, fe->mod_time = mod_time; fe->length = length; fe->included_p = 0; + fe->symtab = NULL; } @@ -6644,7 +6660,7 @@ dwarf_decode_lines (struct line_header * CORE_ADDR baseaddr; struct objfile *objfile = cu->objfile; const int decode_for_pst_p = (pst != NULL); - struct subfile *last_subfile = NULL; + struct subfile *last_subfile = NULL, *first_subfile = current_subfile; baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -6869,6 +6885,35 @@ dwarf_decode_lines (struct line_header * dwarf2_create_include_psymtab (include_name, pst, objfile); } } + else + { + /* Make sure a symtab is created for every file, even files + which contain only variables (i.e. no code with associated + line numbers). */ + + int i; + struct file_entry *fe; + + for (i = 0; i < lh->num_file_names; i++) + { + char *dir = NULL; + fe = &lh->file_names[i]; + if (fe->dir_index) + dir = lh->include_dirs[fe->dir_index - 1]; + dwarf2_start_subfile (fe->name, dir, comp_dir); + + /* Skip the main file; we don't need it, and it must be + allocated last, so that it will show up before the + non-primary symtabs in the objfile's symtab list. */ + if (current_subfile == first_subfile) + continue; + + if (current_subfile->symtab == NULL) + current_subfile->symtab = allocate_symtab (current_subfile->name, + cu->objfile); + fe->symtab = current_subfile->symtab; + } + } } /* Start a subfile for DWARF. FILENAME is the name of the file and @@ -7024,6 +7069,23 @@ new_symbol (struct die_info *die, struct { SYMBOL_LINE (sym) = DW_UNSND (attr); } + + attr = dwarf2_attr (die, DW_AT_decl_file, cu); + if (attr) + { + int file_index = DW_UNSND (attr); + if (cu->line_header == NULL + || file_index > cu->line_header->num_file_names) + complaint (&symfile_complaints, + _("file index out of range")); + else + { + struct file_entry *fe; + fe = &cu->line_header->file_names[file_index - 1]; + SYMBOL_SYMTAB (sym) = fe->symtab; + } + } + switch (die->tag) { case DW_TAG_label: Index: symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.152 diff -u -p -r1.152 symtab.c --- symtab.c 9 Jan 2007 22:43:08 -0000 1.152 +++ symtab.c 21 Jan 2007 16:42:10 -0000 @@ -1133,6 +1133,10 @@ lookup_symbol (const char *name, const s if (needtofreename) xfree (demangled_name); + /* Override the returned symtab with the symbol's specific one. */ + if (returnval != NULL && symtab != NULL) + *symtab = SYMBOL_SYMTAB (returnval); + return returnval; } @@ -3008,7 +3012,11 @@ search_symbols (char *regexp, domain_enu QUIT; /* If it would match (logic taken from loop below) - load the file and go on to the next one */ + load the file and go on to the next one. We check the + filename here, but that's a bit bogus: we don't know + what file it really comes from until we have full + symtabs. The symbol might be in a header file included by + this psymtab. This only affects Insight. */ if (file_matches (ps->filename, files, nfiles) && ((regexp == NULL || re_exec (SYMBOL_NATURAL_NAME (*psym)) != 0) @@ -3087,8 +3095,10 @@ search_symbols (char *regexp, domain_enu b = BLOCKVECTOR_BLOCK (bv, i); ALL_BLOCK_SYMBOLS (b, iter, sym) { + struct symtab *real_symtab = SYMBOL_SYMTAB (sym); QUIT; - if (file_matches (s->filename, files, nfiles) + + if (file_matches (real_symtab->filename, files, nfiles) && ((regexp == NULL || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0) && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF @@ -3101,7 +3111,7 @@ search_symbols (char *regexp, domain_enu /* match */ psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search)); psr->block = i; - psr->symtab = s; + psr->symtab = real_symtab; psr->symbol = sym; psr->msymbol = NULL; psr->next = NULL; Index: symtab.h =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.100 diff -u -p -r1.100 symtab.h --- symtab.h 9 Jan 2007 17:58:59 -0000 1.100 +++ symtab.h 21 Jan 2007 16:42:11 -0000 @@ -609,6 +609,10 @@ struct symbol struct type *type; + /* The symbol table containing this symbol. This is the file + associated with LINE. */ + struct symtab *symtab; + /* Domain code. */ ENUM_BITFIELD(domain_enum_tag) domain : 6; @@ -664,6 +668,7 @@ struct symbol #define SYMBOL_CLASS(symbol) (symbol)->aclass #define SYMBOL_TYPE(symbol) (symbol)->type #define SYMBOL_LINE(symbol) (symbol)->line +#define SYMBOL_SYMTAB(symbol) (symbol)->symtab #define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg #define SYMBOL_OBJFILE(symbol) (symbol)->aux_value.objfile #define SYMBOL_OPS(symbol) (symbol)->ops Index: testsuite/gdb.base/included.c =================================================================== RCS file: testsuite/gdb.base/included.c diff -N testsuite/gdb.base/included.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/included.c 21 Jan 2007 16:42:11 -0000 @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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. */ + +#include "included.h" + +int +main() +{ + return 0; +} Index: testsuite/gdb.base/included.exp =================================================================== RCS file: testsuite/gdb.base/included.exp diff -N testsuite/gdb.base/included.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/included.exp 21 Jan 2007 16:42:11 -0000 @@ -0,0 +1,46 @@ +# Copyright 2007 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. + +set testfile "included" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested included.exp + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +gdb_test "set listsize 1" "" + +gdb_test "list main" ".*" +get_debug_format +set non_dwarf [expr ! [test_debug_format "DWARF 2"]] + +# We should be able to find the source file containing the definition, +# even though it was an included header. +if { $non_dwarf } { setup_xfail *-*-* } +gdb_test "list integer" "int integer;" + +gdb_test "ptype integer" "type = int" + +# We should report that integer comes from the header file. +if { $non_dwarf } { setup_xfail *-*-* } +gdb_test "info variables integer" "\r\nFile \[^\r\n\]*/${subdir}/${testfile}.h:\r\nint integer;" Index: testsuite/gdb.base/included.h =================================================================== RCS file: testsuite/gdb.base/included.h diff -N testsuite/gdb.base/included.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/included.h 21 Jan 2007 16:42:11 -0000 @@ -0,0 +1,20 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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. */ + +int integer;