本文介绍了调试boost ::线程应用,高误报率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


  1. halgrind

  2. drd

不幸的是,他们有一个非常假的阳性率。所以使用真正简单的程序下面 valgrind --tool = drd 抱怨大约94错误,其中no应该是。所以与我的复杂程序,我得到大约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()
{
//在这里做一些事情
}

int main(int argc,char * argv [ ])
{
boost :: thread thread(run);
thread.join();
std :: cerr<< main:done< std :: endl;
return 0;
}
;

如何调试boost线程程序?是否有其他工具可能更适合?



解决方案



那个valgrind版本3.6.1后被打破。如果我使用valgrind 3.6.1一切正常。



这里来自的错误报告valgrind --tool = drd

  == 60767 == Thread 1:
== 60767 ==以0x100026ec0大小8
== 60767 == at 0x2A316E:pthread_mutex_lock(在/usr/lib/system/libsystem_c.dylib中)
== 60767 == by 0x2A82FA:_pthread_cond_wait(在/ 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()(在/usr/local/lib/libboost_thread.dylib)
== 60767 == by 0x10000195C:main(in ./ playgroudThreads)
== 60767 ==地址0x100026ec0在从0x100026e30的偏移144。分配上下文:
== 60767 == at 0xC5B3:malloc(vg_replace_malloc.c:266)
== 60767 == by 0x9968D:operator new(unsigned long)(在/ 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: :detail :: thread_data< void(*)()> * boost :: detail :: heap_new& boost :: detail :: thread_data< 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& ;>,boost :: thread :: dummy *> :: type)(in ./playgroudThreads)
== 60767 == by 0x100001950:main(in ./playgroudThreads)
== 60767 ==其他段结束(线程2)
== 60767 ==在0x2A7B68:thread_start(在/usr/lib/system/libsystem_c.dylib)
== 60767 ==其他段结束)
== 60767 == at 0x3E667A:mach_msg_trap(在/usr/lib/system/libsystem_kernel.dylib)
== 60767 == by 0x3DED38:semaphore_create(在/ usr / lib / system / libsystem_kernel .dylib)
== 60767 == by 0x2A50F7:new_sem_from_pool(在/usr/lib/system/libsystem_c.dylib)
== 60767 == by 0x2A6199:_pthread_exit(在/ usr / lib / system /libsystem_c.dylib)
== 60767 == by 0x2A48C9:_pthread_start(在/usr/lib/system/libsystem_c.dylib)
== 60767 == by 0x2A7B74:thread_start(在/ usr / lib /system/libsystem_c.dylib)


解决方案

=http://valgrind.org/docs/manual/drd-manual.html =nofollow> DRD手册

p>

因此,如果DRD报告一个假阳性,在一个像你的无竞争程序,它有一个错误。



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


I have programmed a boost::thread application, where I might have some race conditions. I want to debug this program. Therefore I used the following valgrind tools:

  1. halgrind
  2. drd

unfortunately they have a very false positive rate. So with the really simple program below valgrind --tool=drd complains about 94 errors, where no should be. So with my complex program I get about 15000 errors. So it is really hard to find the actual error.

I could reproduce this behavior with the following boost libraries 1.46.0 and 1.47.0. And with valgrind 3.7.0 SVN and valgrind 3.8.0 SVN. The operating systems I tried it out where Ubuntu 11.10 and Mac OS X 10.7. The compiler where gcc 4.2.1 and 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;
}
;

How do you debug your boost thread programs? Are there other tools which might be better suited?

Solution

It seems that valgrind after version 3.6.1 is broken. If I use valgrind 3.6.1 everything works fine.

Here on error report from 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)
解决方案

From DRD manual

So DRD does not have any false positive if the implementation uses just POSIX threads and not non-POSIX stuff like Linux's futex.

Therefore, if DRD reports a false positive, on a race-free program like yours, it has a bug. It is not supposed to have false positives.

However, I could not reproduce the errors you reported, on my machine (Archlinux/ gcc 4.6.2 / valgrind 3.6.1 / boost 1.47).

这篇关于调试boost ::线程应用,高误报率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 14:07