Skip to content

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 ​

Add a preprocessor definition to disable the problematic constexpr functionality:

Visual Studio:

  1. Right-click project → Properties
  2. Navigate to C/C++ → Preprocessor
  3. In Preprocessor Definitions, add _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR
  4. Rebuild solution

CMake Projects:

cmake
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:

  1. Open Windows Settings → Apps → Apps & features
  2. Locate Microsoft Visual C++ 2015-2022 Redistributable
  3. Select Modify → Repair

3. Runtime Version Detection ​

Add a startup check to detect incompatible runtimes:

cpp
#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 ​

  1. Include the Appended Redistributable during installation deployment
  2. Maintain consistent toolchain versions across all components
  3. Implement CI/CD checks for runtime compatibility
  4. Add version validation to installation scripts
ps
$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 VersionStatusAction Required
<14.40.33810⛔ CrashRepair/Update
≥14.40.33810✓ StableNone
With macro flag✓ CompatibleNone

Additional Resources ​

Always ensure your deployment environment uses a Visual C++ Redistributable version equal to or newer than your build toolchain.