web-dev-qa-db-ja.com

データブレークポイントとは何ですか?

dataブレークポイントがあることを知りました。私は過去5年間、VisualStudioを使用してC++で作業してきましたが、データブレークポイントを使用したことはありません。

誰かがデータブレークポイントとは何か、それらをいつ使用するか、そしてhow VSでそれらを使用することに光を当てることができますか?

私の理解によると、変数の値の変更をチェックするときにデータブレークポイントを設定できます。この場合、変数値の条件でデータブレークポイントを設定できます。

他の例はありますか?

24
anand

定義:

データブレークポイントを使用すると、指定したメモリ位置に格納されている値が変更されたときに実行を中断できます。

MSDNから: 方法:データブレークポイントを設定する

メモリ変更ブレークポイントの設定方法

  1. [デバッグ]メニューから[新しいブレークポイント]を選択し、[新しいデータブレークポイント]をクリックします

    —または—

    [ブレークポイント]ウィンドウのメニューで、[新規]ドロップダウンをクリックし、[新しいデータブレークポイント]を選択します。

    [新しいブレークポイント]ダイアログボックスが表示されます。

  2. [アドレス]ボックスに、メモリアドレスまたはメモリアドレスに評価される式を入力します。たとえば、変数fooの内容が変更されたときにブレークする&foo。

  3. [バイト数]ボックスに、デバッガーが監視するバイト数を入力します。たとえば、4を入力すると、デバッガーは&fooで始まる4バイトを監視し、それらのバイトのいずれかが値を変更すると中断します。

  4. [OK]をクリックします。

28

古き良き Daniel LeCheminantは確かな答えを持っています what データブレークポイントが行うことについて、私は有用な使用法を強調するいくつかの逸話を投げます:

what が変更されることはわかっているが、どこでコードが変更されているかがほとんどまたはまったくわからないシナリオ(それ以外の場合は、単に使用できるため)条件付きブレークポイント)。具体的には、

「不可能」シナリオ-変数XNULLであるため、プログラムがクラッシュします。変数XNULLに設定するコードがないため、変数XNULLにすることはできません。 。 Xを初期化するコードに通常のブレークポイントを設定し、ヒットしたら、NULLへの変更を監視するデータブレークポイントを設定します。やや一般的なのは、メモリが解放されるのが早すぎる早すぎるであり、それへのポインタがまだ残っている場合です。データブレークポイントを使用して、誰がメモリを解放しているかを調べます。

面倒なシナリオ-サードパーティのライブラリがデータ構造に悪い、厄介な、恐ろしいことをしています。 someone がデータをスラッシングしていて、明らかにコードが完璧であるため、それが起こっていることはご存知でしょう。しかし、どこで、いつかはわかりません。確かに、1メガバイトの逆アセンブルされたDLLをシングルステップで実行できます...しかし、データにデータブレークポイントを設定できるのに、気にせずに座って、データが破棄されるのを待ってください。

Heisenbugs-不可能なシナリオに似ていますが、注意深く見ると消えてしまうため、通常のブレークポイント(条件付きブレークポイントであっても)は役に立ちません。タイミングとユーザー入力に敏感なロジックは、この種のことに対して特に脆弱です。データブレークポイントは、時間が正しいになるまでデバッガーが実際にブレークする必要がないため、そのとらえどころのないバグが実際に発生したときにのみ変更されるメモリ位置を考え出すことができると仮定します。データブレークポイントを使用して、Heisenbugのトラップを設定し、現行犯でそれをキャッチできます。

スパゲッティシナリオ-グローバルデータにアクセスする古い腐ったコードベースで一般的どこでも。ええ、あなたは普通の古い条件付きブレークポイントを使うことができます...しかしあなたはそれらの何百も必要になるでしょう。データブレークポイントはそれを簡単にします。

57
Shog9

これまでのところ、すばらしい定義とたくさんのすばらしい理論的説明があります。

具体的な例を見てみましょう!

私は現在、かなり大きくて複雑なコードベースに取り組んでいます。私はコードの1ビットに小さな安全な変更を加え、コードベースの完全に無関係なチャンクで、メモリアロケータでクラッシュし始めました。これは通常、メモリ管理で非常に間違った処理を行っていることを示しています。つまり、二重削除または範囲外の書き込みのいずれかです。

ありがたいことに、このようなことをチェックするデバッグメモリマネージャーをオンにするオプションがあります。オンにすると、すぐにメモリブロックガード違反の報告が始まりました。これは、何かが範囲外に書き込まれたことを意味します。問題は、このレポートは、メモリの割り当てが解除されたときにのみ表示されることです。基本的には、「ねえ、何かだった壊れています。何がわかるかわかります!」

残念ながら、この特定のメモリチャンクは、割り当て解除の時点で、文字通り何千もの他のメモリチャンクと完全に区別できません。幸い、デバッグフレームワークは各割り当てに連続したIDのタグを付け、破損したメモリには一貫したIDがありました(興味がある場合は#9667)。後でメモリマネージャーに1つのクイックブレークポイントがあり、その場所を見つけることができました。メモリが割り当てられました。結局のところ、これもすぐには役に立ちませんでした。

しかし、その時点で、私にはいくつかの重要な要素がありました。

  • 私はメモリのブロックのアドレスを知っていました
  • 私はその記憶の意図された長さを知っていました
  • 将来のある時点で、そのメモリの意図された長さを超える特定のバイトが上書きされることを私は知っていました

これを考えると、その特定のバイトにデータブレークポイントを設定し、「go」を押して、破損が発生した場所を見つけることができます。

私がやったこと-それは私が現在修正中のオフバイワンエラーにつながりました。

これは、データブレークポイントがどのように役立つかを示す具体的な例です。 :)

3
ZorbaTHut

データブレークポイントは、一部のメモリが特定の値に設定されたときに発生するブレークポイントだと思います。たとえば、通常のforループでi == 10のときにブレークポイントを設定して、10回目の反復後に停止することができます。クラスのメンバーが変更されるのを待つなど、ヒープ上の変数の変更を監視することもできます。

0
strager