-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crash when using LLVM10 built with MSVC for x86-32 Debug #45521
Comments
Apologies for wonky formatting -- I didn't realize that Bugzilla doesn't support Markdown. Here is a slightly less bad version: (Reporting on behalf of Alex Reinking, who found this while debugging Halide:) OVERVIEW: There is an apparently 100% reproducible crash when using LLVM 10 build The crash appears due to a double-free in the destructor of SmallVector, The stack trace looks like:
In the debugger output window we see:
which looks a lot like it's trying to free a stack address. The 2nd argument is STEPS TO REPEAT: Note that Visual Studio 16.6.x (the latest) exposes a bug in LLVM that has Without vcpkgGet and compile LLVM:
With vcpkgCompile with:
Compiler info:
CMake info:
vcpkg list (only x86-windows is relevant):
|
Is there anyone with expertise in this area who could take a look? It's an obscure corner case, but it's one that our project would still like to support. |
Bumping this again. Can someone take a look and/or respond, please? |
I notice this code does
but every place in tree that does this has a '&' with the auto like this
getActionsDefinitionBuilder returns a reference but I think auto may not be deducing a reference so its making a copy of the builder. |
Craig, thanks for your response. Unfortunately, changing that line to read "auto&" instead of plain "auto" had no effect. This example was minimized from this call to getActionDefinitionsBuilder in X86LegalizerInfo::setLegalizerInfo32bit. if (!Subtarget.is64Bit()) {
|
Bumping this again. We might not be able to release for Win32 if we can't get to the bottom of this. |
There are some interesting aspects of MSVC's x86-32 calling conventions that could explain these symptoms. I'm familiar with them, and I would investigate, but my Windows machine is out of commission at the moment. If anyone else wants to experiment, try to avoid passing complex things (things containing SmallVector members) by value. |
To clarify: this is LLVM 10 only, but not 11 or trunk, yes? |
I have not tested with LLVM 11 or trunk yet. |
I reproduced this and debugged this a bit. So far, this feels like an MSVC compiler bug. This I replaced the SmallVector with my own wrapper object with instrumented ctor/dtor operations: struct Wrapper { This produces the following logs from a single call to typeInSet: Wrapper() 0x8d7a4c0 instances 1 Addresses starting with 0x8d... appear to be stack, and 0x8f... appears to be heap. So my reading of this log is:
Note that the source of the move operation is not the same as the address of the copied wrapper (0x8d7a450 vs 0x8d7a490). There are no other Wrapper constructor calls, so how did this address come into existence? In the debugger, I put a watchpoint on the bytes of the copy-constructed Wrapper. The watchpoint stopped in the implementation of memcpy, confirming the theory that Wrapper is memcpy'd even though it is not a trivially copyable object. So far as I can tell, this is not a standard library bug. This is the code for the std::function constructor: I annotated the disassembly here: 0:000> uf 00dd6c87 - 5 - 42 EBX now points to parameter area1125 00dd6c43 83ec08 sub esp,8 Allocate 4 bytes and align stack to 8 bytes1125 00dd6c4c 55 push ebp Push EBP like a normal prologue1125 00dd6c4d 8b6b04 mov ebp,dword ptr [ebx+4] Copy return address into allocated bytes (EBX+4 points to retaddr)1125 00dd6c54 8bec mov ebp,esp Copy SP to FP as in normal prologue1125 00dd6c56 83ec28 sub esp,28h Normal stack allocation1125 00dd6c59 57 push edi Save EDI, it is callee-saved1125 00dd6c5a 51 push ecx Initialize stack frame to all 0xCC bytes, preserve
|
Here is a reduced bug for the MSVC compiler: #include The Wrapper object models the SmallVector interior object pointer. It tracks its identity with the receiveWrapper has a similar prologue to the std::function constructor I annotated in the last comment: ?receiveWrapper@@YAXUWrapper@@@z (void __cdecl receiveWrapper(struct Wrapper)): This prologue basically realigns the stack (see the declspec align 8) and copies the bytes of all of the parameters into the new space, along with the return address and EBP to set up a fake stack frame so standard frame pointer stack walks work well. And, here's the assertion failure: $ cl -GS- t.cpp && ./t.exe t.cpp /out:t.exe So, it's not our bug. We could workaround it by force enabling optimization on this particular file. |
I did my best to write up the issue here: |
Landed a workaround in 4e3edef. |
*** Bug llvm/llvm-bugzilla-archive#48054 has been marked as a duplicate of this bug. *** |
*** Bug llvm/llvm-bugzilla-archive#49097 has been marked as a duplicate of this bug. *** |
mentioned in issue llvm/llvm-bugzilla-archive#48054 |
mentioned in issue llvm/llvm-bugzilla-archive#49097 |
Extended Description
(Reporting on behalf of Alex Reinking, who found this while debugging Halide:)
Overview:
There is an apparently 100% reproducible crash when using LLVM 10 build using MSVC 2017 or 2019, for Windows x86 (32-bit), Debug mode only.
The crash appears due to a double-free in the destructor of SmallVector, perhaps due to a bug in the copy/move/operator= operations of SmallVector. In particular, the object whose destructor triggers the crash is a lambda capture-by-value clone of a small-vector that was initially created on the stack.
The stack trace looks like:
In the debugger output window we see:
Invalid address specified to RtlValidateHeap( 02150000, 01B5ECC8 )
, which looks a lot like it's trying to free a stack address. The 2nd argument is the pointer passed to free (stored in SmallVector's BeginX field).Steps To Repeat:
Note that Visual Studio 16.6.x (the latest) exposes a bug in LLVM that has now been patched, but prevents it from compiling. The instructions below use Visual Studio 15.9.23 (2017) instead.
Without vcpkg
Get and compile LLVM:
With vcpkg
Compile with:
Compiler info:
CMake info:
vcpkg list (only x86-windows is relevant):
The text was updated successfully, but these errors were encountered: