問題タブ [dbgeng]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
0 に答える
65 参照

multithreading - マルチコア システム上のマルチスレッド アプリケーションでの命令のステッピング/トレースを記録する

DbgEng を使用して WinDbg の拡張機能を作成しました。これは、ユーザー モードとカーネル モードで実行された各命令のレジスタとスタックの状態を含むトレースを記録します。
ステップ トレースでは、ブレークポイントを使用します (トレースが記録されるスレッド コンテキストに TRAP フラグを設定しようとしましたが、同じ結果が得られました)。各ステップの後、ブレークポイントにヒットすると、IDebugEventCallbacks::Breakpoint() が呼び出され、DEBUG_STATUS_BREAK が返されます。これにより、デバッガーはエンジン ループで IDebugControl::WaitForEvent() 関数を完了し、現在の命令の状態を記録します。
トレースは、マルチコア システム (4 つの物理コア、8 つの仮想コア) 上のテスト マルチスレッド アプリケーションで記録されます。テスト アプリケーションは、メインのスレッドとは別に 6 つのスレッドを作成します。4 つのスレッドが同じ関数 func0 のトレースを非同期に記録します。作成された他の 3 つのスレッドは、計算をシミュレートします。
テストプログラムのコード:

ほとんどの場合、すべてが期待どおりに機能し、次のような完全に記録されたトレースが得られます。

ただし、デバッガーがステップをスキップし、ブレークポイントをトリガーしないことがあります。
例えば:

状態 rip = 00007ff6'ad314215 が記録され、次のアドレス 00007ff6'ad31421a にブレークポイントが設定されているとします。その後、プログラムの実行を続行し、アドレス 00007ff6'ad31421a のブレークポイントがトリガーされることを期待します。しかし、00007ff6'ad31421a でブレークポイントにヒットして IDebugEventCallbacks::Breakpoint() を呼び出す代わりに、現在の rip = 00007ff6'ad314221 で、次のパラメーターを使用して IDebugEventCallbacks::Exception() を呼び出します。

したがって、システムはすでに 00007ff6'ad31421a で命令を実行しましたが、何らかの理由でデバッガーは設定されたブレークポイントに到達せず、ブレークポイントが設定されていない次の命令 (00007ff6`ad314221) で例外を発生させました。

また、実行が記録されているスレッドの IDebugEventCallbacks::ChangeEngineState() でプログラム カウンター (threadContext.rip) をチェックしようとしましたが、スキップされた命令のアドレス (00007ff6'ad31421a) に等しいカウンターを取得できませんでした。 .

その結果、トレースにアドレス 00007ff6'ad31421a の状態がありません。

質問:

  1. この動作の理由は何ですか?
  2. この動作はマルチコア システムでの実行によって引き起こされる可能性があるという意見に応えましたが、この判決の著者は、これが何らかの形で正当化される情報源には言及していません。これが事実である場合、誰かがその根拠へのリンクを提供できますか?
  3. 問題を解決するための提案はありますか?
  4. ユーザー モードやカーネル モードと同様に、Windows の状態で同様のトレースを記録できるツールはありますか?