After a few days of painful debugging, I could reproduce a bug in one of my unit test with this small program:
#include <iostream>
#include <vector>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <chrono>
#include <new>
int main(){
try{
for(size_t j=0;j<100;++j){
std::cout<<j<<std::endl;
std::mutex mutex;
std::unique_ptr<std::condition_variable>cv;
std::vector<std::thread>v(10);
auto wait=[&](size_t i){
std::unique_lock<std::mutex>ul(mutex);
if(!cv){cv=std::make_unique<std::condition_variable>();}
cv->wait_for(ul,std::chrono::milliseconds(i*10));
};
for(size_t i=0;i<v.size();++i){v[i]=std::thread(wait,i);}
for(size_t i=0;i<v.size();++i){v[i].join();}}}
catch(...){
std::cout<<"Exception"<<std::endl;
std::abort();}
}
When I compile with lmcheck on:
g++-4.9.2 -lmcheck -std=c++1y -pthread /home/Arnaud/Test.cpp -o Test
the program runs and stops with memory clobbered before allocated block
I could reproduce this on multiple machines and both with gcc 4.9.2 and gcc 5.1. What is wrong with this code?
NB: This code runs fine with Visual Studio 2013.
According to this documentation, mcheck
isn't thread-safe.
It looks like linking with -lmcheck
adds allocation hooks which call mcheck
, meaning that it's no longer safe to allocate and deallocate memory from multiple threads without extra synchronisation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With