看来,我用什么就都能发现一些BUG啊。
诶,以后开发者都要避开我,不让我用了。
最近,自己组建了Eclipse的ARM开发环境,使用Codesourcery G++的工具链。JTAG调试使用OpenOCD,当然,硬件调试工具还是使用我自己的Versaloon。
总的来说没有什么问题,可以正常的调试,设置断点,查看变量等。
【错误描述】
但启动调试的时候,每次总是会有1个错误:
Error: address+size wrapped(0xfffffffe, 0x00000004)
在Reset_Handler中设置中断,也很容易出错:
Error: SWJ-DP STICKY ERROR
【调试分析】
在Eclipse设置了一下GDB启动命令,增加:set debug remote 1,这样就可以显示GDB的RSP数据通信了,发现可疑包:
Sending packet: $mfffffffe,4#fc...Packet received: 00000000
Sending packet: $Z0,fffffffe,2#43...Packet received: OK
第一个个包是从0xfffffffe开始读取4个字节,难道GDB疯掉了?
第二个包是要在0xfffffffe处设置一个2字节的端点,OpenOCD昧着良心返回了OK。
【痛苦中的曙光】
让我也百思不得其解,就这样过了一天,第二天,决心找到问题的根源。
不过。。。到了晚上还没有什么头绪,突然,我看了一下寄存器。
发现启动的时候,lr(连接寄存器)的值为0xffffffff。
是不是调试器想在这里设置断点?我的目标芯片的STM32芯片,命令地址需要和0xfffffffe与一下,所以就得到了0xfffffffe?
【验证】
启动之后,出现了上述的错误。然后把lr寄存器改为0xffffff0f。在启动运行的Reset_Handler中的另一个位置执行run_to_line命令,查看GDB的remote log:
Sending packet: $mffffff0e,4#c6...Packet received: 00000000
Sending packet: $Z0,ffffff0e,2#0d...Packet received: OK
【NND】
有图为证:
在(1)处,P命令用于设置寄存器的值,e是15号寄存器,也就是lr,0fffffff是小端模式,就是0xffffff0f。
罪证在(2)和(3),一个是在0xffffff0f读取4字节数据,一个是在0xffffff0f设置一个2字节的断点。
【IAR是如何处理的】
IAR的GDB Server调试可以记录GDB调试的命令和应答数据,程序启动后(包括在调试过程中),发现lr和sp的指一直都是0x00000000,再看一下g命令返回的数据(启动之后,停止在第一条要运行的指令位置,而不是main函数位置):
>> +$g#67 2B 24 67 23 36 37
<< +$00000000000000 2B 24 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 10a5a5a5a5a5a5a5 31 30 61 35 61 35 61 35 61 35 61 35 61 35 61 35
<< a5a5a5a5a5a5a5a5 61 35 61 35 61 35 61 35 61 35 61 35 61 35 61 35
<< a5a5a5a5a5a5a5a5 61 35 61 35 61 35 61 35 61 35 61 35 61 35 61 35
<< a5a5a5a5a5a5a5a5 61 35 61 35 61 35 61 35 61 35 61 35 61 35 61 35
<< a5a5a5a5a5a5a5a5 61 35 61 35 61 35 61 35 61 35 61 35 61 35 61 35
<< a5a5a5a5a5000400 61 35 61 35 61 35 61 35 61 35 30 30 30 34 30 30
<< 20ffffffff682100 32 30 66 66 66 66 66 66 66 66 36 38 32 31 30 30
<< 0800000000000000 30 38 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 0000000000000000 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
<< 01#19 30 31 23 31 39
可见,SP=0x20000400,LR=0xffffffff,IAR直接忽略了这2个数据,而不像Codesourcery的GDB,有效数据和无效数据傻傻分不清楚。
文章评论(0条评论)
登录后参与讨论