Visual Studioデバッガーを使用して値が変更されたときに中断する


198

変数にウォッチを配置し、その値が変更されたときにのみVisual Studioを中断させる方法はありますか?

トリッキーな状態の問題を見つけるのが非常に簡単になります。

これはできますか?

ブレークポイント条件にはブレークポイントセットが必要です。ウォッチを設定し、状態の変化時にVisual Studioにブレークポイントを設定させます。


ただし、条件が満たされない限り、ブレークポイントは何にも影響を与えないので、ブレークポイントを(Setterのように)どこにでも配置してそこから取得できます。それとも何か不足していますか?
オスカー

6
上手。これは、デバッグのvb6の方法に似ています。ブレークポイントの場所は気にしません。ちょうどウォッチウィンドウに条件式を追加し、VB6は、条件が満たされたところはどこでも中断します島嶼地区などでしょう...
ガルザーナジム

申し訳ありませんが、セッターが進むべき道であると私が知っている限り、道を見たことがない
Oskar

1
より良いニュースを見つけたいと思っていました。vs2010は変更がないことを示していますmsdn.microsoft.com/en-us/library/350dyxd0.aspxネイティブc ++だけがこの@Scottguを持っているので、もっと上手にできます!
gerryLowry

回答:


134

Visual Studio 2005メニュー:

デバッグ -> 新しいブレークポイント -> 新しいデータブレークポイント

入る:

&myVariable

38
これはマネージコードで利用できますか?このオプションはC#プロジェクトでは無効になっています。これは、ガベージコレクタが関係している場合に、管理対象アプリのデバッグで実装するのが難しい機能です。
Gulzar Nazim

27
残念ながらアンマネージコードでのみ使用できます:msdn.microsoft.com/en-us/library/350dyxd0.aspx
Josh Kodroff 2008年

17
また、フィールドを一時的にプロパティに変換し、ゲッターまたはセッターにブレークポイントを設定することもできます。
Jon Davis

12
「デバッグ->新しいブレークポイント」の下の「データブレークポイント」オプションが無効になっています。実際にデバッグしているのかどうかに関わらず、無効のままです。私は、Visual Studio 2015を使用している
JBB

2
少し遅いですが、@ jbbはデバッグ中にブレークポイントで停止したときにのみ有効になります。
Allball103 2018

27

コードで明示的に中断することもできます。

// Assuming C#
if (condition)
{
    System.Diagnostics.Debugger.Break();
}

MSDNから:

Debugger.Break:デバッガーが接続されていない場合、ユーザーはデバッガーを接続するかどうかを尋ねられます。はいの場合、デバッガーが開始されます。デバッガーが接続されている場合、デバッガーはユーザーブレークポイントイベントで通知され、デバッガーブレークポイントにヒットした場合と同様に、デバッガーはプロセスの実行を中断します。

ただし、これはフォールバックにすぎません。他のコメントで説明されているように、Visual Studioで条件付きブレークポイントを設定する方が適切です。


2
FWIW、エディットコンティニューを使用して、私はこの方法を使用することを好みます:IME、条件付きブレークポイントは遅い
Mark Sowul

これは機能しますが、非常に苦痛です-私は結局同じようなことをしました-私はこれを私が疑ったすべてのメソッドの上部に置きました-そして再び下部に(finally節で)-その方法で私は正確にどれを知っていましたメソッドが問題を引き起こしていました(つまり、メソッドに入る前にデータが良好で、メソッドを終了する前に不良であることがわかっていました)。
BrainSlugs83

26

本当に古い投稿ですが、誰かが知らない場合に備えて...

Visual Studio 2015、あなたは上のブレークポイントを置くことができset、自動実装プロパティのアクセサとプロパティが更新されたときにデバッガが解除されます

public bool IsUpdated
{
    get;
    set;    //set breakpoint on this line
}

更新

あるいは; @AbdulRaufMujahidがコメントで指摘しているように、自動実装プロパティが1行にある場合、カーソルをget;またはに置いてset;ヒットするF9と、ブレークポイントがそれに応じて配置されます。いいね!

public bool IsUpdated { get; set; }

5
自動実装されたプロパティが1行である場合でも、たとえば、パブリック文字列UserName {set; 取得する; }。ユーザーはゲッターまたはセッターを強調表示し、F9を押してブレークポイントを追加できます
Abdul Rauf

@hikakinどうも!
Craig

13

次の宣言を含むAというクラスがあるとします。

class A  
{  
    public:  
        A();

    private:
        int m_value;
};

誰かが「m_value」の値を変更したときにプログラムを停止したい。

クラス定義に移動し、Aのコンストラクターにブレークポイントを設定します。

A::A()
{
    ... // set breakpoint here
}

プログラムを停止したら:

デバッグ->新しいブレークポイント->新しいデータブレークポイント...

アドレス:&(this-> m_value)
バイト数:4(intは4バイトなので)

これでプログラムを再開できます。値が変更されると、デバッガーは停止します。

継承クラスまたは複合クラスでも同じことができます。

class B
{
   private:
       A m_a;
};

アドレス:&(this-> m_a.m_value)

検査する変数のバイト数がわからない場合は、sizeof演算子を使用できます。

例えば:

// to know the size of the word processor,  
// if you want to inspect a pointer.
int wordTam = sizeof (void* ); 

「コールスタック」を見ると、変数の値を変更した関数を確認できます。


1
それで、私が探しているものが自分のクラスにない場合、正確にはどうしますか?たとえば、コントロールが有効または無効になる場所を正確に見つけようとしていますか?確かに、デバッグ中にコントロールのEnabled値に監視を追加できますが、変更時に制御を中断して停止した場所を確認する方法はありません。
Nyerguds 2011年

2
外部ライブラリをデバッグしようとすると、デバッグモードでコンパイルされたライブラリが必要になります。私はコンポーネントに慣れていませんが、「コールバック」をプロパティに接続して、ブレークポイントを中に入れることができます。私が説明するフォームにはメモリアドレスが必要です。それを知る方法がない場合は、他の方法を検索する必要があります。
momboco 2011年

9

変数をプロパティに変更し、setメソッドにブレークポイントを追加します。例:

private bool m_Var = false;
protected bool var
{
    get { 
        return m_var;
    }

    set { 
        m_var = value;
    }
}

3

WPFを使用している場合は、WPF Inspectorというすばらしいツールがあります。
自身をWPFアプリにアタッチし、すべてのプロパティを含むコントロールのツリー全体を表示します。これにより、(特に)プロパティの変更を中断できます。

しかし、残念なことに、任意のプロパティまたは変数で同じことを実行できるツールが見つかりませんでした。



2

ブレークポイントを右クリックするとうまくいきます(ほとんどの場合、特定の変数値の条件付きブレークポイントに使用していますが、スレッド名を含む式でブレークしても機能します。これは、スレッドの問題を見つけようとする場合に非常に便利です)。


2

ピーター・モーテンセンが書いたように:

Visual Studio 2005メニュー:

デバッグ->新しいブレークポイント->新しいデータブレークポイント

入力:&myVariable

追加情報:

明らかに、システムはメモリ内のどのアドレスを監視するかを知っている必要があります。したがって、通常のブレークポイントをmyVariable(またはmyClass.m_Variable)の初期化に設定します。システムを実行し、そのブレークポイントで停止するまで待ちます。-これでメニューエントリが有効になり、と入力して変数を監視し&myVariableたり、次のように入力してインスタンスを監視したりできます&myClass.m_Variable。これでアドレスが明確になりました。

すでに与えられた解決策を説明することによって私が間違ったことをしたとき申し訳ありません。しかし、私はコメントを加えることができませんでした、そしてこれに関していくつかのコメントがありました。


1

アンマネージコードでメモリウォッチポイントを使用できます。ただし、これらがマネージコードで使用できるかどうかはわかりません。


1

おそらく、DebugBreak()関数を上手に使用できます。


正確には?タイトなループで別のスレッドを実行し、変更が発生するたびにDebugBreak()を呼び出すことによって?
nalply 2013年

@nalpyたとえば、myVariableが使用されている場所を追跡し、その値を使用後に補助previousValue変数に格納し、次にDebugBreak()を呼び出すことができmyVariable!=previousValueます。次に、どのコードブロックmyVariableが変更されたかがわかります。しかし、AShellyのソリューションが最善であることに同意します。
wipは2013年

1

オプションで、変数の=演算子をオーバーロードし、オーバーロードされた関数内に特定の条件でブレークポイントを置くことができます。


1

2019年の更新:

これは、.Net Core 3.0以降のVisual Studio 2019 Preview 2で正式にサポートされるようになりました。もちろん、IDEのプレビューバージョンを使用することの潜在的なリスクを考慮しなければならない場合もあります。近い将来、これは公式のVisual Studioに含まれると思います。

https://blogs.msdn.microsoft.com/visualstudio/2019/02/12/break-when-value-changes-data-breakpoints-for-net-core-in-visual-studio-2019/

幸い、データブレークポイントは、Visual Studio 2019 Preview 2の.NET Core(3.0以降)で使用できるようになったため、C ++専用ではなくなりました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.