CLRデバッガのアーキテクチャ

共通言語ランタイム(CLR)は、オペレーティングシステムカーネルの一部としてのみAPIをデバッグします。プログラムが例外を生成し、アンマネージコードでは、カーネルが実装プロセスを中断、とWin32 APIのデバッグ例外情報がデバッガに渡され使用されます。CLRデバッグAPIは、マネージコードのために同じ機能を提供することができます。マネージコードが例外を生成すると、CLRデバッグAPIは、実装プロセスを中断し、デバッガに例外情報を渡すことができます。

プロセス・アーキテクチャ

CLRデバッグAPIは、2つの主要コンポーネントで構成されています。

  • 常にプログラムにロードされたデバッグDLLは、同じプロセスをデバッグされています。ランタイムコントローラは、実行制御と検査を実行しているCLRマネージコードとスレッドと通信するための責任があります。

  • デバッガインタフェースは、異なるプロセスをデバッグ中のプログラムにロードされます。デバッガインタフェースは、デバッガ実行と通信するコントローラの代わりに責任があります。また、プロセスをデバッグしたり、これらのイベントを処理しているからのWin32デバッグイベントを処理するための責任がある、またはアンマネージコードデバッガに渡します。APIをデバッグするCLRデバッガインタフェースは、パブリックAPIを持つ唯一のメンバーです。

CLRデバッグAPIは、クロスまたはプロセスを使用してリモートコンピュータを横切ってサポートしていない、APIアーキテクチャの次の図に示されているようである、APIデバッガの使用は、独自のプロセス内でこれを実行しなければなりません。この図に示すデバッガとそのAPIが存在するとCLRデバッグCLR相互作用の異なる成分の位置。

CLRデバッグAPIアーキテクチャ

CLRデバッガのアーキテクチャ

マネージドコード・デバッガ

あなたはサポートのみマネージコードのデバッガを構築することができます。「ソフト・プラス」メカニズムを使用することにより、CLRはこのデバッガは、必要に応じてプロセスにアタッチできるようにするAPIをデバッグします。プロセスにアタッチソフトデバッガは、プロセスから分離することができます。

スレッド同期

CLRデバッグAPIの要件とプロセスアーキテクチャは、関連競合しています。一方では、多くの理由デバッグロジックとデバッグ中のプログラムのためにも非常に説得力の同じプロセスに残りますが、。しばしば機能によってではなく、メモリレイアウトを処理するためにそれらを固定することにより、例えば、複雑なデータ構造。ダイレクトコール機能より簡単に(代わりにデータ構造デコードを処理しようとしているの外側から)。デバッグロジックのための別の理由は、それによって性能を向上させる、プロセス間通信のオーバーヘッドを排除する同じプロセスで残ります。最後に、CLRデバッガの重要な特徴は、ユーザーコード内でオブジェクトが存在試運転のプロセスで実行する機能があり、ターゲットのデバッグプロセスでいくつかの協力が必要であることは明らかです。

一方、CLRデバッガは、外部プロセスから正確に行うことができますアンマネージコードのデバッグ、と共存しなければなりません。インプロセスデバッガは、オペレータおよび最大エクステントをデバッグする対象プロセスデバッガとの間の相互作用を減少させるために加えて、外部プロセスデバッガは、インプロセスのデバッガーよりも安全です。

そのためこれらの相反する要件のため、様々な方法の内容の一部は、結合CLRデバッグAPIになります。プライマリデバッグインタフェースは、プロセス外、およびネイティブのWin32デバッグサービスが共存して配置されています。しかし、CLRデバッグAPIは、安全にユーザプロセス内のコードを実行できるようにするために、ターゲット機能の試運転プロセスと同期して追加します。この同期動作を行うために、APIは無関係スレッドおよびプロセスのすべてのスレッドの実行時の状態における休止の位置で動作を中断しないように、オペレーティングシステムとCLRと協力します。その後、デバッガは特別なスレッドでコードを実行することができ、スレッドは実行時の状態を確認し、必要なコールユーザーコードであればできます。

マネージドコード実行ブレークポイント命令または例外が発生した場合、コントローラは、実行時に通知します。このコンポーネントは、スレッドは、マネージコードと実行されているアンマネージドコードのスレッドを実行して決定します。マネージコードを実行しているスレッドが安全に一時停止状態に達することができる前に、一般的に、それはこれらのスレッドを継続することができます。例えば、彼らは継続的なガベージコレクションを完了する必要があります。安全な状態を達成するために、コードのスレッドを管理する場合、すべてのスレッドが中断されています。次に、デバッガインタフェースは、デバッガがブレークポイントまたは例外を受信した通知します。

アンマネージコードが例外又は命令実行ブレークポイントを生成する場合、デバッガ・インターフェース・コンポーネントは、デバッグのWin32 APIを介して通知を受けます。この通知は、管理対象外のデバッガに渡されます。デバッガのニーズが同期を実行するかどうかを決定する制御装置が実行する同期(例えば、マネージドコードのスタックフレームをチェックすることができるようにするために)、デバッガインタフェースは、デバッグ対象プロセスの停止を再起動し、実行時に通知しなければなりません。その後、同期が完了すると、デバッガインタフェースを通知します。この同期は、アンマネージデバッガに対して透過的です。

同期処理中にブレークポイント命令実行スレッドまたは異常を生成しなくてもよいです。この要件の実装を容易にするために、デバッガインタフェースは、スレッドのスレッドを制御するために、フィルタのチェーンに特殊例外フィルタを置きました。あなたがスレッドを再起動すると、スレッドは、例外フィルタが実行するスレッドう例外フィルタコントローラコントロールを入力します。チェーンが例外を処理(又は異常をキャンセル)し続ける一般例外フィルタは、フィルタのスレッドの制御に戻さまたは続行する正しい結果を返すであろう。

まれに、異常なスレッドはロックを開くために、次に実行を完了するために同期する、重要なロックを有することができるネイティブ生成します。(典型的には、これらのロックは、mallocのヒープロックのような低レベルライブラリロック、あろう。)これらのケースでは、同期動作がタイムアウトになり、失敗します。また、これは同期させる必要がある特定の操作の失敗につながります。

ヘルパースレッドのプロセス

APIをデバッグするCLRの正常な動作を保証するためにのみデバッガヘルパースレッドを使用して、各CLRプロセス。このヘルパースレッドは、多くのデバッグAPIが提供する検査サービス、およびいくつかのケースでは、ヘルプスレッド同期を処理する責任があります。あなたは、ヘルパースレッドを識別するためにICorDebugProcess :: GetHelperThreadIDの方法を使用することができます。

JITコンパイラとの対話

デバッグリアルタイム(JIT)コンパイルされたコードにデバッガを有効にするには、CLRデバッグAPIは、関数のネイティブ版の機能のマイクロソフト中間言語(MSIL)バージョンをマップすることができなければなりません。この情報は、ローカル変数の順序と位置情報のポイントコードを含みます。.NET Framework Version 1.0および1.1では、場合にのみ、デバッグモードでは、この情報が生成されます。.NET Framework 2.0で、かつ、常にこの情報を持つことになります。

また、高度にJITコンパイルされたコードを最適化します。最適化実行するために呼び出されるネイティブコード機能付きMSILコードとの間の関係が失われる可能性があり(共通部分式除去、関数内のインライン展開、ループ展開、コード検査、等のような)。したがって、これらの取り組みは真剣にコードの最適化方法のJITコンパイラが正しく情報をマッピングする機能を提供して影響を与えます。だから、時々、デバッグモードでの実行を実行して、JITコンパイラは、いくつかの最適化を実行しません。この制限は、デバッガを正確にローカル変数とパラメータマッピング及び位置の全てのソース線を決定することができることができます。

デバッグモード

CLRデバッグAPIは、次の2つの特別なデバッグモードが用意されています。

  • 「エディットコンティニュ」モード。この場合、ランタイムは、後にコードを変更するさまざまな方法で実行することができるようになります。いくつかのランタイムデータ構造のレイアウトをサポートするために異なっていなければならないので、これはある「編集を続行します。」これは、パフォーマンスにマイナスの影響を持っているので、あなたが「編集をして続ける」を使用機能をする場合を除き、そう、あなたはこのモードで実行しないでください。

  • デバッグモード。このモードでは、JITコンパイラが最適化を無視することができますことができます。したがって、ネイティブコード、高レベル言語ソースコード、その実行をもっと作ることができます。それ以外の場合は必要な場合を除き、このモデルはまた、パフォーマンスに悪影響があるため、このモデルを使用しないでください。

「エディットコンティニュ」外部モードデバッガではなく、「編集と継続」であれば機能を。サポート デバッガデバッグモードの外にいる場合、それはまだ、デバッグ機能のほとんどをサポートしますが、最適化は、異常な動作を引き起こす可能性があります。例えば、方法のラインの間のランダムな選択のようなシングルステップルックスは、インラインメソッドは、スタックトレースに表示されないこと。

あなたは、自分のコントロールのプロセスを開始する前に、実行時にデバッガを取得した場合、デバッガは、プログラム「の編集をして続行」を有効にすることができますモードとデバッグモードCLRデバッグAPIを。これは、多数の目的を達成するのに十分です。しかし、それはいくつかの時間のために実行されているこれらのモードを起動しませんプロセスデバッガ(例えばJITをデバッグ中など)が取り付けられています。

これらの問題のヘルプの契約には、JITモードまたはデバッグモードで独立して、デバッガのプログラムを実行することができます。デバッグを有効にする方法については、デバッグ、追跡および分析を参照してください。

アプリケーション最適化JITデバッグを低減することができます。CLRデバッグAPIは、ローカル変数とスタックフレームの検査を可能にするために、JITコンパイラ最適化されたコードを使用しています。シングルステップ実行がサポートされていますが、しかし、不正確になることがあります。あなたは農産物コードのデバッグに最適化されたすべてのJITを無効にするには、JITコンパイラを指示するプログラムを実行することができます。

おすすめ

転載: www.cnblogs.com/yilang/p/11867731.html