如何为堆栈上的变量设置写入监视点

时间:2017-03-04 20:39:06

标签: assembly gdb stack armv8

在我的代码中,我有

mov x21, 0
str x21, [x29, 16]

然后在代码中

ldr x22, [x29, 16]

将0存储到x22中。 然后,即使在代码的后期,我也有

ldr x23, [x29, 16]

最终将214748364800存储到x23中,即使两个str命令之间没有ldr命令。

我的问题是如何为堆栈上的[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
$1 = 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
$4 = 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

1 个答案:

答案 0 :(得分:0)

  

如何为[x29,16]位置设置观察点

您描述的内容不是固定位置 - 取决于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

现在在第一条指令上设置一个断点并重新运行程序。一旦断点被​​击中,请确认您期望的值确实那里:

(gdb) x/x 0x...    # should be 0, not 0x3200000000

并设置观察点:

(gdb) watch *(int*)0x....
(gdb) continue

...当值发生变化时,GDB应该停止。