From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-oln040092065019.outbound.protection.outlook.com [40.92.65.19]) by sourceware.org (Postfix) with ESMTPS id 87D59385DC00 for ; Sun, 5 Apr 2020 00:04:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 87D59385DC00 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=Djte8ZZcpvVz+Pn83oHuZG8BoWIQadu3wFI/cv8ExDS256MYQWzfuD8MfqOCv7nHQcCfiR1rVWINeVBK1tdwqR3qiyDaBjsRNDaMCQ6JMYNrlo3BI3vxkDB97OcBo9LdYDbCoBaZoEhCPcDSmDwTMItkpV8H1Lz4B3e2/3qCoQugBP8t17DPsVWXX5B7iF1wWj5in30M+TSQveMfIr9MJvz6pEli+BbatOffOTpBcJI19qbZwjNLVkmBCYO44e1ylrNtaivS4ibNfz/l7/ibpR0xm0fPKP3ZpMapEkmtv38GXTGfucSJzAPv0+JDgaMv7gtubct6jTDPV7WYbpZtPg== 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=HnCuXqr31/4Y7mpwdEv2L+6tuWQfSHn8uZGsA2OG8os=; b=cqiXt4jEih/6o2KUfTG6qrzQu1aG/muMIBB0aptvNkm2PY5SGdHpkO+LmdgnP3tj/xnxTeYJs8mrKoarZqi7sLRuyDryOPHiqvCfPTsraIEq+8eMca7IFb4evLIJswlcf6NBI4OEtOGROFbqPQv9SaBIcIzJxseIoWDoeddQATscNy/1V59+LENMS+GuJdxQwfT0WCY+kLhPux/OzsdO7mcCAx8aR0TMoasZI3mY//9HMxhfRdAj8ZdwqXzbJn1ztfXN7Lx7hbLvVvRMUvq1B3YPp03daIo0uzDLXWCypmfBzS5FazzuLBIk4ILlFG3swKPo5iLpkO153H6kcrZUuw== 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 DB5EUR01FT059.eop-EUR01.prod.protection.outlook.com (2a01:111:e400:7e1a::45) by DB5EUR01HT033.eop-EUR01.prod.protection.outlook.com (2a01:111:e400:7e1a::411) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2878.15; Sun, 5 Apr 2020 00:04:36 +0000 Received: from AM6PR03MB5170.eurprd03.prod.outlook.com (2a01:111:e400:7e1a::44) by DB5EUR01FT059.mail.protection.outlook.com (2a01:111:e400:7e1a::164) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2878.15 via Frontend Transport; Sun, 5 Apr 2020 00:04:36 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:3B64E34D6A96B74248055E443D61C13773BF0975447D7BD60546528F33A88892; UpperCasedChecksum:69CBFBDF10F83F55390F8A038BC6A7E727D119197E7E915E680DF473583AADCB; SizeAsReceived:8247; 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.2878.018; Sun, 5 Apr 2020 00:04:36 +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> <20200404222326.GB3917@embecosm.com> From: Bernd Edlinger Message-ID: Date: Sun, 5 Apr 2020 02:04:34 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 In-Reply-To: <20200404222326.GB3917@embecosm.com> Content-Type: text/plain; charset=windows-1252 Content-Language: en-US Content-Transfer-Encoding: 7bit X-ClientProxiedBy: AM0PR0102CA0045.eurprd01.prod.exchangelabs.com (2603:10a6:208::22) To AM6PR03MB5170.eurprd03.prod.outlook.com (2603:10a6:20b:ca::23) X-Microsoft-Original-Message-ID: <4ab203d5-0291-1032-afe9-dc58100ac735@hotmail.de> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from [192.168.1.101] (92.77.140.102) by AM0PR0102CA0045.eurprd01.prod.exchangelabs.com (2603:10a6:208::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2878.15 via Frontend Transport; Sun, 5 Apr 2020 00:04:35 +0000 X-Microsoft-Original-Message-ID: <4ab203d5-0291-1032-afe9-dc58100ac735@hotmail.de> X-TMN: [Uic8AK2PP79KNmhqD4itFnGeXbKrfy/u] X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 50 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: 88465b8d-6960-438a-3de6-08d7d8f4ed00 X-MS-TrafficTypeDiagnostic: DB5EUR01HT033: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ZC8yQeaC+8lMPekLDyZAsNDhoiT+dh8Xm0FA7b9mGx6MjHxykqQxCDGPSMF08wljsbTHO1CoBJgZZIUlyY8qn45hUJ/bEltCMepgfMsvwgfsSMBo8ZIj0kcSAV7NBW7Qio3ybIJ/w90U729Jo5xpmSlYmL85nxbvBqjco8wHHhmFjbw4WuHF5EJNompBSbG/rKkUDlDDPIcdYwEwh6eOiPt85nH0mXiG6hTssvyrBd4= 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: q/2ewYTJzz/dNRVm2UfOV+pyUq5qb9rORC1IHh4ednaeAxr6HUuB3z2giZZjmoznOfP4sou+0emP/j5G2bqw1YxBb1FEX4FwqOYZu16D7q6Ts6TQf05Dzze1mPCbnfXMKHYQ/dzfOZVnDDAr3DlP0Q== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 88465b8d-6960-438a-3de6-08d7d8f4ed00 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Apr 2020 00:04:36.2026 (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: DB5EUR01HT033 X-Spam-Status: No, score=-17.2 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: Sun, 05 Apr 2020 00:04:42 -0000 On 4/5/20 12:23 AM, Andrew Burgess wrote: > * 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. > DWARF is broken by design, I said that already. But I think there is no reason why the test case cannot work. Maybe I overlooked something, but that is what I think in the moment. > 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. > In the moment, my approach is leave GCC as is, and teach GDB to make as much sense as possible out of the DWARF info as it is, we have a lot of backward compatibility to maintain. Even if the DWARF is eventually fixed it must be a new dwarf revision v6 or so. Bernd. > 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 */ >>>