分配块之前内存被破坏

8

经过几天痛苦的调试,我终于能够用这个小程序重现一个单元测试中的bug:

#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();}
}

当我使用lmcheck编译时:

g++-4.9.2 -lmcheck -std=c++1y -pthread /home/Arnaud/Test.cpp -o Test

程序运行时出现“memory clobbered before allocated block”错误。
我在多台计算机上都能重现这个问题,使用的gcc版本分别为4.9.2和5.1。这段代码有什么问题?
注意:这段代码在Visual Studio 2013中能正常运行。

1
我猜这是因为mcheck不是线程安全的:http://www.gnu.org/software/libc/manual/html_node/Heap-Consistency-Checking.html - Mike Seymour
是的,它不是线程安全的。 - Sam Varshavchik
@MikeSeymour:谢谢。你应该写一个简短的答案。我会接受它。 - Arnaud
1个回答

8

根据这份文档mcheck不是线程安全的。

看起来使用-lmcheck链接会添加分配钩子来调用mcheck,这意味着在多个线程中分配和释放内存时需要额外的同步措施。


我刚刚花了几个小时在gdb和dump核心堆栈跟踪中寻找关于mcheck()在我的代码中发现了什么错误的线索。结果只是使用了线程。:( 你通过指出显然记录的内容,拯救了我的一天。我读了手册页,但没有注意到它!:( - Arnaud Bouchez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接