5

ここ数週間、私はアンマネージ.NETデバッグAPIをいじっています。

MSDNはインターフェイス自体を文書化していますが、実際にそれらを意味のある方法で使用する方法を見つけるために、さまざまなブログ(主にMike Stall )とCLRマネージデバッガーサンプルおよびILSpyソースのマネージラッパーに頼りました。最終的に、実行中のプロセスにテストプログラムをアタッチし、ブレークポイントを設定してヒットすることができました。

次にやりたいのは、そのようなブレークポイントに到達することです。関連するオブジェクトインスタンスのフィールドを読み取ります。これは、デバッグターゲットメソッドがNGENまたはJITされていない場合に、NGENされたアセンブリの読み込みを無効にし(環境設定「COMPLUS_ZAPDISABLE = 1」)、JIT最適化を無効にする(別名「.iniファイルトリック」 )ことで正常に機能します。 )。

ただし、理想的なターゲットである小売用に最適化された(NGEN / JITされた)コードで同じことを試してみると、機能しません。たとえば、エントリブレークポイントをヒットしても、メソッド引数の数を取得できますが、最初の引数自体を取得できません(デバッグAPIは例外をスローします)。

さて、これの理由は、デバッグAPIがプラットフォームに依存しないことになっているためだと思います。この場合、アセンブリはもう存在しません。しかし、このプラットフォームのIntelへの依存関係を受け入れるとどうなりますか?CLRがfastcall呼び出し規約を使用していることを知っている限り、この場合、ECXレジスタには最初のメソッド引数(メンバー関数の暗黙の「this」参照)が含まれます。

私はこれをテストしましたが、実際にブレークポイントに到達すると、ECXにはNGENされたアセンブリにOBJECTREF(オブジェクトインスタンスのアドレス)が含まれます。

インスタンスフィールドを読み取る最後のステップは、このポインタを基準にしたフィールドオフセットを取得することです。これは、ネイティブコード生成中にCLRがインスタンスフィールドのパッキングをどのように行うかを知ることができないため、私が立ち往生している場所です。。

これはCLRのバージョン/実装に依存する可能性があることを認識していますが、SOS拡張機能を備えたWinDbgがこのレイアウトを見つけることができるため、明らかに方法があります。デバッグAPIを使用しない場合、どういうわけかSOS.dllを活用できますか?

4

1 に答える 1

0

最初の質問では、引数/ローカルが見つからない理由は、最適化されたコードをデバッグしているためです。最適化されたコードでは、args/localsを追跡できません。

2番目の質問については、オブジェクトのフィールドを読み取るために、WinDbgではSOS.dllSOSEX.dllまたはPSSCOR2/ 4.dllを使用するか、VisualStudioではSOS/PSSCORを使用する必要があります。

編集:コードからこれを実行したいことがわかりました。これには、残念ながら文書化されていないデータアクセス(DAC)APIを使用する必要があります。

于 2013-01-07T12:43:53.230 に答える