From a88ee931eee4ba7339c481735b9405f66161e2f6 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Sat, 22 Apr 2023 07:50:08 +0200 Subject: gdb: Fix false match issue in skip_prologue_using_linetable [ Changes in v2: - rebase on trunk Changes in v3: - add test-case ] We should exclude matches to the ending PC to prevent false matches with the next function, as prologue_end is located at the end PC. : 0x00: ... <-- start_pc 0x04: ... 0x08: ... <-- breakpoint 0x0c: ret : 0x10: ret <-- end_pc | prologue_end of fun2 Tested on x86_64-linux. Co-Authored-By: WANG Rui (fix, tiny change [1]) Co-Authored-By: Tom de Vries (test-case) Approved-by: Kevin Buettner [1] https://www.gnu.org/prep/maintain/html_node/Legally-Significant.html PR symtab/30369 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30369 --- gdb/symtab.c | 2 +- gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.c | 30 ++++++ gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp | 118 ++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.c create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp diff --git a/gdb/symtab.c b/gdb/symtab.c index 9e1e8e9..27611a3 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -3715,7 +3715,7 @@ skip_prologue_using_linetable (CORE_ADDR func_addr) for (; (it < linetable->item + linetable->nitems - && it->raw_pc () <= unrel_end); + && it->raw_pc () < unrel_end); it++) if (it->prologue_end) return {it->pc (objfile)}; diff --git a/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.c b/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.c new file mode 100644 index 0000000..2f29652 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.c @@ -0,0 +1,30 @@ +/* Copyright 2023 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 . */ + +int +main (void) +{ + int main = 1; /* Main body. */ + + asm ("foo_label: .global foo_label"); + int foo = 2; /* Foo body. */ + asm ("foo_end: .global foo_end"); + + asm ("bar_label: .global bar_label"); + int bar = 3; /* Bar body. */ + asm ("bar_end: .global bar_end"); + + return main + foo + bar; +} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp b/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp new file mode 100644 index 0000000..488f85f --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp @@ -0,0 +1,118 @@ +# Copyright 2023 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 . + +# Check that prologue analysis in foo is correct in the presence of a +# prologue_end marker in immediately following function bar. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +require dwarf2_support + +standard_testfile .c .S + +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + global srcdir subdir srcfile srcfile2 + declare_labels lines_label + + cu {} { + compile_unit { + {language @DW_LANG_C} + {name dw2-prologue-end.c} + {stmt_list ${lines_label} DW_FORM_sec_offset} + } { + subprogram { + {external 1 flag} + {name foo} + {low_pc foo_label addr} + {high_pc foo_end addr} + } + subprogram { + {external 1 flag} + {name bar} + {low_pc bar_label addr} + {high_pc bar_end addr} + } + } + } + + lines {version 5} lines_label { + set diridx [include_dir "${srcdir}/${subdir}"] + file_name "$srcfile" $diridx + + program { + DW_LNS_set_file $diridx + + DW_LNE_set_address foo_label + line [gdb_get_line_number "Foo body"] + DW_LNS_copy + + DW_LNE_set_address bar_label + DW_LNS_set_prologue_end + line [gdb_get_line_number "Bar body"] + DW_LNS_copy + + DW_LNE_set_address bar_end + DW_LNE_end_sequence + } + } +} + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}] } { + return -1 +} + +# Don't runto main here, otherwise the following doesn't +# function as regression test for PR30369. + +# Get the "break foo" address. + +set break_addr "" +gdb_test_multiple "break foo" "" { + -re -wrap "at ($hex):\[^\r\n\]*" { + set break_addr $expect_out(1,string) + pass $gdb_test_name + } +} + +if { $break_addr == "" } { + return +} + +# Get the "foo_label" address. + +set foo_label_addr "" +gdb_test_multiple "print /x &foo_label" "" { + -re -wrap "= ($hex)" { + set foo_label_addr $expect_out(1,string) + pass $gdb_test_name + } +} + +if { $foo_label_addr == "" } { + return +} + +# Check that bar immediately follows foo. Otherwise the following doesn't +# function as regression test for PR30369. + +gdb_test "print &foo_end == &bar_label" " = 1" + +# Check that the breakpoint is set at the expected address. Regression test +# for PR30369. + +gdb_assert { $break_addr == $foo_label_addr } -- cgit v1.1