2016-08-11 3 views
2

私はMDBGサンプルを使用してマネージド.NETデバッガを作成しています。デバッガStepInto自動生成コードとJMCの問題

現在、私はStepIntoの動作に苦しんでいますが、StepOutとStepOverは動作するようです。

Just-My-Codeステッピングを達成するには、モジュールロード時にSetJMCStatusを呼び出しています。それは正常に動作し、私は自分のコードをデバッグすることができます。

しかし、私はJMCとしてモジュール全体を設定しているので、自動生成されたコードがいくつか登場し、踏み込んでしまいます。そのようなコードの例は、自動プロパティである可能性があります。

デバッガはstep-intoを使って私のモジュールの一部であるため、step-intoで私のコードとしてマークされているget_propertyNameset_propertyNameというメソッドを自動的に生成しています。

このような自動生成コードを自分のコードと区別するために、自動生成コードの場合には欠けているデバッグシンボルの存在を使用できます。そして、私は単純にメソッドをステッピング中にスキップするコードとしてマークすることができます。

問題は、ステッピング中に内部に入る前に、どのメソッドが自動生成されているのかわかりません。私はデバッグシンボルを持たないメソッドの中に足を踏み入れたとき、自分のコードではないとマークすることができますが、それは遅すぎます - デバッガは停止しないところで停止しました。

理論的には私はIMetadataImportを使用して、私のモジュール方法を反復して、デバッガの起動時にそのJMCStatusを設定するが、それは非常に高価と思われる可能性があり:

foreach (var methodToken in mdbgModule.Importer.EnumerateAllMethodTokens()) { 
       var func = mdbgModule.GetFunction(methodToken); 
        if (func.SymMethod == null) 
         func.CorFunction.JMCStatus = false; 
      } 

だけ私が次に実行するために何が起こっているかの関数を知っているだろう場合は、私はその状態を設定して、自動生成されたコードの中で初めてステッピングするのを防ぐことができます。

ステッピングのためのMDBGアプローチは何も変えずに、SetJMCStatusを必要な場所に呼び出すので、コードを提供するのが適切かどうかはわかりません。もしそうなら、私は質問、ちょうどコメントを追加!

トピックに関するご意見をお待ちしております。

よろしく、

答えて

1

マイク・ストールhinted一つの選択肢で、あなたはモジュール全体のためにJMCを設定し、とき、デバッガステッパーブレークは、この方法は、デバッグ可能であるかどうかをチェックし、そうでない場合、それはJMC状態だ無効にでき、ステッパーを再実行します。 (再開するステッパーがステップインする前に脱出する必要がある場合、これが動作に変化をもたらすかどうかはわかりません)

おそらく、pdbが利用可能なモジュール[DebuggerNonUserCode](おそらく[DebuggerHidden])のクラス/メソッドでJMCを無効にすることによって、しかし、すべてのクラス/メソッドを列挙し、それらが属性を持っているかどうかを調べるのではなく、カスタム属性を列挙して戻します(IMetaDataImport::EnumCustomAttributesではtkTypeが設定されていますが、tkではなく、IMetaDataImport::GetCustomAttributePropsを使って適用されます)。

メソッドレベルで適用される場合は[CompilerGenerated]属性と似たような処理を実行できますが、クラスレベルで適用すると誤検出することがあります(コンパイラはイテレータと非同期メソッドのステートマシンに適用しますがどちらも非生成コードを持つ可能性が高い)。

+0

ありがとう、ブライアン!私はMike Stallの記事を何度か読んだことがありますが、今でも私はそれからヒントを得ることができませんでした!とにかく、ステッパーを再実行することは、驚異的なアイデアのようです!私はすぐにそれを試し、あなたに知らせるでしょう。 CompilerGenerated属性の問題は、プロパティget/setにユーザコードが含まれることがあることです。 – 3615

+0

Btw、私は最初のアイデアに関連したいくつかのコードで質問を更新しました。 IMetadataTables.GetTableInfoからmethodDefsの数を取得し、ICorDebugModule.GetFunctionFromTokenで使用されるシーケンシャルトークンを作成しています。 – 3615

+0

私が言及したヒントは、最後の2番目の段落の最後の文にあります。これにより、デバッガは、ユーザがそのメソッドで最初に停止するまで、JMCステータスの設定を遅らせることもできます。 –

関連する問題