[gdb/testsuite] Fix bad line table entry sequence Consider test-case gdb.dwarf2/dw2-ranges-base.exp. It has a line-table for dw2-ranges-base.c like this: ... Line Number Statements: [0x0000014e] Extended opcode 2: set Address to 0x4004ba [0x00000159] Advance Line by 10 to 11 [0x0000015b] Copy [0x0000015c] Advance PC by 12 to 0x4004c6 [0x0000015e] Advance Line by 19 to 30 [0x00000160] Copy [0x00000161] Extended opcode 1: End of Sequence ... The Copy followed by End-of-Sequence is as specified in the dwarf assembly, but incorrect. Both the Copy and the End-of-Sequence append a row to the matrix, each using the same addres: 0x4004c6. The Copy declares a target instruction at that address. The End-of-Sequence declares that the sequence ends before that address. It's a contradiction that the target instruction is both part of the sequence (according to Copy) and not part of the sequence (according to End-of-Sequence). The offending Copy is silently skipped by buildsym_compunit::record_line. A gdb PR has been filed to warn about this (PR26092). Fix the dwarf assembly test-cases that contain this contradictory construct, to prevent people from: - coming across this while testing patches, and mistakenly getting the impression that this is valid dwarf, or even - copying it to new test-cases. Also, add a dwarf assembly test-case called dw2-bad-dw-lne-end-sequence.exp containing this construct, to verify that it's ignored. Tested on x86_64-linux. Also tested using a detection patch with assert, such that the only test-case triggering that assert is dw2-bad-dw-lne-end-sequence.exp. The corresponding build had to be done without --with-separate-debug-dir=/usr/lib/debug", otherwise we'd trigger the assert in debug info generated with recent GCC (PR gcc/95574). gdb/testsuite/ChangeLog: 2020-06-08 Tom de Vries * gdb.dwarf2/dw2-bad-elf.exp: Fix bad line table entry sequence. * gdb.dwarf2/dw2-dir-file-name.exp: Same. * gdb.dwarf2/dw2-inline-small-func.exp: Same. * gdb.dwarf2/dw2-ranges-base.exp: Same. * gdb.dwarf2/dw2-ranges-func.exp: Same. * gdb.dwarf2/dw2-bad-dw-lne-end-sequence.exp: New file. --- .../gdb.dwarf2/dw2-bad-dw-lne-end-sequence.exp | 116 +++++++++++++++++++++ gdb/testsuite/gdb.dwarf2/dw2-bad-elf.exp | 4 - gdb/testsuite/gdb.dwarf2/dw2-dir-file-name.exp | 1 - gdb/testsuite/gdb.dwarf2/dw2-inline-small-func.exp | 1 - gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp | 6 -- gdb/testsuite/gdb.dwarf2/dw2-ranges-func.exp | 10 -- 6 files changed, 116 insertions(+), 22 deletions(-) diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bad-dw-lne-end-sequence.exp b/gdb/testsuite/gdb.dwarf2/dw2-bad-dw-lne-end-sequence.exp new file mode 100644 index 0000000000..b01f82ce85 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-bad-dw-lne-end-sequence.exp @@ -0,0 +1,116 @@ +# Copyright 2020 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 . + +# Test that line table entries with the same address as an DW_LNE_end_sequence +# are ignored. + +load_lib dwarf.exp + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + verbose "Skipping bad DW_LNE_end_sequence test." + return 0 +} + +standard_testfile main.c .dwarf.S + +set asm_file [standard_output_file $srcfile2] +Dwarf::assemble $asm_file { + global srcdir subdir srcfile srcfile2 + declare_labels L + + # Find start address and length for our functions. + set main_func \ + [function_range main [list ${srcdir}/${subdir}/$srcfile]] + + cu {} { + compile_unit { + {language @DW_LANG_C} + {name main.c} + {stmt_list $L DW_FORM_sec_offset} + } { + subprogram { + {external 1 flag} + {name main} + } + } + } + + lines {version 2} L { + include_dir "${srcdir}/${subdir}" + file_name "$srcfile" 1 + + # Generate simple line table program. The last DW_LNS_copy is + # problematic because it has the same address as the + # DW_LNE_end_sequence. We'll test that it's ignored. + program { + {DW_LNE_set_address [lindex $main_func 0]} + {DW_LNS_advance_line 10} + {DW_LNS_copy} + {DW_LNS_advance_pc [lindex $main_func 1]} + {DW_LNS_advance_line 19} + {DW_LNS_copy} + {DW_LNE_end_sequence} + } + } +} + +if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}] } { + return -1 +} + +gdb_test_no_output "set auto-solib-add off" + +if ![runto_main] { + return -1 +} + +gdb_test_no_output "maint expand-symtabs gdb.dwarf2/main.c" \ + "maint expand-symtabs" + +set header_re \ + [multi_line \ + ".*linetable: \\(\\(struct linetable \\*\\) $hex\\):" \ + "INDEX\[ \t\]+LINE\[ \t\]+ADDRESS\[ \t\]+IS-STMT *" \ + ""] + +set end_of_sequence_re \ + "^$decimal\[ \t\]+END\[ \t\]+$hex\(\[ \t\]+Y\)? *\r\n" + +set ok 1 +set cmd "maint info line-table gdb.dwarf2/main.c" +gdb_test_multiple $cmd "bad ops ignored" { + -re "^$decimal\[ \t\]+($decimal)\[ \t\]+$hex\(\[ \t\]+Y\)? *\r\n" { + set line $expect_out(1,string) + if { $line != 11 } { + set ok 0 + } + exp_continue + } + -re "$end_of_sequence_re" { + exp_continue + } + -re "^$gdb_prompt $" { + if { $ok } { + pass $gdb_test_name + } else { + fail $gdb_test_name + } + } + -re $header_re { + exp_continue + } +} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bad-elf.exp b/gdb/testsuite/gdb.dwarf2/dw2-bad-elf.exp index f6fe54a634..88a522ad63 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-bad-elf.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-bad-elf.exp @@ -126,8 +126,6 @@ Dwarf::assemble $asm_file { {DW_LNS_advance_line 10} {DW_LNS_copy} {DW_LNS_advance_pc [lindex $main_result 1]} - {DW_LNS_advance_line 19} - {DW_LNS_copy} {DW_LNE_end_sequence} } } @@ -142,8 +140,6 @@ Dwarf::assemble $asm_file { {DW_LNS_advance_line 5} {DW_LNS_copy} {DW_LNS_advance_pc 64} - {DW_LNS_advance_line 8} - {DW_LNS_copy} {DW_LNE_end_sequence} } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-dir-file-name.exp b/gdb/testsuite/gdb.dwarf2/dw2-dir-file-name.exp index 0de71f29d5..3fc142661b 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-dir-file-name.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-dir-file-name.exp @@ -146,7 +146,6 @@ proc out_line { name cu_dir cu_name line_dir line_name } { .uleb128 ${addr_len}+1 .byte 2 .${addr_len}byte ${name}_end - .byte 1 /* DW_LNS_copy */ .byte 0 /* DW_LNE_end_of_sequence */ .uleb128 1 .byte 1 diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-small-func.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-small-func.exp index 4fcc3cfeac..1efe49d009 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-inline-small-func.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-small-func.exp @@ -114,7 +114,6 @@ Dwarf::assemble $asm_file { {DW_LNS_copy} {DW_LNE_set_address line_label_3} - {DW_LNS_copy} {DW_LNE_end_sequence} } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp index 92f8f6cecb..9e4ebf7f3c 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp @@ -88,24 +88,18 @@ Dwarf::assemble $asm_file { {DW_LNS_advance_line 10} {DW_LNS_copy} {DW_LNS_advance_pc [lindex $main_func 1]} - {DW_LNS_advance_line 19} - {DW_LNS_copy} {DW_LNE_end_sequence} {DW_LNE_set_address [lindex $frame2_func 0]} {DW_LNS_advance_line 20} {DW_LNS_copy} {DW_LNS_advance_pc [lindex $frame2_func 1]} - {DW_LNS_advance_line 29} - {DW_LNS_copy} {DW_LNE_end_sequence} {DW_LNE_set_address [lindex $frame3_func 0]} {DW_LNS_advance_line 30} {DW_LNS_copy} {DW_LNS_advance_pc [lindex $frame3_func 1]} - {DW_LNS_advance_line 39} - {DW_LNS_copy} {DW_LNE_end_sequence} } } diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-func.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges-func.exp index 0a95adc5bc..eafd9f65fb 100644 --- a/gdb/testsuite/gdb.dwarf2/dw2-ranges-func.exp +++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-func.exp @@ -143,8 +143,6 @@ proc do_test {suffix} { {DW_LNS_advance_line [expr [gdb_get_line_number "main return"] - [gdb_get_line_number "main foo call"]]} {DW_LNS_copy} {DW_LNE_set_address $main_end} - {DW_LNS_advance_line [expr [gdb_get_line_number "main end"] - [gdb_get_line_number "main return"] + 1]} - {DW_LNS_copy} {DW_LNE_end_sequence} {DW_LNE_set_address $foo_start} @@ -160,24 +158,18 @@ proc do_test {suffix} { {DW_LNS_advance_line [expr [gdb_get_line_number "foo end"] - [gdb_get_line_number "foo foo_cold call"]]} {DW_LNS_copy} {DW_LNE_set_address $foo_end} - {DW_LNS_advance_line 1} - {DW_LNS_copy} {DW_LNE_end_sequence} {DW_LNE_set_address $bar_start} {DW_LNS_advance_line [expr [gdb_get_line_number "bar end"] - 1]} {DW_LNS_copy} {DW_LNS_advance_pc $bar_len} - {DW_LNS_advance_line 1} - {DW_LNS_copy} {DW_LNE_end_sequence} {DW_LNE_set_address $baz_start} {DW_LNS_advance_line [expr [gdb_get_line_number "baz end"] - 1]} {DW_LNS_copy} {DW_LNS_advance_pc $baz_len} - {DW_LNS_advance_line 1} - {DW_LNS_copy} {DW_LNE_end_sequence} {DW_LNE_set_address $foo_cold_start} @@ -190,8 +182,6 @@ proc do_test {suffix} { {DW_LNS_advance_line [expr [gdb_get_line_number "foo_cold end"] - [gdb_get_line_number "foo_cold baz call"]]} {DW_LNS_copy} {DW_LNE_set_address $foo_cold_end} - {DW_LNS_advance_line 1} - {DW_LNS_copy} {DW_LNE_end_sequence} } }