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 ModifyRepair

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.