<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 - Stack walk metadata lost or altered by lld-link"
href="https://bugs.llvm.org/show_bug.cgi?id=38847">38847</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Stack walk metadata lost or altered by lld-link
</td>
</tr>
<tr>
<th>Product</th>
<td>lld
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Windows NT
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>COFF
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>brucedawson@chromium.org
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=20845" name="attach_20845" title="Source and batch files for reproducing the bug">attachment 20845</a> <a href="attachment.cgi?id=20845&action=edit" title="Source and batch files for reproducing the bug">[details]</a></span>
Source and batch files for reproducing the bug
When a 32-bit executable that is statically linked with the CRT crashes inside
of memcpy then the stack walking may or may not succeed, depending on whether
the binary was linked with lld-link or with VC++'s link. This was first
observed in Chrome in crbug.com/864351 but has also been reproduced in a
minimal scenario. It looks like memcpy contains custom metadata or some other
attribute which is preserved by link.exe but not by lld-link.exe. I am using
LLD 7.0.0.
In the minimal test case main() calls ChildFunction() (tagged as noinline)
which then calls memcpy in order to cause a crash. When linked with link.exe
the call stack is correct:
Output from debugging link.exe version:
0:000> kc
00 memcpy_stackwalk!memcpy
01 memcpy_stackwalk!ChildFunction
02 memcpy_stackwalk!main
Output from debugging lld-link.exe version:
0:000> kc
00 memcpy_stackwalk!TrailingDownVec
01 memcpy_stackwalk!main
Examining the stack shows that the ChildFunction return address is on the
stack:
0:000> dps esp
00bbfc08 01259c38 memcpy_stackwalk!__argc
00bbfc0c 033e6050
00bbfc10 0121105a memcpy_stackwalk!ChildFunction+0x5a
[C:\src\code\repros\memcpy_stackwalk\memcpy_stackwalk.cpp @ 17]
00bbfc14 90001000
00bbfc18 00a50000
00bbfc1c 00000098
00bbfc20 00000004
00bbfc24 00000000
00bbfc28 00a50000
00bbfc2c 90001000
00bbfc30 00bbfc38
00bbfc34 01211072 memcpy_stackwalk!main+0x12
[C:\src\code\repros\memcpy_stackwalk\memcpy_stackwalk.cpp @ 25]
Examining the assembly language also confirms that ChildFunction() is not
inlined or tail-call optimized. It is not a compiler bug because the
compilation is unchanged between the two tests. The only thing that changes is
the linker. This behavior (changing nothing but the linker) was also reproduced
in Chrome with the same results.
The test program is trivial. The source and the two batch files for building it
are attached.
#include <Windows.h>
int copy_amount = 0x98;
// Make sure this function isn't inlined.
void __declspec(noinline) ChildFunction() {
char* dst = (char*)0x90001000;
const char* src = (const char*)VirtualAlloc(nullptr, 4096, MEM_COMMIT |
MEM_RESERVE, PAGE_READWRITE);
memcpy(dst, src, copy_amount);
}
int main() {
ChildFunction();
}
The build.bat batch file for lld-link is shown below. The link.exe one is
identical except for the linker command invoked.
@setlocal
del memcpy_stackwalk.obj
del memcpy_stackwalk.exe
call "C:\Program Files (x86)\Microsoft Visual
Studio\2017\Professional\VC\Auxiliary\Build\vcvarsall.bat" x86
set path=c:\src\chromium3\src\third_party\llvm-build\Release+Asserts\bin;%path%
clang-cl /Z7 /c -m32 memcpy_stackwalk.cpp
lld-link /DEBUG memcpy_stackwalk.obj</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>