Crash when assigning to std::future under MSVC's Debug mode

Viewed 649

The following code crashes in random intervals when built with MSVC under Debug mode, unlike the Release.

#include <future>

using namespace std;

int main() {
    auto l = [](){};
    auto f = async(launch::async, l);

    for (int i = 0; i < 1000000; ++i)
        f = async(launch::async, l);
}

The console output says:

f:\dd\vctools\crt\crtw32\stdcpp\thr\mutex.c(51): mutex destroyed while busy

The full call stack is: https://pastebin.com/0g2ZF5C1

Now obviously it's just a stress test, but am I doing something utterly stupid? It seems to me it's fine to reassign a new task to an existing future, as it's said that operator=:

Releases any shared state and move-assigns the contents of other to *this

(Due to http://en.cppreference.com/w/cpp/thread/future/operator%3D).

Is it a bug in MSVC's runtime?

Remarkably, the program stops crashing if I manually call wait() before the assignment, thus making the loop into:

for (int i = 0; i < 1000000; ++i) {
    f.wait();
    f = async(launch::async, l);
}

Isn't operator= itself supposed to call wait?

Background:

_MSC_VER equals 1911

Code was built with help of:

Microsoft Visual Studio Community 2017 Preview(2)
Version 15.4.0 Preview 2.0

Just opened a brand new C++ project.

2 Answers

I got to this question since I had a very similar issue with MSVC debug mode, getting sporadic crashes with the mutex destroyed while busy message.

In my case it turns out that it was an issue with VS2017 that had been present up until version 15.8 (as specified here).

Updating to VS2019 solved this issue for me. Although this question is pretty old, I'm writing this up as another alternative answer.

Related