windowsmultithreadingvisual-c++mutexdependency-management

First std::mutex::lock() crashes in application built with latest Visual Studio 2022


Recently I installed the latest Visual Studio 2022 v17.10 to build my programs, and initially all went well. But after some other program installation, my programs started failing immediately on start where the first std::mutex::lock() is called with the exception

0xC0000005: Access violation reading location 0x0000000000000000.

and 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 &)

It turned out that the installed application was built in a previous version of Visual Studio 2022, and it silently downgraded C:\Windows\System32\msvcp140.dll to version 14.34.31931.0, where the exception happens.

I personally managed to restore normal operation of my programs, by pressing Repair in Microsoft Visual C++ 2015-2022 Redistributable (x64) - 14.40.33810, which restored C:\Windows\System32\msvcp140.dll to version 14.40.33810.0.

But since this unexpected crash on start-up can easily happen to the users of my program, I would like to ask, is there a way to make the programs built in the latest Visual Studio 2022 compatible with runtimes from previous versions of the same Visual Studio 2022? Or at least how to show meaningful error to the users if the runtime is downgraded for some reason instead of silent application termination.


Solution

  • Short answer, use the _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR preprocessor macro.

    This nugget of info from the Microsoft/STL changelog might help us understand the visual studio snafu that unfolded over the past couple days.

    Fixed mutex's constructor to be constexpr. #3824 #4000 #4339 Note: Programs that aren't following the documented restrictions on binary compatibility may encounter null dereferences in mutex machinery. You must follow this rule: When you mix binaries built by different supported versions of the toolset, the Redistributable version must be at least as new as the latest toolset used by any app component.

    You can define _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR as an escape hatch.

    --- microsoft/STL changelog

    I ran into similar issue on a GitHub Actions workflow and arrived here from these independently reported issues in the Visual Studio developer community:

    1. https://developercommunity.visualstudio.com/t/All-my-std::unique_lock-crashed-after-th/10665376?space=41&sort=newest&viewtype=all
    2. https://developercommunity.visualstudio.com/t/Access-violation-in-_Thrd_yield-after-up/10664660
    3. https://github.com/actions/runner-images/issues/10004

    You can find a detailed breakdown - https://github.com/actions/runner-images/issues/10004#issuecomment-2156109231