RTThread中falut定位方法
RTThread中fault定位方法
在《RTThread中HardFault_Handler分析》一文中已经分析了RTThread中对于fault中断的处理方法。接下来讲解如何根据错误输出信息对程序出现fault的位置进行定位。
rtthread_simulator_v0.1.0 工程中的main.c中的我们添加以下3行代码
void(*fp)(void) ; //1 int main(void) { fp = 0; //2 fp(); //3 return 0; }
编译后按ctrl+5进入软件仿真状态,全速运行后,UART#1窗口输出如下信息
由此可见运行时候发生了fault,通过《RTThread中HardFault_Handler分析》的内容我们可以知道,输出窗口中打印出来了各个
-
寄存器的状态
usage fault:
psr: 0x60000000
r00: 0x00000000
r01: 0x20000000
r02: 0x00000014
r03: 0x0000000a
r04: 0x00000000
r05: 0xdeadbeef
r06: 0xdeadbeef
r07: 0xdeadbeef
r08: 0xdeadbeef
r09: 0xdeadbeef
r10: 0xdeadbeef
r11: 0xdeadbeef
r12: 0x00000000
lr: 0x08000151
pc: 0x00000000 -
出错的线程:main
hard fault on thread: main
-
具体的错误信息:用法 fault ,状态寄存器(UFSR) 值为 0x02 即视图切换到ARM状态
usage fault:
SCB_CFSR_UFSR:0x02 INVSTATE
上述寄存器信息中,lr寄存器中的值为0x08000151 ,此值为进入fault异常中断之前的lr的值。
我们知道lr为连接寄存器里面保存的是调用子程序之前的PC的值。 因为 CM3 内部 使用了指令流水线,读 PC 时返回的值是当前指令的地址+4 ,所以进入异常之前自动加载到lr的值也为调用子程序前的指令地址+4。由于PC的最低位保存ARM/Thumb 运行状态,Cortex-M3只能运行在Thumb 状态,即LSB = 1。所以我们想要找到出错误程序的指令位置, 只需要对打印出来的lr的值减去5即可。
0x08000151 减去5后为0x0800014C 说明我们程序出错位置在PC = 0x0800014C 附近。
在Disassembly窗口下,我们找到0x0800014C 指令位置
可以看到 0x0800014C 指令位置正好在fp()代码段内。
我们进一步分析产生错误的原因,根据打
用法 fault 状态寄存器(UFSR),地址:0xE000_ED2A
main()函数中我们将函数指针fp的值设为了0,然后去调用fp(),相当于让程序跳转到0地址处去运行。实际上真正出错的地方是0x0800014E处,这里执行了一条BLX 跳转指令,执行完将r0的值0更新到了PC,即PC=0。PC的最低位LSB被更新成了0,试图切换到ARM状态,状态寄存器(UFSR) 中的 INVSTATE 位被置位 ,因此产生了fault。
- RT-Thread Env工具的使用方法
- rt-thread装载可重定位文件的源码分析
- rt-thread装载可重定位文件的源码分析
- rt-thread中用消息队列实现广播功能的一种方法
- 定位程序Crash常用工具和方法
- UI更新方法Handler和runOnUiThread
- IOS设置完定位后回到APP中后要自动做某些操作的方法,使用通知
- Windows进程崩溃问题的定位方法
- 学习rt-thread
- Tried to obtain the web lock from a thread解决方法之一
- 【Java】Thread类中的join()方法原理
- Thread_wait、notify、notifyAll的使用方法
- Java线程状态及Thread类中的主要方法
- selenium元素定位方法介绍
- Thread 方法
- 无法定位程序输入点 IsThreadDesktopComposited 于动态链接库 USER32.dll 上
- jQuery层动画定位滑动效果的方法
- 你用什么方法检查 PHP 脚本的执行效率(通常是脚本执行时间)和数据库 SQL 的效率(通常是数据库 Query 时间), 并定位和分析脚本执行和数据库查询的瓶颈所在?
- 2017年百度地图定位详细使用方法
- RT-Thread操作系统之一线程总结