From patchwork Mon Nov 10 00:16:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Evans X-Patchwork-Id: 3629 Received: (qmail 25508 invoked by alias); 10 Nov 2014 00:17:06 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 25498 invoked by uid 89); 10 Nov 2014 00:17:05 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f48.google.com Received: from mail-pa0-f48.google.com (HELO mail-pa0-f48.google.com) (209.85.220.48) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Mon, 10 Nov 2014 00:17:04 +0000 Received: by mail-pa0-f48.google.com with SMTP id ey11so7006530pad.7 for ; Sun, 09 Nov 2014 16:17:02 -0800 (PST) X-Received: by 10.67.15.174 with SMTP id fp14mr28668840pad.66.1415578622455; Sun, 09 Nov 2014 16:17:02 -0800 (PST) Received: from seba.sebabeach.org.gmail.com (173-13-178-50-sfba.hfc.comcastbusiness.net. [173.13.178.50]) by mx.google.com with ESMTPSA id a12sm14752350pdm.64.2014.11.09.16.17.01 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 09 Nov 2014 16:17:01 -0800 (PST) From: Doug Evans To: gdb-patches@sourceware.org Subject: [PATCH] Fix PR 17559: confusion over result of find_pc_line Date: Sun, 09 Nov 2014 16:16:10 -0800 Message-ID: MIME-Version: 1.0 X-IsSubscribed: yes 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 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. 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 . + +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; }