调试boost :: thread应用程序,误报率高

时间:2011-11-03 17:35:13

标签: c++ multithreading debugging valgrind boost-thread

我编写了一个boost :: thread应用程序,我可能会遇到一些竞争条件。我想调试这个程序。因此我使用了以下valgrind工具:

  1. halgrind
  2. DRD
  3. 不幸的是,他们的误报率很高。因此,valgrind --tool=drd以下真正简单的程序会抱怨94个错误,其中不应该错误。因此,通过我的复杂程序,我得到大约15000个错误。所以很难找到实际的错误。

    我可以使用以下boost库1.46.0和1.47.0重现此行为。并使用valgrind 3.7.0 SVN和valgrind 3.8.0 SVN。操作系统我尝试了Ubuntu 11.10和Mac OS X 10.7。编译器所在的gcc 4.2.1和gcc 4.6.1。

    #include <iostream>
    #include <boost/thread.hpp>
    
    void run()
    {
        //do some stuff here
    }
    
    int main(int argc, char* argv[])
    {
        boost::thread thread(run);
        thread.join();
        std::cerr << "main: done" << std::endl;
        return 0;
    }
    ;
    

    如何调试boost程序?还有其他工具可能更适合吗?

    解决方案

    似乎版本3.6.1之后的valgrind被破坏了。如果我使用valgrind 3.6.1,一切正常。

    此处有valgrind --tool=drd的错误报告:

    ==60767== Thread 1:
    ==60767== Conflicting store by thread 1 at 0x100026ec0 size 8
    ==60767==    at 0x2A316E: pthread_mutex_lock (in /usr/lib/system/libsystem_c.dylib)
    ==60767==    by 0x2A82FA: _pthread_cond_wait (in /usr/lib/system/libsystem_c.dylib)
    ==60767==    by 0x32A4E: boost::condition_variable::wait(boost::unique_lock<boost::mutex>&) (in /usr/local/lib/libboost_thread.dylib)
    ==60767==    by 0x2BE5A: boost::thread::join() (in /usr/local/lib/libboost_thread.dylib)
    ==60767==    by 0x10000195C: main (in ./playgroudThreads)
    ==60767== Address 0x100026ec0 is at offset 144 from 0x100026e30. Allocation context:
    ==60767==    at 0xC5B3: malloc (vg_replace_malloc.c:266)
    ==60767==    by 0x9968D: operator new(unsigned long) (in /usr/lib/libstdc++.6.0.9.dylib)
    ==60767==    by 0x1000069ED: boost::detail::thread_data<void (*)()>* boost::detail::heap_new_impl<boost::detail::thread_data<void (*)()>, void (*&)()>(void (*&)()) (in ./playgroudThreads)
    ==60767==    by 0x100006A87: boost::detail::thread_data<void (*)()>* boost::detail::heap_new<boost::detail::thread_data<void (*)()>, void (*)()>(void (*&)()) (in ./playgroudThreads)
    ==60767==    by 0x100006ACA: boost::shared_ptr<boost::detail::thread_data_base> boost::thread::make_thread_info<void (*)()>(void (*)()) (in ./playgroudThreads)
    ==60767==    by 0x100006B08: boost::thread::thread<void (*)()>(void (*)(), boost::disable_if<boost::is_convertible<void (*&)(), boost::detail::thread_move_t<void (*)()> >, boost::thread::dummy*>::type) (in ./playgroudThreads)
    ==60767==    by 0x100001950: main (in ./playgroudThreads)
    ==60767== Other segment start (thread 2)
    ==60767==    at 0x2A7B68: thread_start (in /usr/lib/system/libsystem_c.dylib)
    ==60767== Other segment end (thread 2)
    ==60767==    at 0x3E667A: mach_msg_trap (in /usr/lib/system/libsystem_kernel.dylib)
    ==60767==    by 0x3DED38: semaphore_create (in /usr/lib/system/libsystem_kernel.dylib)
    ==60767==    by 0x2A50F7: new_sem_from_pool (in /usr/lib/system/libsystem_c.dylib)
    ==60767==    by 0x2A6199: _pthread_exit (in /usr/lib/system/libsystem_c.dylib)
    ==60767==    by 0x2A48C9: _pthread_start (in /usr/lib/system/libsystem_c.dylib)
    ==60767==    by 0x2A7B74: thread_start (in /usr/lib/system/libsystem_c.dylib)
    

1 个答案:

答案 0 :(得分:1)

来自DRD manual

  

数据竞争探测器之前发生的一个重要优势是它们不会报告任何误报。   DRD基于先发生算法。

因此,如果实现仅使用POSIX线程而不是像Linux的futex这样的非POSIX内容,则DRD没有任何误报。

因此,如果DRD报告误报,就像你这样的无种族计划,它有一个错误。它不应该有误报。

但是,我无法在我的机器上重现您报告的错误(Archlinux / gcc 4.6.2 / valgrind 3.6.1 / boost 1.47)。