From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05olkn2109.outbound.protection.outlook.com [40.92.90.109]) by sourceware.org (Postfix) with ESMTPS id 6C10F385BF83 for ; Tue, 14 Apr 2020 11:38:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 6C10F385BF83 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=hotmail.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=bernd.edlinger@hotmail.de ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=T74KT0/GMfww/vX0uJH1ob/35QSQzC9LR9nx70lwJsSVvbLAEPXygN6rqMPLuckcf9CqaykrJJF+3zcuXKNXy46Pae9DeSIjxTTJ3kPcTMJtSQlDIRLoIwq9lH/dkNHQG6Rx4c6xnt1lSeNon61PdvgRpNwM1vCq5xRt+bXf8qlKbeMOG3yKU9JYuu0pkbv7W6DFJrSou0mX6s7VdgYEiaDS23p/O1GzT+G28N/3ZJrZmIfyuiiesXIEF6UqXYBknUCdQLX8vS68M6KSh2IfsBXg8s2IjrwHjYQBiHUWNQ3OMMWeszCsVxE+qfFFrhypfo4e6Nxi7HVi0eWpokaiwg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=MV2ZbBKuQedYYZsVbk0kqBOZ3sDOeZoUMLvMgt2EJ3k=; b=QY6SZC4iwjp5j8Agkk/1KRbGwqPFHaJhJ7XE1F0KYV3EXopynhKXo+h7/aWJZ073Ic9TINS2l36AwDLsrtUdO5nh2ihHPoo2Xox6pBly5SPHWts/IOdTyfetEAxy0og1VecDdfOGvfGBd8WstZInoRfOd4EqzJ05CyBM+6zh/v8zL/Z/4rBScCxl8rr52I+JdfVtgitKXmEbvAXYqVGoUXaCPgfYRizokrCfFh6Ue4GBnfkHvqNvf1TyV05Bp/CMiNSvhgs2z7HIlCnLpGUuE/gEvN8KO7c4B9jGv+NSOGkl8X/wETHHct+rqAGo7BnaL2e5Ri+rHnMpyHRbz4gXBg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=hotmail.de; dmarc=pass action=none header.from=hotmail.de; dkim=pass header.d=hotmail.de; arc=none Received: from VI1EUR05FT020.eop-eur05.prod.protection.outlook.com (2a01:111:e400:fc12::4b) by VI1EUR05HT016.eop-eur05.prod.protection.outlook.com (2a01:111:e400:fc12::449) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2900.18; Tue, 14 Apr 2020 11:38:00 +0000 Received: from AM6PR03MB5170.eurprd03.prod.outlook.com (2a01:111:e400:fc12::43) by VI1EUR05FT020.mail.protection.outlook.com (2a01:111:e400:fc12::192) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2900.15 via Frontend Transport; Tue, 14 Apr 2020 11:38:00 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:76BE8B04B9A346CBEABD44CBC0703250C5112F6FD0B71963311329BD8C6CDD2A; UpperCasedChecksum:1F0F4E936C9C447BB8C6919DC7DD48509F1445644A43C28B896DB8DC41AB382F; SizeAsReceived:8335; Count:50 Received: from AM6PR03MB5170.eurprd03.prod.outlook.com ([fe80::d57:5853:a396:969d]) by AM6PR03MB5170.eurprd03.prod.outlook.com ([fe80::d57:5853:a396:969d%7]) with mapi id 15.20.2900.028; Tue, 14 Apr 2020 11:38:00 +0000 Subject: Re: [PATCH 2/2] gdb: Preserve is-stmt lines when switch between files To: Andrew Burgess Cc: gdb-patches@sourceware.org, Tom Tromey References: <6e9b21a0002164cec014dfe4d94d816a376989b4.1585952198.git.andrew.burgess@embecosm.com> <20200414112841.GC2366@embecosm.com> From: Bernd Edlinger Message-ID: Date: Tue, 14 Apr 2020 13:37:56 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 In-Reply-To: <20200414112841.GC2366@embecosm.com> Content-Type: text/plain; charset=windows-1252 Content-Language: en-US Content-Transfer-Encoding: 7bit X-ClientProxiedBy: ZR0P278CA0021.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:1c::8) To AM6PR03MB5170.eurprd03.prod.outlook.com (2603:10a6:20b:ca::23) X-Microsoft-Original-Message-ID: <2c6fa2e8-9687-917d-8698-b8c2349eff0d@hotmail.de> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from [192.168.1.101] (84.57.47.218) by ZR0P278CA0021.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:1c::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2900.15 via Frontend Transport; Tue, 14 Apr 2020 11:37:59 +0000 X-Microsoft-Original-Message-ID: <2c6fa2e8-9687-917d-8698-b8c2349eff0d@hotmail.de> X-TMN: [CrjPHLjoUZfFHPJWBJTxwe21UR2kNVAp] X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 50 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: 775b2733-79bc-4b32-b772-08d7e06848b8 X-MS-TrafficTypeDiagnostic: VI1EUR05HT016: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: k1l/76bjQECwzcZkXJZ30r20j9H0vS7TP8zmecMsrcrRhoST+DAiL8QStfMOQFqbTvapxQYjPQe5sLvm2Nk2/TA6PdKMN891j/2Z0ig+imQAzXO3FC4VlIxOG9WoMWp+CU8dTbEEzvR8bBj9vo0wrrzxcAm0e7WQ0Xo2tdrDhxoH83+5iPke8UftWaK6NK0yttmxwHjsMDqT8msobScUO8tWZUw9gyBfGjBB6FAikHI= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:0; SRV:; IPV:NLI; SFV:NSPM; H:AM6PR03MB5170.eurprd03.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:; DIR:OUT; SFP:1901; X-MS-Exchange-AntiSpam-MessageData: UHwMXZjgARTQsdbyYA3YtHrxBqzyOVALPDvk0a7DIWP6rsr4WD4PnZF90/NLQhs5SKiqV/dWXuHemA+ahDQDsxqp//2xMC2WRI3Daq4ZFZ2GBBgwsOOu6GkzdYzoloTRxOMaMM141LowHdBFSoRsPA== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 775b2733-79bc-4b32-b772-08d7e06848b8 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 14 Apr 2020 11:38:00.5355 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1EUR05HT016 X-Spam-Status: No, score=-15.5 required=5.0 tests=BAYES_00, FORGED_MUA_MOZILLA, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_DMARC_STATUS, KAM_SHORT, MSGID_FROM_MTA_HEADER, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, 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 11:38:07 -0000 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. 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 */ >