c++ - 调试boost::thread应用,误报率高

标签 c++ multithreading debugging valgrind boost-thread

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

  1. 哈尔格林德
  2. 博士

不幸的是,他们的误报率非常高。因此,使用下面的非常简单的程序 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)

最佳答案

来自 DRD manual

An important advantage of happens-before data race detectors is that these do not report any false positives. DRD is based on the happens-before algorithm.

因此,如果实现仅使用 POSIX 线程而不使用非 POSIX 线程(如 Linux 的 futex),DRD 不会有任何误报。

因此,如果 DRD 报告误报,那么在像您这样的无种族程序上,它就有一个错误。它不应该有误报。

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

关于c++ - 调试boost::thread应用,误报率高,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7999360/

相关文章:

c++ - 结合 boost unordered_map、bind 和 std::find_if

c++ - Libzip - 归档错误总是返回 ZIP_ER_OK,即使创建归档失败

c++ - MFC 还活着吗?

ios - 在迭代之前复制集合是否足以防止同步问题?

C - pthread条件变量

java - 处理InterruptedException的最佳方法

c# - 如何记录 C# 应用程序的执行顺序

张量的 C++ 编译时索引/元组访问

python - 如何在程序中启动 python 控制台(以便于调试)?

c# - Windows 商店应用程序中是否有全局异常处理程序?