From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x344.google.com (mail-wm1-x344.google.com [IPv6:2a00:1450:4864:20::344]) by sourceware.org (Postfix) with ESMTPS id 66752385DC2B for ; Sat, 4 Apr 2020 22:23:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 66752385DC2B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=andrew.burgess@embecosm.com Received: by mail-wm1-x344.google.com with SMTP id t128so10923207wma.0 for ; Sat, 04 Apr 2020 15:23:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=Hp0ZWoJIdNP5k96tEt1eKTz4p+wbf1n6Zx9uotJ+dAE=; b=L0b77ubjN8JQ7Gslwe+LPB7mCwQsSFEBYqrVKKGicsZp46AANgv6zTvHkiesUXQRZI zGRS5+nUfzs5SlMl4p1c+EcKRwtlfPgwlzVGulTzYXrJ/q1Med6V4IWGQFd1Rkv0elMe C5qLaUd1r9gX54Q9ANQc2Ac52+HwtLROwADcUv5E2/XYDYBSXgB49S4Mq08hpATHmUA9 dkJ8QzlcvM+DpvQn0icHlEDq+sF3qWTCwFzGP3P+hHFmO94DDKLqWdwQ8WyuR6L+M9AP v2gQda0JbUN00CJZmMLYyVlacRB128HzmKv/r1lc7+A4RWQpcRxIyeXPRrFy5eN42RAs wxqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=Hp0ZWoJIdNP5k96tEt1eKTz4p+wbf1n6Zx9uotJ+dAE=; b=tsrao3TGWSoHyk+JJl6ks59mjyC8kjVKRGSoRh0fOVLhaa+HNu9QkQTFow4r4QM2IP DJGpVhk6JSGxgunsttzr1OYJpXCHOCrEQOxKYQEUSUlkreuXApszqFlVr4ZYqCzf8NaU yF5DgC5XQ9DOECrsbgCNVxRUbAdRYdPzNrg4qHk3ufD896GPVYsZcElgz8g6BOSdIPv3 dDKJnBPWumi5t3nSLOxKwyJlaN+3wwxElUNzwLRqRKGJmu8kTZvT0hzNCkDaV6W00Cap mOd4aEIJSJldKZZ3iXGmZyOFy8iBEiUuEbt0WHzryU7HkcwXEV+bU+Sn8Tqu2wpvDmgF HCEw== X-Gm-Message-State: AGi0PuasIkVosGGZBVmVGJXL8xuLzsHNpw8ZnjK44pVSmaD9i+qj6UQd 37m4J8ee9rH9KmQ6ovjxPxqpgmL1XS0= X-Google-Smtp-Source: APiQypJ/F1bgAcsl9LdV7Fh4vWOroCJtLybhbln6GbDwKqICAevBqCcXwn1HVBeGns1tLQ0baJsuGA== X-Received: by 2002:a1c:1bc2:: with SMTP id b185mr14559842wmb.167.1586039008129; Sat, 04 Apr 2020 15:23:28 -0700 (PDT) Received: from localhost (host86-186-80-207.range86-186.btcentralplus.com. [86.186.80.207]) by smtp.gmail.com with ESMTPSA id e8sm10350088wrw.40.2020.04.04.15.23.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Apr 2020 15:23:27 -0700 (PDT) Date: Sat, 4 Apr 2020 23:23:26 +0100 From: Andrew Burgess To: Bernd Edlinger Cc: gdb-patches@sourceware.org, Tom Tromey Subject: Re: [PATCH 2/2] gdb: Preserve is-stmt lines when switch between files Message-ID: <20200404222326.GB3917@embecosm.com> References: <6e9b21a0002164cec014dfe4d94d816a376989b4.1585952198.git.andrew.burgess@embecosm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Operating-System: Linux/5.5.13-200.fc31.x86_64 (x86_64) X-Uptime: 23:10:08 up 6:14, 1 X-Editor: GNU Emacs [ http://www.gnu.org/software/emacs ] X-Spam-Status: No, score=-26.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 04 Apr 2020 22:23:33 -0000 * Bernd Edlinger [2020-04-04 20:07:52 +0200]: > Sorry, Andrew, > > please hold this one. > > This will definitely break all the step over inline > stuff that was already working. By all I assume you only mean gdb.cp/step-and-next-inline.exp, which I specifically talk about in the commit message. The DWARF produced in that test is horribly broken, I was tempted to drop the whole test, but a few parts do still work, and hopefully if GCC gets fixed we'll be back in business. As I mentioned in the GCC bug report, if I hack GDB to "fix" the DWARF produced by GCC, then that test passes fine with no regressions with this patch as is. All other tests still pass with this patch - admittedly there's not much testing the inline behaviour, but there are a few. If you know of a case with valid DWARF that is broken by this test then I'm all ears. With the setup I used for the tests in this patch it's actually pretty easy to synthesis test of inline functions, so all you really need to do is describe a test you think will break and I can knock up a test case for it reasonably quickly. > > Can we please go to the drawing board before we continue > from here? Sure. I posted my thoughts just now. Thanks, Andrew > > > Thanks > Bernd. > > On 4/4/20 12:21 AM, Andrew Burgess wrote: > > 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) : New > > member variable. > > : 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. > > --- > > gdb/ChangeLog | 10 ++ > > gdb/dwarf2/read.c | 47 +++++- > > gdb/testsuite/ChangeLog | 11 ++ > > gdb/testsuite/gdb.cp/step-and-next-inline.exp | 7 + > > gdb/testsuite/gdb.dwarf2/dw2-inline-header-1.exp | 156 ++++++++++++++++++ > > gdb/testsuite/gdb.dwarf2/dw2-inline-header-2.exp | 179 ++++++++++++++++++++ > > gdb/testsuite/gdb.dwarf2/dw2-inline-header-3.exp | 192 ++++++++++++++++++++++ > > gdb/testsuite/gdb.dwarf2/dw2-inline-header-lbls.c | 46 ++++++ > > gdb/testsuite/gdb.dwarf2/dw2-inline-header.c | 24 +++ > > gdb/testsuite/gdb.dwarf2/dw2-inline-header.h | 24 +++ > > 10 files changed, 693 insertions(+), 3 deletions(-) > > create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-inline-header-1.exp > > create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-inline-header-2.exp > > create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-inline-header-3.exp > > create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-inline-header-lbls.c > > create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-inline-header.c > > create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-inline-header.h > > > > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c > > index f94c66b4f1b..261c8455424 100644 > > --- a/gdb/dwarf2/read.c > > +++ b/gdb/dwarf2/read.c > > @@ -19327,6 +19327,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; > > > > @@ -19520,14 +19529,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; > > > > @@ -19546,6 +19575,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, > > @@ -19565,6 +19603,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_addr = 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..6a1e990002c > > --- /dev/null > > +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-1.exp > > @@ -0,0 +1,156 @@ > > +# 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 . > > + > > +# 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 asm_file [standard_output_file $srcfile2] > > +Dwarf::assemble $asm_file { > > + global srcdir subdir srcfile srcfile3 srcfile4 > > + declare_labels lines_label callee_subprog_label > > + > > + get_func_info main > > + > > + 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] {nodebug optimize=-O1}] } { > > + 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..46499919a8b > > --- /dev/null > > +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-2.exp > > @@ -0,0 +1,179 @@ > > +# 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 . > > + > > +# 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 asm_file [standard_output_file $srcfile2] > > +Dwarf::assemble $asm_file { > > + global srcdir subdir srcfile srcfile3 srcfile4 > > + declare_labels lines_label callee_subprog_label > > + > > + get_func_info main > > + > > + 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] {nodebug optimize=-O1}] } { > > + 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..c683dc4bb8a > > --- /dev/null > > +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-3.exp > > @@ -0,0 +1,192 @@ > > +# 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 . > > + > > +# 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 asm_file [standard_output_file $srcfile2] > > +Dwarf::assemble $asm_file { > > + global srcdir subdir srcfile srcfile3 srcfile4 > > + declare_labels lines_label callee_subprog_label > > + > > + get_func_info main > > + > > + 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] {nodebug optimize=-O1}] } { > > + 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 . */ > > + > > +/* 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 . */ > > + > > +/* 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 . */ > > + > > +/* 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 */ > >