diff mbox

Fix PR 17559: confusion over result of find_pc_line

Message ID m3r3xb29md.fsf@sspiff.org
State New
Headers show

Commit Message

Doug Evans Nov. 10, 2014, 12:16 a.m. UTC
Hi.

This patch fixes pr 17559.

Basically the problem is that "symtab" is ambiguous.
Is it the primary symtab (where we canonically think of
blockvectors as being stored) or is it for a specific file
(where each file's line table is stored) ?
[btw, I have a big data structure reorg patch in my sandbox to fix this]

gdb_disassembly wants the symtab that contains the line table
but is instead getting the primary symtab.

Regression tested on amd64-linux.

2014-11-09  Doug Evans  <xdje42@gmail.com>

	PR symtab/17559
	* symtab.c (find_pc_line_symtab): New function.
	* symtab.h (find_pc_line_symtab): Declare.
	* disasm.c (gdb_disassembly): Call find_pc_line_symtab instead of
	find_pc_symtab.
	* tui/tui-disasm.c (tui_set_disassem_content): Ditto.
	* tui/tui-hooks.c (tui_selected_frame_level_changed_hook): Ditto.
	* tui/tui-source.c (tui_vertical_source_scroll): Ditto.
	* tui/tui-win.c (make_visible_with_new_height): Ditto.
	* tui/tui-winsource.c (tui_horizontal_source_scroll): Ditto.
	(tui_display_main): Call find_pc_line_symtab instead of find_pc_line.

	testsuite/
	* gdb.base/line-symtabs.exp: New file.
	* gdb.base/line-symtabs.c: New file.
	* gdb.base/line-symtabs.h: New file.

Comments

Doug Evans Nov. 15, 2014, 6:12 p.m. UTC | #1
On Sun, Nov 9, 2014 at 4:16 PM, Doug Evans <xdje42@gmail.com> wrote:
> Hi.
>
> This patch fixes pr 17559.
>
> Basically the problem is that "symtab" is ambiguous.
> Is it the primary symtab (where we canonically think of
> blockvectors as being stored) or is it for a specific file
> (where each file's line table is stored) ?
> [btw, I have a big data structure reorg patch in my sandbox to fix this]
>
> gdb_disassembly wants the symtab that contains the line table
> but is instead getting the primary symtab.
>
> Regression tested on amd64-linux.
>
> 2014-11-09  Doug Evans  <xdje42@gmail.com>
>
>         PR symtab/17559
>         * symtab.c (find_pc_line_symtab): New function.
>         * symtab.h (find_pc_line_symtab): Declare.
>         * disasm.c (gdb_disassembly): Call find_pc_line_symtab instead of
>         find_pc_symtab.
>         * tui/tui-disasm.c (tui_set_disassem_content): Ditto.
>         * tui/tui-hooks.c (tui_selected_frame_level_changed_hook): Ditto.
>         * tui/tui-source.c (tui_vertical_source_scroll): Ditto.
>         * tui/tui-win.c (make_visible_with_new_height): Ditto.
>         * tui/tui-winsource.c (tui_horizontal_source_scroll): Ditto.
>         (tui_display_main): Call find_pc_line_symtab instead of find_pc_line.
>
>         testsuite/
>         * gdb.base/line-symtabs.exp: New file.
>         * gdb.base/line-symtabs.c: New file.
>         * gdb.base/line-symtabs.h: New file.

Committed.
[I added copyright headers to line-symtabs.[ch].]
diff mbox

Patch

diff --git a/gdb/disasm.c b/gdb/disasm.c
index 6ff3793..365aa94 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -410,13 +410,12 @@  gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
   struct ui_file *stb = mem_fileopen ();
   struct cleanup *cleanups = make_cleanup_ui_file_delete (stb);
   struct disassemble_info di = gdb_disassemble_info (gdbarch, stb);
-  /* To collect the instruction outputted from opcodes.  */
-  struct symtab *symtab = NULL;
+  struct symtab *symtab;
   struct linetable_entry *le = NULL;
   int nlines = -1;
 
   /* Assume symtab is valid for whole PC range.  */
-  symtab = find_pc_symtab (low);
+  symtab = find_pc_line_symtab (low);
 
   if (symtab != NULL && symtab->linetable != NULL)
     {
diff --git a/gdb/symtab.c b/gdb/symtab.c
index df974bf..25eed38 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -2442,6 +2442,19 @@  find_pc_line (CORE_ADDR pc, int notcurrent)
     pc = overlay_mapped_address (pc, section);
   return find_pc_sect_line (pc, section, notcurrent);
 }
+
+/* See symtab.h.  */
+
+struct symtab *
+find_pc_line_symtab (CORE_ADDR pc)
+{
+  struct symtab_and_line sal;
+
+  /* This always passes zero for NOTCURRENT to find_pc_line.
+     There are currently no callers that ever pass non-zero.  */
+  sal = find_pc_line (pc, 0);
+  return sal.symtab;
+}
 
 /* Find line number LINE in any symtab whose name is the same as
    SYMTAB.
diff --git a/gdb/symtab.h b/gdb/symtab.h
index d78b832..635cd21 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1272,6 +1272,10 @@  extern struct symtab_and_line find_pc_line (CORE_ADDR, int);
 extern struct symtab_and_line find_pc_sect_line (CORE_ADDR,
 						 struct obj_section *, int);
 
+/* Wrapper around find_pc_line to just return the symtab.  */
+
+extern struct symtab *find_pc_line_symtab (CORE_ADDR);
+
 /* Given a symtab and line number, return the pc there.  */
 
 extern int find_line_pc (struct symtab *, int, CORE_ADDR *);
diff --git a/gdb/testsuite/gdb.base/line-symtabs.c b/gdb/testsuite/gdb.base/line-symtabs.c
new file mode 100644
index 0000000..e9e715b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/line-symtabs.c
@@ -0,0 +1,8 @@ 
+#include "line-symtabs.h"
+
+int
+main ()
+{
+  header_function ();
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/line-symtabs.exp b/gdb/testsuite/gdb.base/line-symtabs.exp
new file mode 100644
index 0000000..9bcbb92
--- /dev/null
+++ b/gdb/testsuite/gdb.base/line-symtabs.exp
@@ -0,0 +1,33 @@ 
+# Test handling of line symbol tables (non-primary symtabs).
+# Copyright 2014 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/>.
+
+standard_testfile .c line-symtabs.h
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+if ![runto_main] {
+    fail "Can't run to main"
+    return -1
+}
+
+# PR 17559: gdb_disassembly was using the wrong symtab lookup function.
+# It was expecting the symtab of the source file containing $pc,
+# instead it was getting the primary symtab of that compilation unit.
+gdb_breakpoint "$srcfile2:[gdb_get_line_number {break here} $srcfile2]"
+gdb_continue_to_breakpoint "continue to breakpoint in header"
+gdb_test "disas /m" "break here.*End of assembler dump\\."
diff --git a/gdb/testsuite/gdb.base/line-symtabs.h b/gdb/testsuite/gdb.base/line-symtabs.h
new file mode 100644
index 0000000..66c9215
--- /dev/null
+++ b/gdb/testsuite/gdb.base/line-symtabs.h
@@ -0,0 +1,8 @@ 
+
+int x;
+
+void
+header_function (void)
+{
+  x = 42; /* break here */
+}
diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c
index 1c89a14..88b14de 100644
--- a/gdb/tui/tui-disasm.c
+++ b/gdb/tui/tui-disasm.c
@@ -275,7 +275,7 @@  tui_set_disassem_content (struct gdbarch *gdbarch, CORE_ADDR pc)
 void
 tui_show_disassem (struct gdbarch *gdbarch, CORE_ADDR start_addr)
 {
-  struct symtab *s = find_pc_symtab (start_addr);
+  struct symtab *s = find_pc_line_symtab (start_addr);
   struct tui_win_info *win_with_focus = tui_win_with_focus ();
   struct tui_line_or_address val;
 
diff --git a/gdb/tui/tui-hooks.c b/gdb/tui/tui-hooks.c
index 7db392a..4c6e450 100644
--- a/gdb/tui/tui-hooks.c
+++ b/gdb/tui/tui-hooks.c
@@ -202,7 +202,7 @@  tui_selected_frame_level_changed_hook (int level)
     {
       struct symtab *s;
 
-      s = find_pc_symtab (pc);
+      s = find_pc_line_symtab (pc);
       /* elz: This if here fixes the problem with the pc not being
 	 displayed in the tui asm layout, with no debug symbols.  The
 	 value of s would be 0 here, and select_source_symtab would
diff --git a/gdb/tui/tui-source.c b/gdb/tui/tui-source.c
index 7aceaa8..9842bb3 100644
--- a/gdb/tui/tui-source.c
+++ b/gdb/tui/tui-source.c
@@ -357,7 +357,7 @@  tui_vertical_source_scroll (enum tui_scroll_direction scroll_direction,
       struct symtab_and_line cursal = get_current_source_symtab_and_line ();
 
       if (cursal.symtab == (struct symtab *) NULL)
-	s = find_pc_symtab (get_frame_pc (get_selected_frame (NULL)));
+	s = find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)));
       else
 	s = cursal.symtab;
 
diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c
index 9c7a23f..d17a1e4 100644
--- a/gdb/tui/tui-win.c
+++ b/gdb/tui/tui-win.c
@@ -1386,7 +1386,7 @@  make_visible_with_new_height (struct tui_win_info *win_info)
 	  struct frame_info *frame = deprecated_safe_get_selected_frame ();
 	  struct gdbarch *gdbarch = get_frame_arch (frame);
 
-	  s = find_pc_symtab (get_frame_pc (frame));
+	  s = find_pc_line_symtab (get_frame_pc (frame));
 	  if (win_info->generic.type == SRC_WIN)
 	    {
 	      line.loa = LOA_LINE;
diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c
index 171b171..48a95e4 100644
--- a/gdb/tui/tui-winsource.c
+++ b/gdb/tui/tui-winsource.c
@@ -51,12 +51,12 @@  tui_display_main (void)
       tui_get_begin_asm_address (&gdbarch, &addr);
       if (addr != (CORE_ADDR) 0)
 	{
-	  struct symtab_and_line sal;
+	  struct symtab *s;
 
 	  tui_update_source_windows_with_addr (gdbarch, addr);
-	  sal = find_pc_line (addr, 0);
-          if (sal.symtab)
-             tui_update_locator_fullname (symtab_to_fullname (sal.symtab));
+	  s = find_pc_line_symtab (addr);
+          if (s != NULL)
+             tui_update_locator_fullname (symtab_to_fullname (s));
           else
              tui_update_locator_fullname ("??");
 	}
@@ -331,7 +331,7 @@  tui_horizontal_source_scroll (struct tui_win_info *win_info,
 	    = get_current_source_symtab_and_line ();
 
 	  if (cursal.symtab == NULL)
-	    s = find_pc_symtab (get_frame_pc (get_selected_frame (NULL)));
+	    s = find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)));
 	  else
 	    s = cursal.symtab;
 	}