0

1 時間ほど、非常に不穏な動作について説明しようとしてきましたが、それが Visual Studio のコンパイラによるものなのか、デバッガによるものなのかは不明です。私は今、答えの一部を知っています。基本的に、MSVC2005 Debug ビルドで以下をコンパイルして実行しています。

DWORD timeStamp;
struct SomeEventStruct {
  DWORD timeStamp;
  // ... plus other data
};
void Magic( const SomeEventStruct & anEvent )
{
    if ( anEvent.timeStamp < timeStamp )
    {
      ASSERT( false ); // shouldn't happen! Time does not run backwards!
    }
    timeStamp = anEvent.timeStamp;
}

ASSERT( false )が実行できる唯一の方法は、if式が true と評価される場合ですよね? では、なぜASSERT()起動し、変数の値を検査するためにデバッガーに侵入したときに、 timeStamp0 であることがよくあるのでしょうか? 定義上、これは不可能です。符号なしの値がゼロ未満になることはありません。

確かに、これはマルチスレッド アプリケーションですが、他のスレッドがこれらの変数に触れることはなく、すべてメイン UI スレッド内にあります。また、状況を単純化しました。実際には、それらはメンバー変数と関数であり、重要だとは思いません。私が関連していると信じているのは、最初にASSERT()解雇され、デバッガーに侵入するように招待されたとき、変数の値が妥当であり、そこで悪いタイムスタンプが見つかったということです。物事が奇妙になり始めたのは、それを続けた後でした。

if最終的に、ステートメントとステートメントの間で timeStamp 値がゼロにリセットされていることがわかりましたASSERT( false )。これを行う可能性のある唯一のコード行は、最終的にタイマーイベントに接続されていることを知っています(上記のタイムスタンプ付きイベントとは異なります-タイマーは、興味のあるシステムイベントの表示を更新するために起動します)。

だから今私が知りたいのは、Windowsタイマーイベントが割り込みのように機能し、ある時点でスレッドの実行を中断し、後でそれに戻るか...またはVSデバッガーに固有の何かがここで起こっているか、またはの内部の仕組みASSERT()?前の呼び出しが完了するまでタイマー イベント ハンドラーが実行されないようにしたい場合、その再入を防ぐのは私次第ですか?

4

0 に答える 0