[llvm-bugs] [Bug 48790] New: [DebugInfo] Malformed DWARF produced during LTO build
via llvm-bugs
llvm-bugs at lists.llvm.org
Mon Jan 18 09:39:17 PST 2021
https://bugs.llvm.org/show_bug.cgi?id=48790
Bug ID: 48790
Summary: [DebugInfo] Malformed DWARF produced during LTO build
Product: libraries
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Keywords: wrong-debug
Severity: release blocker
Priority: P
Component: Common Code Generator Code
Assignee: unassignedbugs at nondot.org
Reporter: jeremy.morse.llvm at gmail.com
CC: aprantl at apple.com, dblaikie at gmail.com,
greg.bedwell at sony.com, jdevlieghere at apple.com,
llvm-bugs at lists.llvm.org, paul.robinson at am.sony.com,
vsk at apple.com
The reproducer below causes LLVM master (93592b726c7) to produce malformed
DWARF when built with "-O3 -g -flto". Running `llvm-dwarfdump -verify`
complains "invalid DIE reference", and our debugger becomes displeased.
Reverting e08f205f / D70350, "Allow cross-CU references of subprogram
definitions", fixes it for us.
Sources:
$ cat -n 1.cpp
1 struct HHH;
2
3 struct xxx {
4 HHH yyy();
5 } zzz;
6
$ cat -n 2.cpp
1 int ggg;
2
3 struct HHH {
4 template <typename bbb> int ccc(bbb) {
5 while (--ggg)
6 ;
7 }
8 };
9
10 void eee() {
11 HHH fff;
12 fff.ccc([] {});
13 }
14
Built thus (the target is important it seems):
$ clang++ -O3 -g -flto -w -c 1.cpp -o 1.o -target x86_64-scei-ps4
$ clang++ -O3 -g -flto -w -c 2.cpp -o 2.o -target x86_64-scei-ps4
$ ld.lld 1.o 2.o -o 3.out -r
$ llvm-dwarfdump -verify 3.out
Produces:
--------8<--------
error: invalid DIE reference 0x00000046. Offset is in between DIEs:
0x000000a1: DW_TAG_inlined_subroutine
DW_AT_abstract_origin (0x00000046)
DW_AT_low_pc (0x0000000000000000)
DW_AT_high_pc (0x0000000000000002)
DW_AT_call_file ("1.cpp")
DW_AT_call_line (12)
-------->8--------
I'm attaching an IR reproducer, derived from "ld.lld -save-temps" and the
combined-and-optimized IR it produces. Feeding that IR into llc also produces
an invalid DIE reference.
I've done some prodding, and while to me the DWARF emission code is a twisty
turny maze of passages all alike, I believe the problem is that the DIE for the
"eee" function is placed in the wrong compile unit. Here's a chain of events:
* The DIE for "HHH" is placed in the CU for 1.cpp, because the "zzz" global
var is emitted there.
* The DIE for "ccc" is created in the context of "HHH", CU is 1.cpp
* The template argument for "ccc", a lambda type, is created
* The scope for that template argument is needed: so a DIE "eee" is created.
* That DIE for "eee" is in the "current" unit, 1.cpp
Normally this wouldn't be a problem. I believe that at the end of
DwarfDebug::endFunctionImpl, normally a duplicate DIE would be created for
"eee", because a cross-CU subprogram wouldn't be permitted. However, with
e08f205f a cross-CU subprogram _is_ permitted.
All the child scopes of "eee" are created before "eee" is created, they expect
to be in the CU that the DISubprogram for "eee" specifies, 2.cpp, and they pick
references of form "DW_FORM_ref4". They're then attached to a subprogram DIE in
a different CU, breaking those forms of references. If you use llvm-dwarfdump
-v, you can see that the offset of the DW_AT_abstract_origin above would be
correct, if it was in the correct CU (hat-tip James Henderson).
I don't really have a proposal for how to fix this right now, DWARF emission is
way out of my comfort zone.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210118/e19c98de/attachment-0001.html>
More information about the llvm-bugs
mailing list