* buildsym.c (watch_main_source_file_lossage): New fn.

(end_symtab): Call it.

	* gdb.base/hashline1.exp: New testcase.
	* gdb.base/hashline2.exp: New testcase.
	* gdb.base/hashline2.exp: New testcase.
This commit is contained in:
Doug Evans 2008-04-17 17:54:05 +00:00
parent 86991504e7
commit 4584e32ea4
6 changed files with 257 additions and 0 deletions

View File

@ -1,5 +1,8 @@
2008-04-17 Doug Evans <dje@google.com>
* buildsym.c (watch_main_source_file_lossage): New fn.
(end_symtab): Call it.
* source.c (find_and_open_source): Add some comments clarifying
handling of FULLNAME argument. Make static. Remove pointless
xstrdup/xfree.

View File

@ -889,6 +889,81 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
start_subfile (name, dirname);
}
/* Subroutine of end_symtab to simplify it.
Look for a subfile that matches the main source file's basename.
If there is only one, and if the main source file doesn't have any
symbol or line number information, then copy this file's symtab and
line_vector to the main source file's subfile and discard the other subfile.
This can happen because of a compiler bug or from the user playing games
with #line or from things like a distributed build system that manipulates
the debug info. */
static void
watch_main_source_file_lossage (void)
{
struct subfile *mainsub, *subfile;
/* Find the main source file.
This loop could be eliminated if start_symtab saved it for us. */
mainsub = NULL;
for (subfile = subfiles; subfile; subfile = subfile->next)
{
/* The main subfile is guaranteed to be the last one. */
if (subfile->next == NULL)
mainsub = subfile;
}
/* If the main source file doesn't have any line number or symbol info,
look for an alias in another subfile.
We have to watch for mainsub == NULL here. It's a quirk of end_symtab,
it can return NULL so there may not be a main subfile. */
if (mainsub
&& mainsub->line_vector == NULL
&& mainsub->symtab == NULL)
{
const char *mainbase = lbasename (mainsub->name);
int nr_matches = 0;
struct subfile *prevsub;
struct subfile *mainsub_alias = NULL;
struct subfile *prev_mainsub_alias = NULL;
prevsub = NULL;
for (subfile = subfiles;
/* Stop before we get to the last one. */
subfile->next;
subfile = subfile->next)
{
if (strcmp (lbasename (subfile->name), mainbase) == 0)
{
++nr_matches;
mainsub_alias = subfile;
prev_mainsub_alias = prevsub;
}
prevsub = subfile;
}
if (nr_matches == 1)
{
gdb_assert (mainsub_alias != NULL && mainsub_alias != mainsub);
/* Found a match for the main source file.
Copy its line_vector and symtab to the main subfile
and then discard it. */
mainsub->line_vector = mainsub_alias->line_vector;
mainsub->line_vector_length = mainsub_alias->line_vector_length;
mainsub->symtab = mainsub_alias->symtab;
if (prev_mainsub_alias == NULL)
subfiles = mainsub_alias->next;
else
prev_mainsub_alias->next = mainsub_alias->next;
xfree (mainsub_alias);
}
}
}
/* Finish the symbol definitions for one main source file, close off
all the lexical contexts for that file (creating struct block's for
them), then make the struct symtab for that file and put it in the
@ -1010,6 +1085,11 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
if (objfile->sf->sym_read_linetable != NULL)
objfile->sf->sym_read_linetable ();
/* Handle the case where the debug info specifies a different path
for the main source file. It can cause us to lose track of its
line number information. */
watch_main_source_file_lossage ();
/* Now create the symtab objects proper, one for each subfile. */
/* (The main file is the last one on the chain.) */

View File

@ -1,3 +1,9 @@
2008-04-17 Doug Evans <dje@google.com>
* gdb.base/hashline1.exp: New testcase.
* gdb.base/hashline2.exp: New testcase.
* gdb.base/hashline2.exp: New testcase.
2008-04-17 Pedro Alves <pedro@codesourcery.com>
* gdb.base/step-break.exp, gdb.base/step-break.c: New files.

View File

@ -0,0 +1,57 @@
# 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/>.
# This file is part of the gdb testsuite.
# Test loading of line number information with absolute path in #line, bug 2360.
if $tracelevel then {
strace $tracelevel
}
set prms_id 2360
set bug_id 0
# srcfile is in objdir because we need to machine generate it in order
# to get the correct path in the #line directive.
set testfile "hashline1"
set srcfile "${testfile}.c"
set binfile "${objdir}/${subdir}/${testfile}"
set fd [open ${objdir}/${subdir}/${srcfile} w]
puts $fd "#line 2 \"[pwd]/${subdir}/${srcfile}\""
puts $fd "int main () { return 0; } /* set breakpoint here */"
close $fd
# The choice of path name for the source file is important in order to trigger
# the bug. Using ${objdir}/${subdir}/${srcfile} here won't trigger the bug.
if { [gdb_compile "./${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
untested hashline1.exp
return -1
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
set bp_location [gdb_get_line_number "set breakpoint here" ${objdir}/${subdir}/${srcfile}]
# Try to set a breakpoint on the specified file location.
gdb_test "break $srcfile:$bp_location" \
"Breakpoint.*at.* file .*$srcfile, line.*" \
"set breakpoint"

View File

@ -0,0 +1,56 @@
# 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/>.
# This file is part of the gdb testsuite.
# Test loading of line number information with an absolute path with extra
# /'s in #line, bug 2360.
if $tracelevel then {
strace $tracelevel
}
set prms_id 2360
set bug_id 0
# srcfile is in objdir because we need to machine generate it in order
# to get the correct path in the #line directive.
set testfile "hashline2"
set srcfile "${testfile}.c"
set binfile "${objdir}/${subdir}/${testfile}"
set fd [open ${objdir}/${subdir}/${srcfile} w]
puts $fd "#line 2 \"///[pwd]/${subdir}/${srcfile}\""
puts $fd "int main () { return 0; } /* set breakpoint here */"
close $fd
if { [gdb_compile "${objdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
untested hashline1.exp
return -1
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
set bp_location [gdb_get_line_number "set breakpoint here" ${objdir}/${subdir}/${srcfile}]
# Try to set a breakpoint on the specified file location.
gdb_test "break $srcfile:$bp_location" \
"Breakpoint.*at.* file .*$srcfile, line.*" \
"set breakpoint"

View File

@ -0,0 +1,55 @@
# 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/>.
# This file is part of the gdb testsuite.
# Test loading of line number information with relative path in #line, bug 2360.
if $tracelevel then {
strace $tracelevel
}
set prms_id 2360
set bug_id 0
# srcfile is in objdir because we need to machine generate it in order
# to get the correct path in the #line directive.
set testfile "hashline3"
set srcfile "${testfile}.c"
set binfile "${objdir}/${subdir}/${testfile}"
set fd [open ${objdir}/${subdir}/${srcfile} w]
puts $fd "#line 2 \"./${subdir}/${srcfile}\""
puts $fd "int main () { return 0; } /* set breakpoint here */"
close $fd
if { [gdb_compile "${objdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
untested hashline1.exp
return -1
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
set bp_location [gdb_get_line_number "set breakpoint here" ${objdir}/${subdir}/${srcfile}]
# Try to set a breakpoint on the specified file location.
gdb_test "break $srcfile:$bp_location" \
"Breakpoint.*at.* file .*$srcfile, line.*" \
"set breakpoint"