GDB の「メモリ アクセス」にブレークポイントを設定できますか?
-
09-06-2019 - |
質問
gdb を介してアプリケーションを実行していて、特定の変数がアクセスまたは変更されるたびにブレークポイントを設定したいと考えています。これを行うための良い方法はありますか?また、C/C++ で変数を監視して変数が変化するかどうか、いつ変化するかを確認する他の方法にも興味があります。
解決
時計 書き込み時にのみ中断されます。 アールウォッチ 読み取り時に中断させて、 ウォッチ 読み取り/書き込み時に中断できるようにします。
メモリの場所に読み取りウォッチポイントを設定できます。
gdb$ rwatch *0xfeedface
Hardware read watchpoint 2: *0xfeedface
ただし、rwatch および awatch コマンドには 1 つの制限が適用されます。式でGDB変数を使用することはできません。
gdb$ rwatch $ebx+0xec1a04f
Expression cannot be implemented with read/access watchpoint.
したがって、自分で拡張する必要があります。
gdb$ print $ebx
$13 = 0x135700
gdb$ rwatch *0x135700+0xec1a04f
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
gdb$ c
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
Value = 0xec34daf
0x9527d6e7 in objc_msgSend ()
編集: ああ、ところで。どちらかのハードウェアが必要です またはソフトウェアサポート. 。ソフトウェアは明らかにはるかに遅いです。OS がハードウェア ウォッチポイントをサポートしているかどうかを確認するには、 can-use-hw-watchpoints 環境設定。
gdb$ show can-use-hw-watchpoints
Debugger's willingness to use watchpoint hardware is 1.
他のヒント
最初の答えが C のような構文を参照していると仮定します。 (char *)(0x135700 +0xec1a04f)
それからやるべき答え rwatch *0x135700+0xec1a04f
間違っています。正しい構文は次のとおりです rwatch *(0x135700+0xec1a04f)
.
の欠如 ()
そのため、ウォッチポイントを自分で使用しようとすると非常に苦労しました。
あなたが探しているものは と呼ばれるものです ウォッチポイント.
使用法
(gdb) watch foo
:の値に注目してください 変数 foo
(gdb) watch *(int*)0x12345678
:が指す値に注目してください 住所, 、必要な型にキャストされます
(gdb) watch a*b + c/d
:勝手に見る 複雑な表現, 、プログラムの母国語で有効です
ウォッチポイントには次の 3 種類があります。
- 時計:gdb は次の場合に壊れます。 書く 発生する
- アールウォッチ:gdb は次の場合に壊れます 読む 発生する
- ウォッチ:gdbが侵入します どちらの場合も
ニーズに合わせてより適切なものを選択できます。
詳細については、こちらをご確認ください これ 外。
私はちょうど次のことを試しました:
$ cat gdbtest.c
int abc = 43;
int main()
{
abc = 10;
}
$ gcc -g -o gdbtest gdbtest.c
$ gdb gdbtest
...
(gdb) watch abc
Hardware watchpoint 1: abc
(gdb) r
Starting program: /home/mweerden/gdbtest
...
Old value = 43
New value = 10
main () at gdbtest.c:6
6 }
(gdb) quit
したがって、可能であるように見えますが、ハードウェアのサポートが必要なようです。
上で述べたように、watch を使用して変数が書き込まれるとき、rwatch を読み取るとき、awatch を使用して変数が読み書きされるとき、または変数に書き込まれるときを確認します。ただし、このコマンドを使用するには、プログラムを中断する必要があり、プログラムを中断したときに変数がスコープ内に存在する必要があることに注意してください。
監視コマンドを使用します。Watchコマンドへの引数は、評価される式です。これは、ウォッチポイントを設定したいバリアベルが現在の範囲にある必要があることを意味します。したがって、非グローバル変数にウォッチポイントを設定するには、変数が範囲にあるときにプログラムを停止するブレークポイントを設定する必要があります。プログラムが壊れた後、ウォッチポイントを設定します。