2017-03-04 45 views
0

在我的代码,我有如何设置一个变量写入观察点堆栈

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

再后来,

ldr x22, [x29, 16] 

存储0到X22。 然后,即使在后面的代码,我有

ldr x23, [x29, 16] 

其结束存储214748364800到X23,即使在这两个ldr命令之间没有str命令。

我的问题是我如何设置[x29, 16]位置的观察点在堆栈上,以便我可以看到它的写入时间?

我正在使用gdb进行调试。

编辑: 这是当我在gdb的输出上设置监视在X29 + 16位置

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,即使它从[x29,#16]加载0

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最大,由于内存分配

+0

在'str'上放置一个断点,然后在断点被击中时'x29 + 16'的任何值添加手表。注意你也需要确保'x29'没有改变。 – Jester

+0

如果你用'(int *)'类型的'watch',你可以试试dbg:'(gdb)print sizeof(int)'吗?如果它是4,并且你正在使用little-endian模式,那么你只能看第4个字节(保持为零),0x32发生在第5个字节。 – Ped7g

+0

我输入'print sizeof(int)'并且它说4.另外,在调用'ldr'时它加载0x3200000000而不是0,之后我输入'x/4x $ x29 + 16'来查看全部4个字节,第二个字节,而不是“0x00000000”,实际上是0x00000032。我猜这就是改变的地方。我如何在第二个字节上专门设置手表?它只是简单地设置显示我输入'p/x $ x29 + 17'的十六进制代码吗? (16是第一个字节,17是第二个等等?) –

回答

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应该停止时的价值的变化。

+0

因此,这有助于设置观察点。但事实证明,这个问题不是我认为的问题。当我执行初始'x/x $ x29 + 16'时,它应该显示0x3200000000,而不是显示0x0。因此,在该位置设置一个监视点对我来说什么都不做,因为它实际上保持为0.实际上,'ldr x23,[x29,16]'行实际上发生了什么,即使它调用了保存0的位置,它存储值0x3200000000' –

+0

@ErickP'ldr'加载,而不是商店。如果该内存仍然为零,那么'x29'必须不同,不能从8个零字节加载'0x3200000000'。 – Ped7g

+0

@ErickP等一秒钟......看到...在gdb 64b或32b中是“int”吗? gdb是否知道'int64_t'?或者'qword'?或者,如果'int'只有32b,那么可以把两块手表放在内存中。 (我不使用gdb,所以我不确定什么是适当的答案和解决方案,以防32b) – Ped7g