diff options
author | WANG Rui <r@hev.cc> | 2023-04-22 07:50:08 +0200 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2023-04-22 07:50:08 +0200 |
commit | a88ee931eee4ba7339c481735b9405f66161e2f6 (patch) | |
tree | 67adc6759eafd58665eb8e8200989a5c05e58c0e | |
parent | d89504f0d90dedd3d5ab83d8c91707a354231d2f (diff) | |
download | gdb-a88ee931eee4ba7339c481735b9405f66161e2f6.zip gdb-a88ee931eee4ba7339c481735b9405f66161e2f6.tar.gz gdb-a88ee931eee4ba7339c481735b9405f66161e2f6.tar.bz2 |
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.
<fun1>:
0x00: ... <-- start_pc
0x04: ...
0x08: ... <-- breakpoint
0x0c: ret
<fun2>:
0x10: ret <-- end_pc | prologue_end of fun2
Tested on x86_64-linux.
Co-Authored-By: WANG Rui <r@hev.cc> (fix, tiny change [1])
Co-Authored-By: Tom de Vries <tdevries@suse.de> (test-case)
Approved-by: Kevin Buettner <kevinb@redhat.com>
[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
-rw-r--r-- | gdb/symtab.c | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.c | 30 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/dw2-prologue-end-2.exp | 118 |
3 files changed, 149 insertions, 1 deletions
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 <http://www.gnu.org/licenses/>. */ + +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 <http://www.gnu.org/licenses/>. + +# 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 } |