std::mutex Access Violation in Visual Studio 2022
Problem Statement
After updating to Visual Studio 2022 (v17.10) or installing applications built with previous VS versions, your program may crash on startup with this critical error:
0xC0000005: Access violation reading location 0x0000000000000000.
The crash occurs at the first std::mutex::lock()
call with this stack trace:
msvcp140.dll!mtx_do_lock(_Mtx_internal_imp_t * mtx, const xtime * target) Line 100 C++
[Inline Frame] my.dll!std::_Mutex_base::lock()
[Inline Frame] my.dll!std::unique_lock<std::mutex>::{ctor}(std::mutex &)
This Access Violation happens when an application downgrades C:\Windows\System32\msvcp140.dll
to an older version (e.g., 14.34.31931.0). Programs compiled with the latest Visual Studio then try to execute code incompatible with the older runtime.
Root Cause
This compatibility break stems from a Visual C++ runtime update:
Microsoft confirmed this in their STL changelog:
"Fixed mutex's constructor to be constexpr. Note: Programs that aren't following documented binary compatibility restrictions may encounter null dereferences in mutex machinery."
Solutions
1. Enable Compatibility Macro (Recommended)
Add a preprocessor definition to disable the problematic constexpr functionality:
Visual Studio:
- Right-click project → Properties
- Navigate to C/C++ → Preprocessor
- In Preprocessor Definitions, add
_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR
- Rebuild solution
CMake Projects:
target_compile_definitions(your_target_name PRIVATE _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR)
Why This Works
This macro reverts std::mutex
to its pre-constexpr constructor behavior, maintaining compatibility with older runtimes.
2. Repair Visual C++ Redistributable
If crash occurs in end-user environments, repair the Microsoft Visual C++ Redistributable:
- Open Windows Settings → Apps → Apps & features
- Locate Microsoft Visual C++ 2015-2022 Redistributable
- Select Modify → Repair
3. Runtime Version Detection
Add a startup check to detect incompatible runtimes:
#include <windows.h>
#include <iostream>
#include <sstream>
bool IsRuntimeCompatible() {
HMODULE hModule = LoadLibraryEx(L"msvcp140.dll", nullptr, LOAD_LIBRARY_AS_DATAFILE);
if (!hModule) return false;
HRSRC hResource = FindResource(hModule, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
if (!hResource) {
FreeLibrary(hModule);
return false;
}
DWORD size = SizeofResource(hModule, hResource);
HGLOBAL hGlobal = LoadResource(hModule, hResource);
void* pData = LockResource(hGlobal);
VS_FIXEDFILEINFO* pFileInfo;
UINT len;
if (!VerQueryValue(pData, L"\\", (LPVOID*)&pFileInfo, &len) || len != sizeof(VS_FIXEDFILEINFO)) {
FreeLibrary(hModule);
return false;
}
const WORD major = HIWORD(pFileInfo->dwFileVersionMS);
const WORD minor = LOWORD(pFileInfo->dwFileVersionMS);
const WORD build = HIWORD(pFileInfo->dwFileVersionLS);
const WORD rev = LOWORD(pFileInfo->dwFileVersionLS);
FreeLibrary(hModule);
const bool compatible = (major > 14) ||
(major == 14 && minor > 40) ||
(major == 14 && minor == 40 && build >= 33810);
if (!compatible) {
std::wstringstream ss;
ss << L"Incompatible runtime: msvcp140.dll v"
<< major << L"." << minor << L"." << build << L"." << rev;
MessageBox(NULL, ss.str().c_str(), L"Runtime Error", MB_ICONERROR);
}
return compatible;
}
int main() {
if (!IsRuntimeCompatible()) return 1;
// Normal application start
}
Important
This detection must occur before any mutex operations. For static mutexes, consider a lightweight launcher executable.
Prevention Best Practices
- Include the Appended Redistributable during installation deployment
- Maintain consistent toolchain versions across all components
- Implement CI/CD checks for runtime compatibility
- Add version validation to installation scripts
$dll = Get-Item "C:\Windows\System32\msvcp140.dll"
if ($dll.VersionInfo.FileMajorPart -lt 14 -or
$dll.VersionInfo.FileMinorPart -lt 40) {
Write-Error "Requires VC++ 2022 Redist v14.40+"
}
Compatibility Matrix
Runtime Version | Status | Action Required |
---|---|---|
<14.40.33810 | ⛔ Crash | Repair/Update |
≥14.40.33810 | ✓ Stable | None |
With macro flag | ✓ Compatible | None |
Additional Resources
Always ensure your deployment environment uses a Visual C++ Redistributable version equal to or newer than your build toolchain.