From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x342.google.com (mail-wm1-x342.google.com [IPv6:2a00:1450:4864:20::342]) by sourceware.org (Postfix) with ESMTPS id 5DD17385BF83 for ; Tue, 14 Apr 2020 13:08:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 5DD17385BF83 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-x342.google.com with SMTP id x25so12915896wmc.0 for ; Tue, 14 Apr 2020 06:08:23 -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=4K//DW5ce0tqitJCNzxYSzg0cDbOGh2U8umQkOnHIMc=; b=LnV9J96Np1Xs4A7vvKEd2odAnfSMkXJQHORQ618gURigeMrLhIBSM+vN+coghNOKD/ sNiUF07Rr/fYdNjVWWigeG5FkFCF9+8yoWSFDCrkZtwa+vaQSwEfZjlxjw+fucAlIA1C erWnemgT+7WrHVFwcY3n6FuvtogVE6aNE2xEhWtpphUzGECxTCjmidzivAclkVJ3dR1v j4lsnRqhUryRI6/sm1BNg5UDufpv/Mk7++Mo+qDaBUQ8BiYJRMTHiBPbBJWcyH2F8nxl PUUS6lIhWYFpFJU6ZDJciglZYPgM9Zub3sJwBvZDeUI+cIqP2crWHN6/2ncNM77u8tEg cx1g== 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=4K//DW5ce0tqitJCNzxYSzg0cDbOGh2U8umQkOnHIMc=; b=L3P45JtshgbnBtwQHVcZrB0EqnWgg4Ohm2A9I/oTWiSwmI94MbIRix8LyyMJhF6COc WmcxKw4TPW4WdTzTcoR+aqXq0UNd2aircYwbvqVMTzl8qbkMohwIUDukRhxbEb8Lo6QI Fn9wV1e3wGPrYydbHQTMEVMl+3DcIP5tguXxHYf1MsAqajjyhXJtiTLU1z8tRDAIiAPw sCiKtd3xoyl87hyFNDcB340ovyDINOBP3YPfGZlC4x1ZjoW08/9za1JbgkwN5AVQ1oSX ry+jWLHsTYyPi/GtesGKahi3MseZr6pmYpl75RrGSnNL4p///x88cmPWE9OP4Tk1XoHd sN0A== X-Gm-Message-State: AGi0PuaSBarrOSy3w4XaiZ2aeYLQlxVD71wTcs27u6bEnYRX+DmHP0w7 +XLUo+Olqc868NVhdbhP4RNapg== X-Google-Smtp-Source: APiQypLAfwGEFeoHGHYW0cHj4aQbWH9aRuwy/J32my7KaZZOb6i8q8trJDlwLqWXkS/Uj894MkQSnA== X-Received: by 2002:a05:600c:224a:: with SMTP id a10mr24448941wmm.174.1586869701901; Tue, 14 Apr 2020 06:08:21 -0700 (PDT) Received: from localhost (host81-151-181-184.range81-151.btcentralplus.com. [81.151.181.184]) by smtp.gmail.com with ESMTPSA id 132sm19283828wmc.47.2020.04.14.06.08.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Apr 2020 06:08:20 -0700 (PDT) Date: Tue, 14 Apr 2020 14:08:19 +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: <20200414130819.GF2366@embecosm.com> References: <6e9b21a0002164cec014dfe4d94d816a376989b4.1585952198.git.andrew.burgess@embecosm.com> <20200414112841.GC2366@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: 14:02:46 up 6 days, 4:17, X-Editor: GNU Emacs [ http://www.gnu.org/software/emacs ] X-Spam-Status: No, score=-24.4 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: Tue, 14 Apr 2020 13:08:27 -0000 * Bernd Edlinger [2020-04-14 13:37:56 +0200]: > > > On 4/14/20 1:28 PM, Andrew Burgess wrote: > > Bernd, > > > > As requested, rebased version of this patch for your feedback. Sorry > > for the delay, I took a short break over Easter. > > > > Apologies for the previous build failure the fix you found was the > > only issue, and was caused by a last second choice to rename > > 'm_stmt_at_addr' to 'm_stmt_at_address', combined with me making a > > dumb mistake generating the patch from a slightly broken tree. Please > > be assured the patch was fully tested before I did the rename. > > > > The trailing blank lines I have no excuse for. > > > > Changes since previous version: > > > > - Rebase > > - Fix m_stmt_at_addr typo > > - Delete some trailing blank lines. > > > > I look forward to hearing your thoughts. > > > > Did you look at fixing the subrouting ranges. > My patch depends entirely on correct range info. > > It is probably not very difficult for you to fix. I think you're referring here to the invalid range information produced by GCC, but maybe I'm wrong and you mean something else? If you are talking about the invalid ranges, as produced in gdb.cp/step-and-next-inline.exp, then no, I haven't tried to fix this as I don't think we can. Unless we can show that GCC is always wrong, and always wrong in the same say then I don't see how we can know that GCC has cut a range short. That's why I raised GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94474 with the hope that we'd get some clarity from the GCC maintainers. I did hack GDB to "fix" the ranges, but this was done using fixed addresses, basically, "if (range_end == 0x......) range_end = 0x......", which obviously isn't a real fix, but did show me that iff GCC got the range information correct, then the test would basically pass just fine. Let me know if you were actually referencing something else. Thanks Andrew > > > Thanks > Bernd. > > > Thanks, > > Andrew > > > > --- > > > > commit cf4bab4672356e190b166e063d2539ddad5eb542 > > Author: Andrew Burgess > > 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) : 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. > > > > 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..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..161a1fc2aea > > --- /dev/null > > +++ b/gdb/testsuite/gdb.dwarf2/dw2-inline-header-3.exp > > @@ -0,0 +1,190 @@ > > +# 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 */ > >