public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <andrew.burgess@embecosm.com>
To: Bernd Edlinger <bernd.edlinger@hotmail.de>
Cc: gdb-patches@sourceware.org, Tom Tromey <tom@tromey.com>
Subject: Re: [PATCH 2/2] gdb: Preserve is-stmt lines when switch between files
Date: Thu, 16 Apr 2020 18:18:09 +0100	[thread overview]
Message-ID: <20200416171809.GJ2366@embecosm.com> (raw)
In-Reply-To: <20200414112841.GC2366@embecosm.com>

Tested this patch on another machine threw up another issue with the
tests.  I was compiling the test file at -O0 to extract label
locations, and -O1 when creating the final build.  On my older machine
this (apparently) wasn't a problem, but with a newer GCC this causes a
test failure.

The only change in this version is in the
dw2-inline-header-{1,2,3}.exp files.

Thanks,
Andrew

---

commit 05c134477fa87759d018d59dc579382582dc6005
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Fri Apr 3 20:32:38 2020 +0100

    gdb: Preserve is-stmt lines when switch between files
    
    After the is-stmt support commit:
    
      commit 8c95582da858ac981f689a6f599acacb8c5c490f
      Date:   Mon Dec 30 21:04:51 2019 +0000
    
          gdb: Add support for tracking the DWARF line table is-stmt field
    
    A regression was observed where a breakpoint could no longer be placed
    in some cases.
    
    Consider a line table like this:
    
      File 1: test.c
      File 2: test.h
    
      | Addr | File | Line | Stmt |
      |------|------|------|------|
      | 1    | 1    | 16   | Y    |
      | 2    | 1    | 17   | Y    |
      | 3    | 2    | 21   | Y    |
      | 4    | 2    | 22   | Y    |
      | 4    | 1    | 18   | N    |
      | 5    | 2    | 23   | N    |
      | 6    | 1    | 24   | Y    |
      | 7    | 1    | END  | Y    |
      |------|------|------|------|
    
    Before the is-stmt patch GDB would ignore any non-stmt lines, so GDB
    built two line table structures:
    
      File 1                 File 2
      ------                 ------
    
      | Addr | Line |        | Addr | Line |
      |------|------|        |------|------|
      | 1    | 16   |        | 3    | 21   |
      | 2    | 17   |        | 4    | 22   |
      | 3    | END  |        | 6    | END  |
      | 6    | 24   |        |------|------|
      | 7    | END  |
      |------|------|
    
    After the is-stmt patch GDB now records non-stmt lines, so the
    generated line table structures look like this:
    
      File 1                   File 2
      ------                   ------
    
      | Addr | Line | Stmt |  | Addr | Line | Stmt |
      |------|------|------|  |------|------|------|
      | 1    | 16   | Y    |  | 3    | 21   | Y    |
      | 2    | 17   | Y    |  | 4    | 22   | Y    |
      | 3    | END  | Y    |  | 4    | END  | Y    |
      | 4    | 18   | N    |  | 5    | 23   | N    |
      | 5    | END  | Y    |  | 6    | END  | Y    |
      | 6    | 24   | Y    |  |------|------|------|
      | 7    | END  | Y    |
      |------|------|------|
    
    The problem is that in 'File 2', end END marker at address 4 causes
    the previous line table entry to be discarded, so we actually end up
    with this:
    
      File 2
      ------
    
      | Addr | Line | Stmt |
      |------|------|------|
      | 3    | 21   | Y    |
      | 4    | END  | Y    |
      | 5    | 23   | N    |
      | 6    | END  | Y    |
      |------|------|------|
    
    When a user tries to place a breakpoint in file 2 at line 22, this is
    no longer possible.
    
    The solution I propose here is that we ignore line table entries that
    would trigger a change of file if:
    
      1. The new line being added is at the same address as the previous
      line, and
    
      2. We have previously seen an is-stmt line at the current address.
    
    The result of this is that GDB switches file, and knows that some line
    entry (or entries) are going to be discarded, prefer to keep is-stmt
    lines and discard non-stmt lines.
    
    After this commit the lines tables are now:
    
      File 1                   File 2
      ------                   ------
    
      | Addr | Line | Stmt |  | Addr | Line | Stmt |
      |------|------|------|  |------|------|------|
      | 1    | 16   | Y    |  | 3    | 21   | Y    |
      | 2    | 17   | Y    |  | 4    | 22   | Y    |
      | 3    | END  | Y    |  | 5    | 23   | N    |
      | 5    | END  | Y    |  | 6    | END  | Y    |
      | 6    | 24   | Y    |  |------|------|------|
      | 7    | END  | Y    |
      |------|------|------|
    
    We've lost the non-stmt entry for file 1, line 18, but retained the
    is-stmt entry for file 2, line 22.  The user can now place a
    breakpoint at that location.
    
    One problem that came from this commit was the test
    gdb.cp/step-and-next-inline.exp, which broke in several places.  After
    looking at this test again I think that in some cases this test was
    only ever passing by pure luck.  The debug GCC is producing for this
    test is pretty broken.  I raised this GCC bug:
    
      https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474
    
    for this and disabled one entire half of the test.  There are still
    some cases in here that do pass, and if/when GCC is fixed it would be
    great to enable this test again.
    
    gdb/ChangeLog:
    
            * dwarf2/read.c (class lnp_state_machine) <m_last_address>: New
            member variable.
            <m_stmt_at_address>: New member variable.
            (lnp_state_machine::record_line): Don't record some lines, update
            tracking of is_stmt at the same address.
            (lnp_state_machine::lnp_state_machine): Initialise new member
            variables.
    
    gdb/testsuite/ChangeLog:
    
            * gdb.cp/step-and-next-inline.exp (do_test): Skip all tests in the
            use_header case.
            * gdb.dwarf2/dw2-inline-header-1.exp: New file.
            * gdb.dwarf2/dw2-inline-header-2.exp: New file.
            * gdb.dwarf2/dw2-inline-header-3.exp: New file.
            * gdb.dwarf2/dw2-inline-header-lbls.c: New file.
            * gdb.dwarf2/dw2-inline-header.c: New file.
            * gdb.dwarf2/dw2-inline-header.h: New file.

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index da702205c60..36e8b24a29a 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -19508,6 +19508,15 @@ class lnp_state_machine
   /* The last file a line number was recorded for.  */
   struct subfile *m_last_subfile = NULL;
 
+  /* The address of the last line entry.  */
+  CORE_ADDR m_last_address;
+
+  /* Set to true when a previous line at the same address (using
+     m_last_address) had m_is_stmt true.  This is reset to false when a
+     line entry at a new address (m_address different to m_last_address) is
+     processed.  */
+  bool m_stmt_at_address = false;
+
   /* When true, record the lines we decode.  */
   bool m_currently_recording_lines = false;
 
@@ -19701,14 +19710,34 @@ lnp_state_machine::record_line (bool end_sequence)
       fe->included_p = 1;
       if (m_record_lines_p)
 	{
-	  if (m_last_subfile != m_cu->get_builder ()->get_current_subfile ()
-	      || end_sequence)
+	  /* When we switch files we insert an end maker in the first file,
+	     switch to the second file and add a new line entry.  The
+	     problem is that the end marker inserted in the first file will
+	     discard any previous line entries at the same address.  If the
+	     line entries in the first file are marked as is-stmt, while
+	     the new line in the second file is non-stmt, then this means
+	     the end marker will discard is-stmt lines so we can have a
+	     non-stmt line.  This means that there are less addresses at
+	     which the user can insert a breakpoint.
+
+	     To improve this we track the last address in m_last_address,
+	     and whether we have seen an is-stmt at this address.  Then
+	     when switching files, if we have seen a stmt at the current
+	     address, and we are switching to create a non-stmt line, then
+	     discard the new line.  */
+	  bool file_changed
+	    = m_last_subfile != m_cu->get_builder ()->get_current_subfile ();
+	  bool ignore_this_line
+	    = (file_changed && !end_sequence && m_last_address == m_address
+	       && !m_is_stmt && m_stmt_at_address);
+
+	  if ((file_changed && !ignore_this_line) || end_sequence)
 	    {
 	      dwarf_finish_line (m_gdbarch, m_last_subfile, m_address,
 				 m_currently_recording_lines ? m_cu : nullptr);
 	    }
 
-	  if (!end_sequence)
+	  if (!end_sequence && !ignore_this_line)
 	    {
 	      bool is_stmt = producer_is_codewarrior (m_cu) || m_is_stmt;
 
@@ -19727,6 +19756,15 @@ lnp_state_machine::record_line (bool end_sequence)
 	    }
 	}
     }
+
+  /* Track whether we have seen any m_is_stmt true at m_address in case we
+     have multiple line table entries all at m_address.  */
+  if (m_last_address != m_address)
+    {
+      m_stmt_at_address = false;
+      m_last_address = m_address;
+    }
+  m_stmt_at_address |= m_is_stmt;
 }
 
 lnp_state_machine::lnp_state_machine (struct dwarf2_cu *cu, gdbarch *arch,
@@ -19746,6 +19784,9 @@ lnp_state_machine::lnp_state_machine (struct dwarf2_cu *cu, gdbarch *arch,
   m_address = gdbarch_adjust_dwarf2_line (arch, 0, 0);
   m_is_stmt = lh->default_is_stmt;
   m_discriminator = 0;
+
+  m_last_address = m_address;
+  m_stmt_at_address = false;
 }
 
 void
diff --git a/gdb/testsuite/gdb.cp/step-and-next-inline.exp b/gdb/testsuite/gdb.cp/step-and-next-inline.exp
index 3733fa75570..a95e21194f9 100644
--- a/gdb/testsuite/gdb.cp/step-and-next-inline.exp
+++ b/gdb/testsuite/gdb.cp/step-and-next-inline.exp
@@ -24,6 +24,13 @@ if { ![supports_statement_frontiers] } {
 proc do_test { use_header } {
     global srcfile testfile
 
+    if { $use_header } {
+	# This test will not pass due to poor debug information
+	# generated by GCC (at least upto 10.x).  See
+	# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474
+	return
+    }
+
     set options {c++ debug nowarnings optimize=-O2\ -gstatement-frontiers}
     if { $use_header } {
 	lappend options additional_flags=-DUSE_NEXT_INLINE_H
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-header-1.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-1.exp
new file mode 100644
index 00000000000..0ba481ad4b7
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-1.exp
@@ -0,0 +1,159 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+# Setup a line table where:
+#
+# | Addr | File | Line | Stmt |
+# |------|------|------|------|
+# | 1    | 1    | 16   | Y    |
+# | 2    | 1    | 17   | Y    |
+# | 3    | 2    | 21   | Y    |
+# | 4    | 2    | 22   | Y    |
+# | 4    | 1    | 18   | N    |
+# | 5    | 2    | 23   | N    |
+# | 6    | 1    | 24   | Y    |
+# | 7    | 1    | END  | Y    |
+# |------|------|------|------|
+#
+# Places a brekpoint at file 2, line 22.  Previously GDB would discrad
+# the line table entry for this line due to switching files for the
+# file 1, line 18 non-statement line.  After patching however, GDB now
+# discards the file 1, line 18 entry instead, and the breakpoint at
+# line 22 should succeed.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    return 0
+}
+
+# The .c files use __attribute__.
+if [get_compiler_info] {
+    return -1
+}
+if !$gcc_compiled {
+    return 0
+}
+
+standard_testfile dw2-inline-header-lbls.c dw2-inline-header.S \
+    dw2-inline-header.c dw2-inline-header.h
+
+set build_options {nodebug optimize=-O1}
+
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+    global srcdir subdir srcfile srcfile3 srcfile4
+    global build_options
+    declare_labels lines_label callee_subprog_label
+
+    get_func_info main $build_options
+
+    cu {} {
+	compile_unit {
+	    {producer "gcc" }
+	    {language @DW_LANG_C}
+	    {name ${srcfile3}}
+	    {low_pc 0 addr}
+	    {stmt_list ${lines_label} DW_FORM_sec_offset}
+	} {
+	    callee_subprog_label: subprogram {
+		{external 1 flag}
+		{name callee}
+		{inline 3 data1}
+	    }
+	    subprogram {
+		{external 1 flag}
+		{name main}
+		{low_pc $main_start addr}
+		{high_pc "$main_start + $main_len" addr}
+	    } {
+		inlined_subroutine {
+		    {abstract_origin %$callee_subprog_label}
+		    {low_pc line_label_1 addr}
+		    {high_pc line_label_7 addr}
+		    {call_file 1 data1}
+		    {call_line 18 data1}
+		}
+	    }
+	}
+    }
+
+    lines {version 2 default_is_stmt 1} lines_label {
+	include_dir "${srcdir}/${subdir}"
+	file_name "$srcfile3" 1
+	file_name "$srcfile4" 1
+
+	program {
+	    {DW_LNE_set_address line_label_1}
+	    {DW_LNS_advance_line 15}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_2}
+	    {DW_LNS_advance_line 1}
+	    {DW_LNS_copy}
+
+	    {DW_LNS_set_file 2}
+	    {DW_LNE_set_address line_label_3}
+	    {DW_LNS_advance_line 4}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_4}
+	    {DW_LNS_advance_line 1}
+	    {DW_LNS_copy}
+
+	    {DW_LNS_advance_line -4}
+	    {DW_LNS_set_file 1}
+	    {DW_LNS_negate_stmt}
+	    {DW_LNS_copy}
+
+	    {DW_LNS_set_file 2}
+	    {DW_LNE_set_address line_label_5}
+	    {DW_LNS_advance_line 5}
+	    {DW_LNS_copy}
+
+	    {DW_LNS_negate_stmt}
+	    {DW_LNS_set_file 1}
+	    {DW_LNE_set_address line_label_6}
+	    {DW_LNS_advance_line 1}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_7}
+	    {DW_LNE_end_sequence}
+	}
+    }
+}
+
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+	  [list $srcfile $asm_file] $build_options] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+# Delete all breakpoints so that the output of "info breakpoints"
+# below will only contain a single breakpoint.
+delete_breakpoints
+
+# Place a breakpoint within the function in the header file.
+gdb_breakpoint "${srcfile4}:22"
+
+# Check that the breakpoint was placed where we expected.  It should
+# appear at the requested line.  When the bug in GDB was present the
+# breakpoint would be placed on one of the following lines instead.
+gdb_test "info breakpoints" \
+    ".* in callee at \[^\r\n\]+${srcfile4}:22\\y.*"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-header-2.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-2.exp
new file mode 100644
index 00000000000..b8ce88ce32e
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-2.exp
@@ -0,0 +1,182 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+# Setup a line table where:
+#
+# | Addr | File | Line | Stmt |
+# |------|------|------|------|
+# | 1    | 1    | 16   | Y    |
+# | 2    | 1    | 17   | Y    |
+# | 3    | 2    | 21   | Y    |
+# | 4    | 2    | 22   | Y    |
+# | 4    | 1    | 18   | N    |
+# | 5    | 1    | 19   | Y    |
+# | 6    | 1    | 20   | Y    |
+# | 7    | 1    | END  | Y    |
+# |------|------|------|------|
+#
+#
+# Place the first brekpoint at file 2, line 22 and a second breakpoint
+# at file 1, line 19.  A third breakpoint is placed at file 1, line
+# 18, but as this line table entry will have been discarded[1] the
+# third breakpoint will actually be placed at the same location as the
+# second breakpoint.
+#
+# [1] The entry for file 1, line 18 is discarded because it is at the
+# same address as the previous entry, but the previous entry is-stmt,
+# while line 18 is a non-stmt.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    return 0
+}
+
+# The .c files use __attribute__.
+if [get_compiler_info] {
+    return -1
+}
+if !$gcc_compiled {
+    return 0
+}
+
+standard_testfile dw2-inline-header-lbls.c dw2-inline-header.S \
+    dw2-inline-header.c dw2-inline-header.h
+
+set build_options {nodebug optimize=-O1}
+
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+    global srcdir subdir srcfile srcfile3 srcfile4
+    global build_options
+    declare_labels lines_label callee_subprog_label
+
+    get_func_info main $build_options
+
+    cu {} {
+	compile_unit {
+	    {producer "gcc" }
+	    {language @DW_LANG_C}
+	    {name ${srcfile3}}
+	    {low_pc 0 addr}
+	    {stmt_list ${lines_label} DW_FORM_sec_offset}
+	} {
+	    callee_subprog_label: subprogram {
+		{external 1 flag}
+		{name callee}
+		{inline 3 data1}
+	    }
+	    subprogram {
+		{external 1 flag}
+		{name main}
+		{low_pc $main_start addr}
+		{high_pc "$main_start + $main_len" addr}
+	    } {
+		inlined_subroutine {
+		    {abstract_origin %$callee_subprog_label}
+		    {low_pc line_label_1 addr}
+		    {high_pc line_label_7 addr}
+		    {call_file 1 data1}
+		    {call_line 18 data1}
+		}
+	    }
+	}
+    }
+
+    lines {version 2 default_is_stmt 1} lines_label {
+	include_dir "${srcdir}/${subdir}"
+	file_name "$srcfile3" 1
+	file_name "$srcfile4" 1
+
+	program {
+	    {DW_LNE_set_address line_label_1}
+	    {DW_LNS_advance_line 15}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_2}
+	    {DW_LNS_advance_line 1}
+	    {DW_LNS_copy}
+
+	    {DW_LNS_set_file 2}
+	    {DW_LNE_set_address line_label_3}
+	    {DW_LNS_advance_line 4}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_4}
+	    {DW_LNS_advance_line 1}
+	    {DW_LNS_copy}
+
+	    {DW_LNS_advance_line -4}
+	    {DW_LNS_set_file 1}
+	    {DW_LNS_negate_stmt}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_5}
+	    {DW_LNS_advance_line 1}
+	    {DW_LNS_negate_stmt}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_6}
+	    {DW_LNS_advance_line 1}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_7}
+	    {DW_LNE_end_sequence}
+	}
+    }
+}
+
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+	  [list $srcfile $asm_file] $build_options] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+# Delete all breakpoints so that the output of "info breakpoints"
+# below will only contain a single breakpoint.
+delete_breakpoints
+
+# Place a breakpoint within the function in the header file.
+gdb_breakpoint "${srcfile4}:22"
+
+# Check that the breakpoint was placed where we expected.  It should
+# appear at the requested line.  When the bug in GDB was present the
+# breakpoint would be placed on one of the following lines instead.
+gdb_test "info breakpoints" \
+    ".* in callee at \[^\r\n\]+${srcfile4}:22\\y.*" \
+    "check for breakpoint at ${srcfile4}"
+
+# Delete all breakpoints so that the output of "info breakpoints"
+# below will only contain a single breakpoint.
+delete_breakpoints
+
+# Place a breakpoint within the function in the header file.
+gdb_breakpoint "${srcfile3}:19"
+
+# Check that the breakpoint was placed where we expected.  It should
+# appear at the requested line.  When the bug in GDB was present the
+# breakpoint would be placed on one of the following lines instead.
+gdb_test "info breakpoints" \
+    ".* in callee at \[^\r\n\]+${srcfile3}:19\\y.*" \
+    "check for breakpoint at ${srcfile3}"
+
+# Line table entry for line 18 will have been discarded, so this
+# brekpoint will be at the same location as line 19.
+gdb_test "break ${srcfile3}:18" \
+    "Note: breakpoint $decimal also set at pc $hex.*"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-header-3.exp b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-3.exp
new file mode 100644
index 00000000000..a2a2dfd07bd
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-3.exp
@@ -0,0 +1,193 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+# Setup a line table where:
+#
+# | Addr | File | Line | Stmt |
+# |------|------|------|------|
+# | 1    | 1    | 16   | Y    |
+# | 2    | 1    | 17   | Y    |
+# | 3    | 2    | 21   | Y    |
+# | 4    | 2    | 22   | Y    |
+# | 4    | 1    | 18   | N    |
+# | 5    | 1    | 19   | N    |
+# | 6    | 1    | 20   | Y    |
+# | 7    | 1    | END  | Y    |
+# |------|------|------|------|
+#
+# Break at file 2, line 22, then single instruction step forward.  We
+# should pass through line 19 and then encounter line 20.
+#
+# Currently we don't expect GDB to see file 1, line 18, as this is a
+# non-stmt line in a different file at the same address as the
+# previous is-stmt line.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+    return 0
+}
+
+# The .c files use __attribute__.
+if [get_compiler_info] {
+    return -1
+}
+if !$gcc_compiled {
+    return 0
+}
+
+standard_testfile dw2-inline-header-lbls.c dw2-inline-header.S \
+    dw2-inline-header.c dw2-inline-header.h
+
+set build_options {nodebug optimize=-O1}
+
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+    global srcdir subdir srcfile srcfile3 srcfile4
+    global build_options
+    declare_labels lines_label callee_subprog_label
+
+    get_func_info main $build_options
+
+    cu {} {
+	compile_unit {
+	    {producer "gcc" }
+	    {language @DW_LANG_C}
+	    {name ${srcfile3}}
+	    {low_pc 0 addr}
+	    {stmt_list ${lines_label} DW_FORM_sec_offset}
+	} {
+	    callee_subprog_label: subprogram {
+		{external 1 flag}
+		{name callee}
+		{inline 3 data1}
+	    }
+	    subprogram {
+		{external 1 flag}
+		{name main}
+		{low_pc $main_start addr}
+		{high_pc "$main_start + $main_len" addr}
+	    } {
+		inlined_subroutine {
+		    {abstract_origin %$callee_subprog_label}
+		    {low_pc line_label_1 addr}
+		    {high_pc line_label_7 addr}
+		    {call_file 1 data1}
+		    {call_line 18 data1}
+		}
+	    }
+	}
+    }
+
+    lines {version 2 default_is_stmt 1} lines_label {
+	include_dir "${srcdir}/${subdir}"
+	file_name "$srcfile3" 1
+	file_name "$srcfile4" 1
+
+	program {
+	    {DW_LNE_set_address line_label_1}
+	    {DW_LNS_advance_line 15}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_2}
+	    {DW_LNS_advance_line 1}
+	    {DW_LNS_copy}
+
+	    {DW_LNS_set_file 2}
+	    {DW_LNE_set_address line_label_3}
+	    {DW_LNS_advance_line 4}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_4}
+	    {DW_LNS_advance_line 1}
+	    {DW_LNS_copy}
+
+	    {DW_LNS_advance_line -4}
+	    {DW_LNS_set_file 1}
+	    {DW_LNS_negate_stmt}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_5}
+	    {DW_LNS_advance_line 1}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_6}
+	    {DW_LNS_advance_line 1}
+	    {DW_LNS_negate_stmt}
+	    {DW_LNS_copy}
+
+	    {DW_LNE_set_address line_label_7}
+	    {DW_LNE_end_sequence}
+	}
+    }
+}
+
+if { [prepare_for_testing "failed to prepare" ${testfile} \
+	  [list $srcfile $asm_file] $build_options] } {
+    return -1
+}
+
+if ![runto_main] {
+    return -1
+}
+
+# Delete all breakpoints so that the output of "info breakpoints"
+# below will only contain a single breakpoint.
+delete_breakpoints
+
+# Place a breakpoint within the function in the header file.
+gdb_breakpoint "${srcfile4}:22"
+
+# Check that the breakpoint was placed where we expected.  It should
+# appear at the requested line.  When the bug in GDB was present the
+# breakpoint would be placed on one of the following lines instead.
+gdb_test "info breakpoints" \
+    ".* in callee at \[^\r\n\]+${srcfile4}:22\\y.*"
+
+gdb_continue_to_breakpoint "${srcfile4}:22" \
+    ".* ${srcfile4} : 22 .*"
+
+# Now single instruction step forward.  Eventually we should hit
+# ${srcfile3}:20, but before we do we should hit the non-statement
+# line ${srcfile3}:19.
+#
+# We don't know how many instructions we'll need to step, but 100
+# should be enough for everyone (surely), and this stops us looping
+# forever if something goes wrong.
+set found_line_19 0
+set found_line_20 0
+set keep_going 1
+for { set i 0 } { $i < 100 && $keep_going } { incr i } {
+    set keep_going 0
+    gdb_test_multiple "stepi" "stepi ${i}" {
+	-re "${srcfile3} : 19 .*${gdb_prompt} " {
+	    set found_line_19 1
+	    set keep_going 1
+	}
+
+	-re "${srcfile3} : 20 .*${gdb_prompt} " {
+	    set found_line_20 1
+	}
+
+	-re "${srcfile4} : 22 .*${gdb_prompt} " {
+	    # Not left line 22 yet.
+	    set keep_going 1
+	}
+    }
+}
+
+gdb_assert { $found_line_19 && $found_line_20 } \
+    "found line 19 and 20"
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-header-lbls.c b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-lbls.c
new file mode 100644
index 00000000000..a1b7b17cbeb
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-lbls.c
@@ -0,0 +1,46 @@
+/* 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 <http://www.gnu.org/licenses/>.  */
+
+/* Used to insert labels with which we can build a fake line table.  */
+#define LL(N) asm ("line_label_" #N ": .globl line_label_" #N)
+
+volatile int var;
+volatile int bar;
+
+/* Generate some code to take up some space.  */
+#define FILLER do { \
+    var = 99;	    \
+} while (0)
+
+int
+main ()
+{					/* main prologue */
+  asm ("main_label: .globl main_label");
+  LL (1);	// F1, Ln 16
+  FILLER;
+  LL (2);	// F1, Ln 17
+  FILLER;
+  LL (3);	// F2, Ln 21
+  FILLER;
+  LL (4);	// F2, Ln 22 // F1, Ln 18, !S
+  FILLER;
+  LL (5);	// F1, Ln 19 !S
+  FILLER;
+  LL (6);	// F1, Ln 20
+  FILLER;
+  LL (7);
+  FILLER;
+  return 0;				/* main end */
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-header.c b/gdb/testsuite/gdb.dwarf2/dw2-inline-header.c
new file mode 100644
index 00000000000..a8331268a09
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header.c
@@ -0,0 +1,24 @@
+/* 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 <http://www.gnu.org/licenses/>.  */
+
+/* dw2-inline-header.c : 16 */
+/* dw2-inline-header.c : 17 */
+/* dw2-inline-header.c : 18 */
+/* dw2-inline-header.c : 19 */
+/* dw2-inline-header.c : 20 */
+/* dw2-inline-header.c : 21 */
+/* dw2-inline-header.c : 22 */
+/* dw2-inline-header.c : 23 */
+/* dw2-inline-header.c : 24 */
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-inline-header.h b/gdb/testsuite/gdb.dwarf2/dw2-inline-header.h
new file mode 100644
index 00000000000..7233acbcd76
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header.h
@@ -0,0 +1,24 @@
+/* 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 <http://www.gnu.org/licenses/>.  */
+
+/* dw2-inline-header.h : 16 */
+/* dw2-inline-header.h : 17 */
+/* dw2-inline-header.h : 18 */
+/* dw2-inline-header.h : 19 */
+/* dw2-inline-header.h : 20 */
+/* dw2-inline-header.h : 21 */
+/* dw2-inline-header.h : 22 */
+/* dw2-inline-header.h : 23 */
+/* dw2-inline-header.h : 24 */

  parent reply	other threads:[~2020-04-16 17:18 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-05 11:37 [PATCH 0/2] Line table is_stmt support Andrew Burgess
2020-02-05 11:37 ` [PATCH 2/2] gdb: Add support for tracking the DWARF line table is-stmt field Andrew Burgess
2020-02-05 17:55   ` Bernd Edlinger
2020-02-10 18:30     ` Bernd Edlinger
2020-02-11 13:57     ` Andrew Burgess
2020-02-14 20:05       ` Bernd Edlinger
2020-03-05 18:01         ` Bernd Edlinger
2020-03-08 12:50           ` [PATCHv2 0/2] Line table is_stmt support Andrew Burgess
2020-03-08 14:39             ` Bernd Edlinger
2020-03-10 23:01               ` Andrew Burgess
2020-03-11  6:50                 ` Simon Marchi
2020-03-11 11:28                   ` Andrew Burgess
2020-03-11 13:27                     ` Simon Marchi
2020-04-03 22:21             ` [PATCH 0/2] More regression fixing from is-stmt patches Andrew Burgess
2020-04-03 22:21             ` [PATCH 1/2] gdb/testsuite: Move helper function into lib/dwarf.exp Andrew Burgess
2020-04-06 20:18               ` Tom Tromey
2020-04-14 11:18                 ` Andrew Burgess
2020-04-03 22:21             ` [PATCH 2/2] gdb: Preserve is-stmt lines when switch between files Andrew Burgess
2020-04-04 18:07               ` Bernd Edlinger
2020-04-04 19:59                 ` Bernd Edlinger
2020-04-04 22:23                 ` Andrew Burgess
2020-04-05  0:04                   ` Bernd Edlinger
2020-04-05  0:47                   ` Bernd Edlinger
2020-04-05  8:55                   ` Bernd Edlinger
2020-04-11  3:52               ` Bernd Edlinger
2020-04-12 17:13                 ` Bernd Edlinger
2020-04-14 11:28                   ` Andrew Burgess
2020-04-14 11:37                     ` Bernd Edlinger
2020-04-14 11:41                       ` Bernd Edlinger
2020-04-14 13:08                       ` Andrew Burgess
2020-04-16 17:18                     ` Andrew Burgess [this message]
2020-04-22 21:13                       ` Tom Tromey
2020-04-25  7:06                         ` Bernd Edlinger
2020-04-27 10:34                           ` Andrew Burgess
2020-05-14 20:18                             ` Tom Tromey
2020-05-14 22:39                               ` Andrew Burgess
2020-05-15  3:35                                 ` Bernd Edlinger
2020-05-15 14:46                                   ` Andrew Burgess
2020-05-16  8:12                                     ` Bernd Edlinger
2020-05-17 17:26                                   ` Bernd Edlinger
2020-05-20 18:26                                   ` Andrew Burgess
2020-05-27 13:10                                     ` Andrew Burgess
2020-06-01  9:05                                       ` Andrew Burgess
2020-03-08 12:50           ` [PATCHv2 1/2] gdb/testsuite: Add is-stmt support to the DWARF compiler Andrew Burgess
2020-03-08 12:50           ` [PATCHv2 2/2] gdb: Add support for tracking the DWARF line table is-stmt field Andrew Burgess
2020-03-16 20:57             ` Tom Tromey
2020-03-16 22:37               ` Bernd Edlinger
2020-03-17 12:47               ` Tom Tromey
2020-03-17 18:23                 ` Tom Tromey
2020-03-17 18:51                   ` Bernd Edlinger
2020-03-17 18:56                   ` Andrew Burgess
2020-03-17 20:18                     ` Tom Tromey
2020-03-17 22:21                       ` Andrew Burgess
2020-03-23 17:30             ` [PATCH 0/3] Keep duplicate line table entries Andrew Burgess
2020-03-23 17:30             ` [PATCH 1/3] gdb/testsuite: Add compiler options parameter to function_range helper Andrew Burgess
2020-04-01 18:31               ` Tom Tromey
2020-03-23 17:30             ` [PATCH 2/3] gdb/testsuite: Add support for DW_LNS_set_file to DWARF compiler Andrew Burgess
2020-04-01 18:32               ` Tom Tromey
2020-03-23 17:30             ` [PATCH 3/3] gdb: Don't remove duplicate entries from the line table Andrew Burgess
2020-04-01 18:34               ` Tom Tromey
2020-06-01 13:26           ` [PATCH 2/2] gdb: Add support for tracking the DWARF line table is-stmt field Pedro Alves
2020-02-06  9:01   ` Luis Machado
2020-02-11 15:39     ` Andrew Burgess
2020-02-09 21:07   ` [PATCH] Fix range end handling of inlined subroutines Bernd Edlinger
2020-02-10 21:48     ` Andrew Burgess
2020-02-22  6:39     ` [PATCHv2] " Bernd Edlinger
2020-03-08 14:57       ` [PATCHv3] " Bernd Edlinger
2020-03-11 22:02         ` Andrew Burgess
2020-03-12 18:21           ` Bernd Edlinger
2020-03-12 18:27             ` Christian Biesinger
2020-03-13  8:03               ` Bernd Edlinger
2020-03-17 22:27                 ` Andrew Burgess
2020-03-19  1:33                   ` Bernd Edlinger
2020-03-21 20:31                     ` Bernd Edlinger
2020-03-23 17:53                       ` Andrew Burgess
2020-03-23 20:58                         ` Bernd Edlinger
2020-06-01 14:28                           ` Pedro Alves
2020-03-13 12:47         ` [PATCHv4] " Bernd Edlinger
2020-02-05 11:37 ` [PATCH 1/2] gdb/testsuite: Add is-stmt support to the DWARF compiler Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200416171809.GJ2366@embecosm.com \
    --to=andrew.burgess@embecosm.com \
    --cc=bernd.edlinger@hotmail.de \
    --cc=gdb-patches@sourceware.org \
    --cc=tom@tromey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).