* 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:
parent
86991504e7
commit
4584e32ea4
@ -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.
|
||||
|
@ -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.) */
|
||||
|
||||
|
@ -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.
|
||||
|
57
gdb/testsuite/gdb.base/hashline1.exp
Normal file
57
gdb/testsuite/gdb.base/hashline1.exp
Normal 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"
|
56
gdb/testsuite/gdb.base/hashline2.exp
Normal file
56
gdb/testsuite/gdb.base/hashline2.exp
Normal 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"
|
55
gdb/testsuite/gdb.base/hashline3.exp
Normal file
55
gdb/testsuite/gdb.base/hashline3.exp
Normal 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"
|
Loading…
Reference in New Issue
Block a user