<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - [DebugInfo] Malformed DWARF produced during LTO build"
href="https://bugs.llvm.org/show_bug.cgi?id=48790">48790</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>[DebugInfo] Malformed DWARF produced during LTO build
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Keywords</th>
<td>wrong-debug
</td>
</tr>
<tr>
<th>Severity</th>
<td>release blocker
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Common Code Generator Code
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>jeremy.morse.llvm@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>aprantl@apple.com, dblaikie@gmail.com, greg.bedwell@sony.com, jdevlieghere@apple.com, llvm-bugs@lists.llvm.org, paul.robinson@am.sony.com, vsk@apple.com
</td>
</tr></table>
<p>
<div>
<pre>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.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>