この記事では、Visual Studio でさまざまな種類のブレークポイントを使用してデバッグ効率を向上させる方法について説明します。 コードの実行の一時停止、情報のログ記録、変数の状態の変更の追跡など、ブレークポイントを適用できるさまざまなシナリオについて説明します。 この記事では、条件付きブレークポイント、トレースポイント、データ ブレークポイント、依存ブレークポイント、一時ブレークポイントを設定する方法について説明します。 また、関数ブレークポイントの設定に関する詳細な手順も含まれています。 このガイドは、Visual Studio で効果的なデバッグのためにブレークポイントを活用しようとしている開発者にとって不可欠です。
Visual Studio でのブレークポイントの使用に慣れていない場合は、「ブレークポイント の概要」を参照してから、この記事に進んでください。
このドキュメントで最適なエクスペリエンスを得る場合は、記事の上部にある一覧から好みの開発言語またはランタイムを選択してください。
シナリオ
次の表は、ブレークポイントの一般的なデバッグ シナリオと、シナリオに推奨されるブレークポイントの種類を示しています。
シナリオ | 説明 |
---|---|
実行中のコードを一時停止して、バグを含む可能性のあるコード行を検査するにはどうすればよいですか? | ブレークポイントを設定します。 詳細については、「ブレークポイントの使用を開始する」を参照してください。 |
変数に予期しない値がありますか? それとも、特定の状態に達したときにアプリを確認したいですか? | 条件付きブレークポイントを試して、条件付きロジックを使用してブレークポイントがアクティブ化される場所とタイミングを制御します。 ブレークポイントを右クリックして条件を追加します。 変数が予期しない値と等しい場合は、条件を true に設定します。 詳細については、「ブレークポイント条件 」を参照してください。 |
コードを変更したり停止したりせずに、構成可能な条件下で情報を出力ウィンドウに記録するにはどうすればよいですか? | Tracepoints を使用すると、コードを変更または停止することなく、構成可能な条件下で情報を出力ウィンドウに記録できます。 詳細については、「Visual Studio デバッガーでトレースポイントを使用する」を参照してください。 |
変数の値がいつ変わるかを知る方法 | C++ の場合は、データ ブレークポイント設定します。 .NET Core 3 以降を使用するアプリの場合は、データ ブレークポイント設定することもできます。 また、C# と F# のみに限り、条件付きブレークポイントを使用してオブジェクト ID を追跡 |
別のブレークポイントにヒットした場合にのみ実行を中断するにはどうすればよいですか? | 別のブレークポイントが最初にヒットした場合にのみ実行を中断する依存ブレークポイントを設定します。 詳細については、「依存ブレークポイント」を参照してください。 |
ブレークポイントに 1 回だけヒットできますか? | コードを 1 回だけ中断できる一時的なブレークポイントを設定します。 詳細については、一時的なブレークポイントを参照してください。 |
特定のイテレーションでループ内のコードを一時停止できますか? | 別のブレークポイントが最初にヒットした場合にのみ実行を中断する依存ブレークポイントを設定します。 詳細については、ヒット カウントに関するページを参照してください。 |
関数名がわかっているが、その場所がわからない場合、関数の開始時にコードを一時停止できますか? | これを行うには、関数ブレークポイントを使用します。 詳細については、「関数のブレークポイントを設定する」を参照してください。 |
同じ名前の複数の関数の開始時にコードを一時停止できますか? | 同じ名前の複数の関数 (異なるプロジェクトのオーバーロードされた関数) がある場合は、関数ブレークポイント使用できます。 |
ブレークポイントアクションとトレースポイント
トレースポイントは、[出力] ウィンドウにメッセージを出力するブレークポイントです。 トレースポイントはプログラミング言語の一時的なトレース ステートメントのように機能し、コードの実行が一時停止されることはありません。 トレースポイントを作成するには、[ブレークポイント設定] ウィンドウで特別なアクションを設定します。 詳細な手順については、Visual Studio デバッガーでのトレースポイントの使用に関するページを参照してください。
ブレークポイント条件
条件を設定して、ブレークポイントを実行するタイミングと場所を制御することができます。 条件には、デバッガーによって認識される有効な式を指定できます。 (有効な式の詳細については、「デバッガーの
ブレークポイント条件を設定するには:
ブレークポイントの記号を右クリックし、[条件] を選択します (または Alt + F9、C キーを押します)。 または、ブレークポイントの記号をポイントして [設定] アイコンを選択し、[ブレークポイント設定] ウィンドウで [条件] を選択します。
コード行の横にある左端の余白を右クリックし、コンテキスト メニューから [条件付きブレークポイントの挿入] を選んで、新しい条件付きブレークポイントを設定することもできます。
また、 [ブレークポイント] ウィンドウでブレークポイントを右クリックして [設定] を選び、 [条件] を選ぶことで、条件を設定することもできます
ドロップダウンで [条件式] 、 [ヒット カウント] 、または [フィルター] を選択し、それぞれに応じた値を設定します。
[閉じる] を選択するか、Ctrl+Enter キーを押して、[ブレークポイント設定] ウィンドウを閉じます。 または、[ブレークポイント] ウィンドウで、[OK] を選択してダイアログを閉じます。
ソース コードと + ウィンドウでは、条件が設定されているブレークポイントには 記号が表示されます。
条件式を作成する
[条件式] を選択するときは、次の 2 つの条件のいずれかを選択できます: [true の場合] または [変更された場合]。 式の条件を満たす場合に中断するときは [true の場合] をオンにし、式の値が変更されたときに中断するときは [変更された場合] をオンにします。
次の例では、testInt
の値が 4 の場合にのみ、ブレークポイントがヒットするように設定します。
次の例では、testInt
の値が変更された場合にのみ、ブレークポイントはヒットします。
無効な構文でブレークポイント条件を設定すると、警告メッセージが表示されます。 有効な構文でブレークポイント条件を指定しても、セマンティクスが無効な場合は、ブレークポイントに初めて達したときに警告メッセージが表示されます。 どちらの場合でも、デバッガーは無効なブレークポイントにヒットすると中断されます。 ブレークポイント条件が有効で、評価結果が false
の場合にのみ、ブレークポイントはスキップされます。
注
[変更された場合] フィールドの場合、デバッガーでは条件の最初の評価は変更とみなされないため、最初の評価ではブレークポイントにヒットしません。
条件式で オブジェクト ID を使用する (C#、F# のみ)
特定のオブジェクトの動作を観察しなければならないことがあります。 たとえば、オブジェクトがコレクションに複数回挿入された理由を確認するような場合です。 C# と F# では、参照型 の特定のインスタンスにオブジェクト ID を作成し、それらの ID をブレークポイントの条件で使用できます。 オブジェクト ID は、共通言語ランタイム (CLR) のデバッグ サービスで生成されて、オブジェクトに関連付けられます。
オブジェクト ID を作成するには:
コードで、オブジェクトが作成された後のどこかにブレークポイントを設定します。
デバッグを開始し、ブレークポイントで実行が停止したら、[デバッグ]>[ウィンドウ]>[ローカル] を選択して (または Ctrl + Alt + V、L キーを押して)、[ローカル] ウィンドウを開きます。
[ローカル] ウィンドウで特定のオブジェクト インスタンスを探し、右クリックして、[オブジェクト ID の作成] を選択します。
$ ウィンドウに、 [ローカル] ウィンドウを閉じます。 これが、オブジェクト ID です。
オブジェクトがコレクションに追加されるときなど、調査が必要となるポイントに、新しいブレークポイントを追加します。 ブレークポイントを右クリックし、[条件] を選択します。
[条件式] フィールドでは、オブジェクト ID を使用します。 たとえば、変数
item
がコレクションに追加するオブジェクトである場合、[true の場合] を選択し、「item == $<n>」と入力します。<n> はオブジェクト ID 番号です。そのオブジェクトがコレクションに追加されると、実行が停止します。
オブジェクト ID を削除する場合は、[ローカル] ウィンドウで変数を右クリックして、[オブジェクト ID の削除] を選択します。
注
オブジェクト ID による参照は弱参照であり、これによって、オブジェクトがガベージ コレクションの対象から外れることはありません。 オブジェクト ID は、現在のデバッグ セッションでのみ有効です。
ヒット カウントの条件を設定する
コード内のループがある回数の反復の後に誤動作を開始することが疑われる場合、そのヒット カウントを超えると実行を停止するブレークポイントを設定できます。これにより、目的の反復回数に達するまで何度も F5 キーを押す必要がなくなります。
[ブレークポイント設定] ウィンドウの [条件] で [ヒット カウント] を選択し、反復回数を指定します。 次の例では、反復ごとにヒットするようにブレークポイントを設定します。
フィルター条件を設定する
指定されたデバイスでのみ、または指定されたプロセスとスレッドでのみ、ブレークポイントが発生するように制限できます。
[ブレークポイント設定] ウィンドウの [条件] で [フィルター] を選択し、次の式の 1 つまたは複数を入力します。
- MachineName = "name"
- ProcessId = 値
- ProcessName = "name"
- ThreadId = 値
- ThreadName = "名前"
文字列の値を二重引用符で囲みます。 句は、 &
(AND)、 ||
(OR)、 !
(NOT)、およびかっこを使用して結合できます。
関数のブレークポイントを設定する
関数が呼び出されたときに実行を中断できます。 これは、たとえば関数名はわかっていても、その場所がわからない場合などに便利です。 また、同じ名前の関数が複数あり、それらすべてで中断したい場合にも便利です (オーバーロードされた関数や、異なるプロジェクトの関数など)。
関数のブレークポイントを設定するには:
[デバッグ]>[新しいブレークポイント]>[関数のブレークポイント] を選択するか、Ctrl + K、B. キーを押します。
また、[ブレークポイント] ウィンドウで >[関数のブレークポイント] を選択してもかまいません。
[新しい関数のブレークポイント] ダイアログで、[関数名] ボックスに関数の名前を入力します。
関数の指定を絞り込むには、次のようにします。
完全修飾関数名を使用します。
例:
Namespace1.ClassX.MethodA()
オーバーロードされた関数のパラメーターの型を追加します。
例:
MethodA(int, string)
"!" 記号を使用して、モジュールを指定します。
例:
App1.dll!MethodA
ネイティブ C++ でコンテキスト演算子を使用します。
{function, , [module]} [+<line offset from start of method>]
例:
{MethodA, , App1.dll}+2
[言語] ドロップダウンで、関数の言語を選択します。
[OK] を選択.
メモリ アドレスを使用して関数のブレークポイントを設定する (ネイティブ C++ のみ)
オブジェクトのアドレスを使用して、クラスの特定のインスタンスで呼び出されるメソッドに関数のブレークポイントを設定できます。 たとえば、my_class
型のアドレス指定可能なオブジェクトがある場合、そのインスタンスから呼び出される my_method
メソッドに関数のブレークポイントを設定できます。
クラスのそのインスタンスがインスタンス化された後のどこかにブレークポイントを設定します。
インスタンスのアドレスを見つけます (例:
0xcccccccc
)。[デバッグ]>[新しいブレークポイント]>[関数のブレークポイント] を選択するか、Ctrl + K、B. キーを押します。
以下を [関数名] ボックスに追加し、[C++] 言語を選択します。
((my_class *) 0xcccccccc)->my_method
データ ブレークポイントを設定する (.NET Core 3.x または .NET 5+)
データ ブレークポイントでは、特定のオブジェクトのプロパティが変更されたときに実行が中断されます。
データ ブレークポイントを設定するには:
.NET Core または .NET 5 以降のプロジェクトでデバッグを開始し、ブレークポイントに到達するまで待ちます。
[自動変数]、[ウォッチ]、または [ローカル] ウィンドウで、プロパティを右クリックし、コンテキスト メニューの [値が変更されたときに中断] を選択します。
.NET Core と .NET 5 以降のデータ ブレークポイントは、次の場合には機能しません。
- ツールヒント、[ローカル]、[自動変数]、または [ウォッチ] ウィンドウで展開できないプロパティ
- 静的変数
- DebuggerTypeProxy 属性を持つクラス
- 構造体内のフィールド
設定できる最大数については、データ ブレークポイントのハードウェア制限に関する記事を参照してください。
データ ブレークポイントを設定する (ネイティブ C++ のみ)
データ ブレークポイントを使用すると、指定したメモリ位置に格納された値が変更されたときに、実行が中断されます。 値が読み取られても変更されていなければ、実行は中断されません。
データ ブレークポイントを設定するには:
C++ プロジェクトでデバッグを開始し、ブレークポイントに達するまで待ちます。 [デバッグ] メニューの [新しいブレークポイント]>[データ ブレークポイント] を選択します。
または、[ブレークポイント] ウィンドウで >[データ ブレークポイント] を選択するか、[自動変数]、[ウォッチ]、または [ローカル] ウィンドウで項目を右クリックして、コンテキスト メニューの [値が変更されたときに中断] を選択することもできます。
[アドレス] ボックスに、メモリ アドレス、またはメモリ アドレスを表す式を入力します。 たとえば、「
&avar
」と入力すると、変数avar
の値が変更されたときに中断します。[バイト数] ドロップダウンで、デバッガーがウォッチするバイト数を選択します。 たとえば、 [4]を選択すると、
&avar
で始まる 4 バイトがウォッチされ、そのバイト値のいずれかが変更されると中断します。
データ ブレークポイントは次の条件では機能しません。
- デバッグ対象外のプロセスがメモリ位置に書き込む場合
- メモリ位置が 2 つ以上のプロセス間で共有されている場合
- メモリ位置がカーネル内で更新される場合 たとえば、32 ビット Windows の
ReadFile
関数にメモリが渡された場合、メモリはカーネル モードから更新されるので、更新時にもデバッガーは中断されません。 - ウォッチ式が 4 バイト (32 ビット ハードウェア) または 8 バイト (64 ビット ハードウェア) より大きい場合。 これは、x86 アーキテクチャの制限です。
注
データ ブレークポイントは、特定のメモリ アドレスに依存します。 変数のアドレスはデバッグ セッションが変わると変化するので、各デバッグ セッションの終了時に、データ ブレークポイントは自動的に無効になります。
ローカル変数にデータ ブレークポイントを設定すると、関数が終了してもブレークポイントは有効なままですが、メモリ アドレスは変更されるので、ブレークポイントは予測どおりに機能しなくなります。 データ ブレークポイントをローカル変数に設定した場合は、関数が終了する前にブレークポイントを削除するか無効にすることをお勧めします。
データ ブレークポイントのハードウェア制限
データ ブレークポイントを設定する場合、Windows カーネルと基になるハードウェアには次の制限があります。 制限とは、設定できるデータ ブレークポイントの最大数を指します。
プロセッサ アーキテクチャ | データ ブレークポイントの制限 |
---|---|
x64 および x86 | 4 |
ARM64 | 2 |
腕 | 1 |
依存ブレークポイントを設定する
依存ブレークポイントでは、別のブレークポイントが最初にヒットした場合にのみ実行が中断されます。 そのため、マルチスレッド アプリケーションをデバッグする場合などの複雑なシナリオでは、別のブレークポイントが最初にヒットした後に追加のブレークポイントを構成できます。 これにより、ゲーム ループやユーティリティ API などの共通パスにあるコードのデバッグがとても簡単になります。それらの関数内にあるブレークポイントを、その関数がアプリケーションの特定の部分から呼び出された場合にのみ有効化するように構成できるためです。
依存ブレークポイントを設定するには:
ブレークポイントの記号の上にマウス ポインターを移動し、[設定] アイコンを選んだ後、[ブレークポイントの設定] ウィンドウで [Only enable when the following breakpoint is hit]\(次のブレークポイントがヒットしたときにのみ有効化\) を選びます。
ドロップダウンから、現在のブレークポイントを依存させる前提条件のブレークポイントを選びます。
[閉じる] を選ぶか、Ctrl + Enter キーを押して、[ブレークポイント設定] ウィンドウを閉じます。 または、[ブレークポイント] ウィンドウから [OK] を選んで、ダイアログを閉じます。
また、右クリックのコンテキスト メニューを使って、依存ブレークポイントを設定することもできます。
コード行の横にある左端の余白を右クリックし、コンテキスト メニューから [条件付きブレークポイントの挿入] を選びます。
- アプリケーションにブレークポイントが 1 つしかない場合、依存ブレークポイントは機能しません。
- 前提条件のブレークポイントが削除されると、依存ブレークポイントは通常の行のブレークポイントに変換されます。
一時ブレークポイントを設定する
このブレークポイントを使うと、コードを 1 回だけ中断できます。 デバッグ時に、Visual Studio デバッガーによって実行中のアプリケーションがこのブレークポイントで 1 回だけ一時停止され、ヒットした直後にそれは削除されます。
一時ブレークポイントを設定するには:
ブレークポイントの記号の上にマウス ポインターを移動し、[設定] アイコンを選んだ後、[ブレークポイントの設定] ウィンドウで [Remove breakpoint once hit]\(ヒットしたらブレークポイントを削除する\) を選びます。
[閉じる] を選ぶか、Ctrl + Enter キーを押して、[ブレークポイント設定] ウィンドウを閉じます。 または、[ブレークポイント] ウィンドウから [OK] を選んで、ダイアログを閉じます。
また、右クリックのコンテキスト メニューを使って、一時ブレークポイントを設定することもできます。
コード行の横にある左端の余白を右クリックし、コンテキスト メニューから [Insert Temporary Breakpoint](一時ブレークポイントの挿入) を選びます。
または、単にショートカット F9 + Shift + Alt、T キーを使って、目的の行に一時ブレークポイントを設定できます。