aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>2008-04-17 17:54:05 +0000
committerDoug Evans <dje@google.com>2008-04-17 17:54:05 +0000
commit4584e32ea409bd2b80cd4aba8635de091a47da4b (patch)
tree0c56c6a763bce306c8752b812bbba52a76decbe4
parent86991504e78a38eec35bd639142409df56663b0a (diff)
downloadgdb-4584e32ea409bd2b80cd4aba8635de091a47da4b.zip
gdb-4584e32ea409bd2b80cd4aba8635de091a47da4b.tar.gz
gdb-4584e32ea409bd2b80cd4aba8635de091a47da4b.tar.bz2
* 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.
-rw-r--r--gdb/ChangeLog3
-rw-r--r--gdb/buildsym.c80
-rw-r--r--gdb/testsuite/ChangeLog6
-rw-r--r--gdb/testsuite/gdb.base/hashline1.exp57
-rw-r--r--gdb/testsuite/gdb.base/hashline2.exp56
-rw-r--r--gdb/testsuite/gdb.base/hashline3.exp55
6 files changed, 257 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 28d7ae5..ffb98b2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index cccd769..282dc4e 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -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.) */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index ff33944..82ae12f 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -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.
diff --git a/gdb/testsuite/gdb.base/hashline1.exp b/gdb/testsuite/gdb.base/hashline1.exp
new file mode 100644
index 0000000..ea3c9c8
--- /dev/null
+++ b/gdb/testsuite/gdb.base/hashline1.exp
@@ -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"
diff --git a/gdb/testsuite/gdb.base/hashline2.exp b/gdb/testsuite/gdb.base/hashline2.exp
new file mode 100644
index 0000000..22d051e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/hashline2.exp
@@ -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"
diff --git a/gdb/testsuite/gdb.base/hashline3.exp b/gdb/testsuite/gdb.base/hashline3.exp
new file mode 100644
index 0000000..34582b1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/hashline3.exp
@@ -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"