4

スレッド サニタイザー ( http://code.google.com/p/data-race-test/wiki/ThreadSanitizer#Using_ThreadSanitizer )を試してみようと思った ので、簡単なプログラムを作成しました。

#include <thread>
#include <atomic>
#include <vector>
#include <iostream>
#include <algorithm>
#include <mutex>
using namespace std;
int violated=0;
mutex mtx;
void violator()
{
    lock_guard<mutex> lg(mtx);
    violated++;
}
int main()
{
    thread t1(violator);
    t1.join();
    thread t2(violator);
    t2.join();
}

違反へのアクセスはミューテックスと同期されているため、AFAIKプログラムは問題ありません(そして、そのプログラムがなくてもレースフリーであるとコメントのように言います)。しかし、tsan は不平を言い、たくさんの警告を出します: http://www.filedropper.com/output では、ツールの使い方が間違っているのでしょうか? 重要な場合は、VS11 Beta を使用しています。

4

1 に答える 1

12

これは正常です。ThreadSanitizer は、C++11 スレッド ライブラリを適切に処理する方法を認識していません。また、Interlocked* または std::atomic を使用したきめ細かな同期を処理することもできません。さらに、ハイブリッド モードでは誤検知が発生する可能性があります。標準ライブラリの競合やその他の誤検出を無視する抑制ファイルを作成できます。Linux x64 と ThreadSanitizer でコードを使用すると、stdlib で 7 つの偽の競合が発生しました。抑制ファイル追加後私はこれらの人種を無視することができました。次に、ロックを解除し、t1.join() を 2 番目のスレッドの開始後に移動しました (したがって、実際の競合が発生します)。ThreadSanitizer はこれを正しく検出します。その後、ミューテックスを再度追加したところ、競合は報告されなくなりました。したがって、実際には非常に便利なようです。Google は、他の多くのプロジェクトの中でも、Chrome ブラウザーでレースを見つけるためにそれを使用しているため、かなり成熟しています (ただし、私の ubuntu 12.10 システムでビルドするのは本当に苦労しました)。

Linux の場合、抑制ファイルは次のようになります。

{
<std::shared_ptr>
ThreadSanitizer:Race
...
fun:std::_Sp_counted_base::_M_release
fun:std::__shared_count::~__shared_count
fun:std::__shared_ptr::~__shared_ptr
}
{
<std::arena_thread_freeres>
ThreadSanitizer:Race
fun:arena_thread_freeres
fun:__libc_thread_freeres
fun:start_thread
}
于 2012-10-31T01:33:05.620 に答える