如何为堆栈上的变量设置写观察点
How to set a write watchpoint for a variable on the stack
在我的代码中,我有
mov x21, 0
str x21, [x29, 16]
然后在代码中,
ldr x22, [x29, 16]
将0存入x22。
然后,甚至在代码的后面,我有
ldr x23, [x29, 16]
最终将 214748364800 存储到 x23 中,即使在两个 ldr
命令之间没有 str
命令。
我的问题是如何为堆栈上的 [x29, 16]
位置设置一个观察点,以便我可以看到它何时被写入?
我正在使用 gdb 进行调试。
编辑:
这是我在 x29+16 位置
上设置手表时 gdb 输出的一部分
Breakpoint 2, 0x0000000000400668 in inittest ()
1: x/i $pc
=> 0x400668 <inittest+8>: mov x21, #0x0 // #0
(gdb) ni
0x000000000040066c in inittest ()
1: x/i $pc
=> 0x40066c <inittest+12>: str x21, [x29,#16]
(gdb) p/x $x29+16
= 0x3fffffff340
(gdb) x/x $x29+16
0x3fffffff340: 0xb8002d40
(gdb) watch *(int*)0x3fffffff340
Hardware watchpoint 5: *(int*)0x3fffffff340
(gdb) c
Continuing.
Hardware watchpoint 5: *(int*)0x3fffffff340
Old value = -1207947968
New value = 0
0x0000000000400670 in inittest ()
1: x/i $pc
=> 0x400670 <inittest+16>: b 0x4006d8 <testOut>
稍后在 gdb 输出中:
(gdb) p $x24
= 103
(gdb) x/x $x29+24
0x3fffffff348: 0x00000000
(gdb) ni
0x00000000004006b4 in testIn ()
1: x/i $pc
=> 0x4006b4 <testIn+16>: ldr x24, [x29,#16]
(gdb) x/x $x29+16
0x3fffffff340: 0x00000000
(gdb) ni
如果我在这里输入 p$x24
,它会显示 214748364800
,即使它是从持有 0
的 [x29,#16]
加载的
0x00000000004006b8 in testIn ()
1: x/i $pc
=> 0x4006b8 <testIn+20>: ldr w23, [x19,x21,lsl #2]
(gdb) ni
0x00000000004006bc in testIn ()
1: x/i $pc
=> 0x4006bc <testIn+24>: str w23, [x29,#28]
(gdb)
0x00000000004006c0 in testIn ()
1: x/i $pc
=> 0x4006c0 <testIn+28>: ldr w23, [x19,x24,lsl #2]
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0x00000000004006c0 in testIn ()
1: x/i $pc
=> 0x4006c0 <testIn+28>: ldr w23, [x19,x24,lsl #2]
由于内存分配
,x24
最多只能达到约 54
,因此出现错误
how do i set a watchpoint for the [x29, 16] location
您描述的不是固定位置 -- 它取决于 x29
的值(您确定 x29
在两个指令之间不会改变吗?)。
在ldr x23, [x29, 16]
处,找出错误值的位置是什么:
(gdb) p/x $x29+16 # this is the location you'll want later
(gdb) x/x $x29+16 # should show 0x3200000000 == 214748364800
现在在第一条指令上设置断点并重新运行程序。遇到断点后,验证您期望的值是否为 really:
(gdb) x/x 0x... # should be 0, not 0x3200000000
并设置观察点:
(gdb) watch *(int*)0x....
(gdb) continue
...当值更改时 GDB 应该停止。
在我的代码中,我有
mov x21, 0
str x21, [x29, 16]
然后在代码中,
ldr x22, [x29, 16]
将0存入x22。 然后,甚至在代码的后面,我有
ldr x23, [x29, 16]
最终将 214748364800 存储到 x23 中,即使在两个 ldr
命令之间没有 str
命令。
我的问题是如何为堆栈上的 [x29, 16]
位置设置一个观察点,以便我可以看到它何时被写入?
我正在使用 gdb 进行调试。
编辑: 这是我在 x29+16 位置
上设置手表时 gdb 输出的一部分Breakpoint 2, 0x0000000000400668 in inittest ()
1: x/i $pc
=> 0x400668 <inittest+8>: mov x21, #0x0 // #0
(gdb) ni
0x000000000040066c in inittest ()
1: x/i $pc
=> 0x40066c <inittest+12>: str x21, [x29,#16]
(gdb) p/x $x29+16
= 0x3fffffff340
(gdb) x/x $x29+16
0x3fffffff340: 0xb8002d40
(gdb) watch *(int*)0x3fffffff340
Hardware watchpoint 5: *(int*)0x3fffffff340
(gdb) c
Continuing.
Hardware watchpoint 5: *(int*)0x3fffffff340
Old value = -1207947968
New value = 0
0x0000000000400670 in inittest ()
1: x/i $pc
=> 0x400670 <inittest+16>: b 0x4006d8 <testOut>
稍后在 gdb 输出中:
(gdb) p $x24
= 103
(gdb) x/x $x29+24
0x3fffffff348: 0x00000000
(gdb) ni
0x00000000004006b4 in testIn ()
1: x/i $pc
=> 0x4006b4 <testIn+16>: ldr x24, [x29,#16]
(gdb) x/x $x29+16
0x3fffffff340: 0x00000000
(gdb) ni
如果我在这里输入 p$x24
,它会显示 214748364800
,即使它是从持有 0
[x29,#16]
加载的
0x00000000004006b8 in testIn ()
1: x/i $pc
=> 0x4006b8 <testIn+20>: ldr w23, [x19,x21,lsl #2]
(gdb) ni
0x00000000004006bc in testIn ()
1: x/i $pc
=> 0x4006bc <testIn+24>: str w23, [x29,#28]
(gdb)
0x00000000004006c0 in testIn ()
1: x/i $pc
=> 0x4006c0 <testIn+28>: ldr w23, [x19,x24,lsl #2]
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0x00000000004006c0 in testIn ()
1: x/i $pc
=> 0x4006c0 <testIn+28>: ldr w23, [x19,x24,lsl #2]
由于内存分配
,x24
最多只能达到约 54
,因此出现错误
how do i set a watchpoint for the [x29, 16] location
您描述的不是固定位置 -- 它取决于 x29
的值(您确定 x29
在两个指令之间不会改变吗?)。
在ldr x23, [x29, 16]
处,找出错误值的位置是什么:
(gdb) p/x $x29+16 # this is the location you'll want later
(gdb) x/x $x29+16 # should show 0x3200000000 == 214748364800
现在在第一条指令上设置断点并重新运行程序。遇到断点后,验证您期望的值是否为 really:
(gdb) x/x 0x... # should be 0, not 0x3200000000
并设置观察点:
(gdb) watch *(int*)0x....
(gdb) continue
...当值更改时 GDB 应该停止。