From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 70770385BF81; Sun, 17 May 2020 08:43:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 70770385BF81 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1589705011; bh=PSSCE0cdMcgciSC9dHPpYRtt4n4cY4gO+ELggVCOBNU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=u1V3vEvozN85F0cZTesym4Ur6XZc4sNvhhTNUmewm1C9nwxI8BgEOAoO9gIoRxokI Z4M3SPU5Un/MjEAlEf+XydAOJVgwV7So22YZPtDMCKy/+HHrwMmG8NITfVl4sGeIeE cyLG7SeAhE/5ymECcQfMcaGULJSL8uAdnKuquO64= From: "andrew.burgess at embecosm dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug debug/94474] Incorrect DWARF range information for inlined function Date: Sun, 17 May 2020 08:43:31 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: debug X-Bugzilla-Version: 9.2.0 X-Bugzilla-Keywords: wrong-debug X-Bugzilla-Severity: normal X-Bugzilla-Who: andrew.burgess at embecosm dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 May 2020 08:43:31 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D94474 --- Comment #12 from Andrew Burgess --- > But what I learned from writing the patch is that gcc cannot > easily tell if a range will be empty or not. That is because > the assembler does emit the line info and the views, > and the assembler decides how many bytes if any a certain > construct will take in the binary representation. > > That is why this empty range appears, because that was > supposed to be the start of the inline function, but > instructions from the function prologue were moved in there. I think there's some miss-communication here. In the first paragraph you say the assembler is responsible for deciding the binary representation. I'd agree with that, in the GNU toolchain this is gas. Then in the second paragraph you say the assembler is performing instruction reordering. Now I don't know every gas optimisation, so I'm not saying gas doesn't do that, but it's not common, and it certainly isn't what's happening in this case. The instruction motion is entirely within GCC. I'll offer evidence for this below. > What causes the problem is the is-stmt line info which > is the only remaining thing from the original plan. And here in lies the GCC bug (or one of them). GCC has performed instruction motion, and GCC has left behind its marker for the is-stmt line. I make no claim about how easy this is to fix, or if (given GCC's code base) its even reasonably possible to consider fixing it, but that doesn't mean it isn't a GCC issue. > But on the other hand, it is not a big issue for gdb to > ignore those artefacts, when they rarely occur. GDB already ignores empty ranges. The DWARF standard specifically allows empty ranges and states that they are to be ignored. But that isn't the artefact you're talking about, you mean the is-stmt markers. The problem is, the markers are placed at an address, given that every address eventually contains an instruction[1] eventually, how can GDB tell if one marker was left by accident or not? > My gdb-patch does this, by changing the is-stmt bit of > this line info. Yes, and I think with this discussion we are getting closer to understanding the work around you want to introduce to GDB, something along the lines of: - On versions XXX -> YYY of GCC, - An is-stmt true marker, - At the same address as an empty range, that is - Associated with an inline function instance, should - Be ignored. It's this kind of specific identification of the bug you're working around that (for me at least) is holding back your GDB patch. But, we shouldn't make a choice between work around the GCC bug in GDB _or_ fix the bug in GCC. The ideal solution (for me) would be, fix GCC _and_ add a work around into GDB targeting the known broken versions of GCC, then we get the best of both worlds. --- To back up my claim that this is a GCC issue, you can generate the assembler file test-v3.s from the reproducer. The .debug_ranges looks like this: .section .debug_ranges,"",@progbits .Ldebug_ranges0: .quad .LFB21 .quad .LHOTE0 .quad .LFSB21 .quad .LCOLDE0 .quad 0 .quad 0 .quad .LBB8 .quad .LBE8 .quad .LBB12 .quad .LBE12 .quad .LBB17 .quad .LBE17 .quad 0 .quad 0 The empty range is the first range in the second sequence, so this one: .quad .LBB8 .quad .LBE8 If we then find this in the assembler we see: .LBB8: .LBI8: .file 2 "step-and-next-inline.h" .loc 2 32 1 is_stmt 1 view .LVU3 .LBB9: .loc 2 34 3 view .LVU4 .LBE9: .LBE8: .loc 1 50 1 is_stmt 0 view .LVU5 subq $8, %rsp .cfi_def_cfa_offset 16 Notice, no assembler instructions (but there are assembler directives) between LBB8 and LBE8. I agree 100% with your diagnosis that this is likely due to instruction reordering, but I disagree with your analysis that this is done in the assembler and that therefore GCC has no visibility of this. --- [1] I know, not _literally_ every address, but you get the point.=