This is an attempt to fix clang/test/Index/crash-recovery-modules.m when compiling a build with the MSVC STL & _ITERATOR_DEBUG_LEVEL == 2 (meaning a DEBUG build)
The problem is related to the STL implementation.
I do run sometimes the Debug build with LLVM_ENABLE_ASSERTIONS (on x64), it brings up interesting issues (see rG007d173e2e0c29903bc17a9d5108f531a6f2ea4d)
The problem
Before, the test used to freeze with this callstack:
A lock was taken by another thread that died since.
The test forcibly triggers a crash with the help of #pragma clang __debug crash. This would hit clang/lib/Lex/Pragma.cpp, L1040.
However the call was made through a CrashRecoveryContext, which is essentially a try/catch, so we get back at clang/lib/Frontend/CompilerInstance.cpp, L1152:
However, later on at the end of this function, CompilerInvocation is destroyed, which in turn triggers destruction of FrontendOptions, which eventually triggers the destruction of its Inputs member.
The problem here is that Inputs was being iterated just before the #pragma crash occurred, and CrashRecoveryContext uses SEH. This leaves STL's internal linked list (for the Inputs vector) in a stale state, pointing to a stack variable that doesn't exist anymore (now that we got out of CrashRecoveryContext). When Inputs is being destroyed, the code in C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\xutility tried to clear that linked list. But now we have nodes pointing to stack memory pages that were already un-commited.
All this ends up to a second crash which happens to leave the _LOCK_DEBUG mutex locked. The crash itself is protected by another CrashRecoveryContext invoked by clang/tools/libclang/CIndex.cpp, L3624 so the program doesn't crash. But it now ends in a stale state, and the _LOCK_DEBUG mutex is locked forever, which leads to the freeze in the top screenshot.