21

競合状態を含むコードが少しあります...一貫して発生しないため、競合状態であることがわかります。デュアルコアマシンでより頻繁に発生するようです。

私がトレースしているとき、それは決して起こりません。ただし、デッドロックになる可能性もあります。これが発生するログと発生しないログの完了段階を分析することで、このバグを単一の機能に特定することができました。ただし、関数のスコープのどこでこれが発生しているのかわかりません。トップレベルではありません。

ログステートメントまたはブレークポイントを追加すると、競合状態の場合にタイミングが変更され、これが発生しなくなります。

これが発生している場所を特定できる競合状態アナライザーを入手する以外に使用できる手法はありますか?

これは、(管理されていない種類の)C++を使用するVisualStudio9にあります。

4

8 に答える 8

10

CLangとgcc4.8+にはThreadSanitizerと呼ばれるツールが含まれています。

-fsanitize=threadフラグを使用してコードをコンパイルします

例:

$ cat simple_race.cc
#include <pthread.h>
#include <stdio.h>

int Global;

void *Thread1(void *x) {
  Global++;
  return NULL;
}

void *Thread2(void *x) {
  Global--;
  return NULL;
}

int main() {
  pthread_t t[2];
  pthread_create(&t[0], NULL, Thread1, NULL);
  pthread_create(&t[1], NULL, Thread2, NULL);
  pthread_join(t[0], NULL);
  pthread_join(t[1], NULL);
}

そして出力

$ clang++ simple_race.cc -fsanitize=thread -fPIE -pie -g
$ ./a.out 
==================
WARNING: ThreadSanitizer: data race (pid=26327)
  Write of size 4 at 0x7f89554701d0 by thread T1:
    #0 Thread1(void*) simple_race.cc:8 (exe+0x000000006e66)

  Previous write of size 4 at 0x7f89554701d0 by thread T2:
    #0 Thread2(void*) simple_race.cc:13 (exe+0x000000006ed6)

  Thread T1 (tid=26328, running) created at:
    #0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b)
    #1 main simple_race.cc:19 (exe+0x000000006f39)

  Thread T2 (tid=26329, running) created at:
    #0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b)
    #1 main simple_race.cc:20 (exe+0x000000006f63)
==================
ThreadSanitizer: reported 1 warnings
于 2016-01-15T10:01:29.843 に答える
6

コードのさまざまな部分にスリープを設定します。スレッドセーフなものは、それ(または非同期コード)が数秒間スリープしてもスレッドセーフになります。

于 2010-06-28T19:10:55.607 に答える
2

実際、競合状態を自動的に見つける試みがいくつかあります。

競合状態の検出に関連して読んだもう1つの用語は、RaceFuzzerですが、それに関する本当に役立つ情報を見つけることができませんでした。

これは比較的若い調査分野だと思うので、私が知る限り、この主題に関する理論的な論文が主にあります。ただし、上記のキーワードの1つをグーグルで検索してみてください。役立つ情報が見つかるかもしれません。

于 2010-06-28T18:47:22.717 に答える
2

これらを追跡するために私が知っている最善の方法は、 VisualStudioでCHESSを使用することです。これは簡単に使用できるツールではなく、アプリのサブセクションを段階的にテストする必要があります。幸運を。

于 2010-06-28T18:47:46.183 に答える
2

Visual Studioのトレースポイントを使用して、競合状態を見つけることができました。もちろん、それでもタイミングに影響しますが、私が使用した場合、少なくとも、競合状態の発生を完全に防ぐには十分ではありませんでした。少なくとも、専用のロギングよりも混乱が少ないように見えました。

それ以外の場合は、他の人が見られるようにコードを投稿してみてください。コードを詳細に調べるだけでは、競合状態を見つけるのに悪い方法ではありません。

于 2010-06-28T19:05:16.373 に答える
2

ですから、私にとってのスレッジハンマーの方法は次のとおりです。これには多くの忍耐が必要であり、最良のシナリオでは正しい軌道に乗ることができます。私はこれを使用して、この特定の問題で何が起こっているのかを理解しました。私はトレースポイントを使用してきました。1つは疑わしい高レベル関数の最初に、もう1つは最後にあります。トレースポイントを下に移動します。関数の先頭にトレースポイントを追加するとバグの発生が止まる場合は、状態を再現できるようになるまでトレースポイントを下に移動します。トレースポイントは、最終的に安全でないコードをトリガーする呼び出しの後に配置した場合はタイミングに影響しませんが、前に配置した場合は影響します。また、出力ウィンドウにも注意してください。どのメッセージの間にバグが発生していますか?トレースポイントを使用して、この範囲を狭めることもできます。

バグをコードの管理可能な領域に絞り込んだら、ブレークポイントをスローして、この時点で他のスレッドが何をしているのかを確認できます。

于 2010-06-28T23:11:31.243 に答える
1

また、保護されていないリソースである可能性もあり、一貫性のない動作を説明する可能性があります(特に、シングルコアでは正常に動作し、デュアルコアでは動作しない場合)。いずれにせよ、コードレビュー(競合状態とスレッドセーフでないソースコードの両方)がソリューションへの最短パスになる可能性があります。

于 2010-06-28T19:33:35.053 に答える
0

特定の種類の競合状態をチェックできるIntelInspectorなどのツールを使用できます。

于 2013-02-14T07:30:15.150 に答える