2017-08-08 8 views
0

私はVSIXを使用してVisual Studioのデバッガプラグインの開発に取り組んでいます。私の問題は、アドレスの配列がありますが、IDebugMemoryBytes2を特定のアドレスに設定できません。 DEBUG_PROPERTY_INFOを使用してアドレスの配列を取得し、IDebugMemoryContext2のAdd関数を使用して配列の特定のアドレスにコンテキストを設定することもできます。しかし、(IDebugMemoryBytes2の)指定されたアドレスからnバイトを読み出すためにReadAt関数を使用する必要があります。VSIXを使用して任意のメモリアドレスからデータを取得

メモリから任意のアドレスからデータを取得する方法はありますか?

私は同じのより多くの情報を追加してい:

私は、デバッガのプラグインを構築するために、Microsoft Visual Studioの拡張パッケージを使用しています。私はこのプラグインを使用してデバッグしようとしているアプリケーションでは、ダブルポインタがあり、それらをさらにプラグインで処理するためにそれらの値を読み取る必要があります。このため、ウォッチウィンドウにすべてのポインタ変数を表示する方法がないため、ポインタ変数が指すすべての配列ブロックに対してDEBUG_PROPERTY_INFOを取得できません。これは私が取り組もうとしている私の問題です。この二重ポインタが指すメモリを読み取る方法はありません。

デバッグプロセスのイベントについては、プラグインが変数をデバッグするためのものであるため、このポインタに値が設定されていることを知っている場所にブレークポイントを設定してプラグインに戻って評価します。

はじめに、私は何とか各アレイの開始アドレスを得ることができました。しかし、まだ、これらの開始アドレスのそれぞれからxバイトのメモリを読み取ることはできません。

すなわち、例えば、私がint ** ptrは= //何か

を指している場合、私は[0] PTRに存在するアドレスを持っている、PTR [1]、PTR [2]などしかし、私はこれらのアドレスのそれぞれに行き、彼らが指しているメモリブロックをフェッチする必要があります。

多くの検索の後、私はこのリンクを見つけました:https://macropolygon.wordpress.com/2012/12/16/evaluating-debugged-process-memory-in-a-visual-studio-extension/これはちょうど私の問題に対処しているようです。

Expression Evaluator関数を使用するには、ExpressionContextを取得するためにIDebugStackFrame2オブジェクトが必要です。このオブジェクトを取得するには、ブレークポイント用のデバッグプロセスでイベントに登録する必要があります。

public int Event(IDebugEngine2 engine, IDebugProcess2 process, 
       IDebugProgram2 program, IDebugThread2 thread, IDebugEvent2 
       debugEvent, ref Guid riidEvent, uint attributes) 
{ 
    if (debugEvent is IDebugBreakpointEvent2) 
    { 
     this.thread = thread; 
    } 

    return VSConstants.S_OK; 
} 

そして、私の登録は次のようである::ポストで言ったように、私がやった

private void GetCurrentThread() 
{ 
    uint cookie; 
    DBGMODE[] modeArray = new DBGMODE[1]; 
    // Get the Debugger service. 
    debugService = Package.GetGlobalService(typeof(SVsShellDebugger)) as 
                   IVsDebugger; 
    if (debugService != null) 
    { 
     // Register for debug events. 
     // Assumes the current class implements IDebugEventCallback2. 
     debugService.AdviseDebuggerEvents(this, out cookie); 
     debugService.AdviseDebugEventCallback(this); 
     debugService.GetMode(modeArray); 

     modeArray[0] = modeArray[0] & ~DBGMODE.DBGMODE_EncMask; 

     if (modeArray[0] == DBGMODE.DBGMODE_Break) 
     { 
       GetCurrentStackFrame(); 
     } 
    } 
} 

しかし、これがすべてではイベント機能を起動していないようですので、私はどのように確認していませんIDebugThread2オブジェクトを取得します。

は私も同じポストで提案されている他の方法で試してみました:

namespace Microsoft.VisualStudio.Debugger.Interop.Internal 
{ 
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("1DA40549-8CCC-48CF-B99B-FC22FE3AFEDF")] 
    public interface IDebuggerInternal11 { 
     [DispId(0x6001001f)] 
     IDebugThread2 CurrentThread { [return: 
     MarshalAs(UnmanagedType.Interface)] 
     [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = 
     MethodCodeType.Runtime)] 
     get; [param: In, MarshalAs(UnmanagedType.Interface)] 
     [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = 
     MethodCodeType.Runtime)] set; } 
    } 
} 

private void GetCurrentThread() 
{ 
    debugService = Package.GetGlobalService(typeof(SVsShellDebugger)) as IVsDebugger; 
    if (debugService != null) 
    { 
     IDebuggerInternal11 debuggerServiceInternal = 
         (IDebuggerInternal11)debugService; 
     thread = debuggerServiceInternal.CurrentThread; 

     GetCurrentStackFrame(); 
    } 
} 

をしかし、この方法では、私は私が何かをしないのですが、私はので、ラインを実行した後、何をするかわからないと思います

IDebuggerInternal11 debuggerServiceInternal = 
            (IDebuggerInternal11)debugService; 

私はdebuggerServiceInternal変数の値をチェックするとき、私はCurrentThread、CurrentStackFrameためSystem.Security.SecurityExceptionがある(参照ので、明らかに次の行がクラッシュの原因となります)。このため、私はエラーを見つけ、ComImport属性がクラスにないことがわかりました。だから私はそれを追加し、今、私はSystem.AccessViolationException:読み取りまたは保護されたメモリを書き込もうとしました。これはしばしば、他のメモリが壊れていることを示します。

私はC#プログラミングにも新しいので、短期間で多くのことを把握するのは少し難しいです。私は今どのように進むべきかについて迷っています。

私の目的を達成するために別の方法を試してみるのと同じ、または助けてもらえれば幸いです。

どうもありがとう、

Esash

答えて

0

くらい検索した後、この問題を解決する最も簡単な方法があるように私は時間の短い居ないので、私はので、迅速な解決を必要とし、今のところ、それはそう.natvisファイルをハッキングするには、ポインタのすべての要素を表示してから、IDebug *インターフェイスメソッドを使用して同じポインタを使用して、各ポインタ要素のメモリコンテキストにアクセスして取得します。しかし、msdnフォーラムで同じ質問を投稿した後、私はこの問題に対する適切な答えはGreggsの言葉通りです: "メモリを読み込むためには、これを高速に実行するには、生のメモリが必要です。ターゲットのデバッグエンジンは通常のVisual Studioネイティブエンジンです(言い換えれば、独自のデバッグエンジンを作成していない)ので、Microsoft.VisualStudio.Debugger.Engineを参照することをお勧めします。次に、DkmStackFrame.ExtractFromDTEObjectを使用してDkmStackFrameオブジェクト。これはDkmProcessオブジェクトを提供し、DkmProcess.ReadMemoryを呼び出してターゲットからメモリを読み取ることができます。

これを実装する方法を理解するために多くのことを試した結果、以下を使用してこれを達成できることが分かりました。DkmProcess.GetProcesses()およびプロセスでReadMemoryを実行しました。 ここで、複数のプロセスが返された場合はどうなるのでしょうか。さて、私は現在のデバッグプロセスに多くのプロセスを取り込み、多くのプロセスをdebuggeeプロセスにアタッチしようとしましたが、DkmProcess.GetProcesses()は、他のプロセスではなく、私は付いています。私はこれがすべてのケースでうまくいくかどうかはわかりませんが、私にとってはこのように働き、同様の要件を持っている人にとってはうまくいくかもしれません。

これを達成するために.natvisファイルを使用すると、VS2013以前のバージョンでIndexListItemsを使用し、VS2015以降のバージョンでCustomListItemsを使用して見栄えを良くするには、「派生なし」属性を使用します。 Syntheticタグに各変数のベースアドレスのみを表示させる方法はありません。したがって、上記の属性は最適な方法ですが、VS2013以前のバージョンでは使用できません(ベースアドレスは表示されますがコンテンツを表示するだけでなく、ポインタ要素のメモリコンテキストにアクセスすることを望む人は、Syntheticタグは正しいことではありません)。

IDebug *インターフェイスを使用して私のように苦労した開発者に役立つことを願っています。参考までに、私の質問に答えたmsdnフォーラムへのリンクも提供しています。

https://social.msdn.microsoft.com/Forums/en-US/030cef1c-ee79-46e9-8e40-bfc59f14cc34/how-can-i-send-a-custom-debug-event-to-my-idebugeventcallback2-handler?forum=vsdebug

感謝。

関連する問題