MS-RTOS 程序崩溃分析方法

更新时间:
2023-08-09
下载文档

MS-RTOS 程序崩溃分析方法

本章将介绍 MS-RTOS 的程序崩溃分析方法。

程序崩溃分析方法

程序崩溃后,MS-RTOS 会通过 ms_printk 函数输出类似如下的信息:

----------------------MS-RTOS crash info begin----------------------
 #MemManage

 R0: 20010000    R1: 20021ca4    R2: 00000000    R3: 20010000
 R4: 20020754    R5: 00000000    R6: 00000000    R7: 20021c80
 R8: 00000000    R9: 20020148   R10: 00000000   R11: 00000000
R12: 2002017c    SP: 20021c60    LR: 08080217    PC: 080801fc

EXC_RETURN: fffffffd
MMFSR=00000082
MMFAR=20010000
MMFSR=MMARVALID DACCVIOL

The fault occurred in thread "process" pid 2.
Call stack analysis:
APP: 0x80801fc, ELF: 0xbcc
APP: 0x8080217, ELF: 0xbe7
APP: 0x808022d, ELF: 0xbfd
APP: 0x8080243, ELF: 0xc13
APP: 0x8080283, ELF: 0xc53
APP: 0x8081275, ELF: 0x1c45
APP: 0x80801d5, ELF: 0xba5
APP: 0x808253b, ELF: 0x2f0b

----------------------MS-RTOS crash info end------------------------

将其复制并保存为一个文本文件(如 crash.log),并放置到应用程序工程编译的输出目录(应用程序工程目录下的 Debug 或 Release 子目录),然后执行 MS-RTOS 崩溃分析脚本(在 Windows 系统上要用“命令提示符”程序,不能用 PowerShell 程序)。

  • 如果崩溃是由于应用程序的问题而造成的,执行类似如下的命令(xxx 为应用程序工程编译生成的应用程序 ELF 文件):
arm-msrtos-crash-analysis.py --app xxx crash.log
  • 如果崩溃是由于 BSP 或驱动的问题而造成的,执行类似如下的命令(xxx 为 BSP 工程编译生成的 BSP ELF 文件):
arm-msrtos-crash-analysis.py --kernel xxx crash.log

MS-RTOS 崩溃分析脚本将输出更详尽的崩溃原因和调用栈,开发者可以根据调用栈定位到出错的文件和函数位置。

Cortex-M 相关寄存器解析中文解释

内存管理 fault 状态寄存器(MFSR)提供的讯息

-------------------------------------------------------------------------------
        |     可能的原因
-------------------------------------------------------------------------------
 STKERR       |  入栈时发生错误(异常响应开始时)
              |  1) 堆栈指针的值被破坏
              |  2) 堆栈容易过大,已经超出 MPU 允许的 region 范围
-------------------------------------------------------------------------------
 USTKERR      |  出栈时发生错误(异常响应终止时)
              |  1) 异常服务例程破坏了堆栈指针
              |  2) 异常服务例程更改了 MPU 配置
-------------------------------------------------------------------------------
 DACCVIOL     |  内存访问违例,常常是用户程序企图访问特权级 region 所致
-------------------------------------------------------------------------------
 IACCVIOL     |  内存访问违例,常常是用户程序企图访问特权级 region 所致
              |  1) 跳转到不可执行指令的 regions
              |  2) 异常返回时,使用了无效的 EXC_RETURN
              |  3) 中断向量表中有无效的向量,如异常在向量建立之前就发生
              |  4) 在异常处理期间,入栈的 PC 值被破坏
 -------------------------------------------------------------------------------
 LSPERR       |  浮点错误,只在带有 FPU Cortex-M4 上存在
 -------------------------------------------------------------------------------

总线 fault 状态寄存器(BFSR)提供的讯息

-------------------------------------------------------------------------------
        |     可能的原因
-------------------------------------------------------------------------------
 STKERR       | (自动)入栈期间出错
              |  1) 堆栈指针的值被破坏
              |  2) 堆栈溢出,到达了未定义存储器的区域
              |  3) PSP 未经初始化就使用
-------------------------------------------------------------------------------
 USTKERR      |  在异常处理期间把 SP 的值被破坏
-------------------------------------------------------------------------------
 IMPRECISERR  |  LDM/STM 指令造成了非精确总线 fault
-------------------------------------------------------------------------------
 PRECISERR    |  在数据访问期间的总线错误,可查看 BFAR 获得具体地址
 -------------------------------------------------------------------------------
 IBUSERR      |   MemManage fault 中的 IACCVIOL
 -------------------------------------------------------------------------------

用法 fault 状态寄存器(UFSR)提供的讯息

-------------------------------------------------------------------------------
        |     可能的原因
-------------------------------------------------------------------------------
 DIVBYZERO    |  发生了除零操作,引发此 fault 的指令可以从入栈的 PC 读取
-------------------------------------------------------------------------------
 UNALIGNED    |   UNALIGN_TRP 置位时发生未对齐访问,
                 引发此 fault 的指令可以从入栈的 PC 读取
-------------------------------------------------------------------------------
 NOCP         |  企图执行一个不存在的协处理器指令,
                 引发此 fault 的指令可以从入栈的PC读取
-------------------------------------------------------------------------------
 INVPC        |  EXC_RETURN 无效
              |  1) 异常返回时使用了无效的 EXC_RETURN,如:
              |       EXC_RETURN = 0xFFFF_FFF1 时却要返回线程模式
              |       EXC_RETURN = 0xFFFF_FFF9 时却要返回 handler 模式
              |  2) 由于 SP/LR 或者堆栈内容被破坏导致返回异常
              |  3) ICI/IT 位对当前指令无效,LDM/STM 指令被异常打断后,
              |      在异常服务例程中更改了入栈的 PC,
              |      结果在中断返回时,非零的 ICI 位段作用到了不使用 ICI 位段的指令上
 -------------------------------------------------------------------------------
 INVSTATE     |  EPSR.T 或者 EPSR.IT 错误
              |  1) 加载到 PC 中的跳转地址值是偶数(LSB = 0)
              |  2) 向量地址的 LSB = 0
              |  3) 入栈的 PSR 在异常处理过程中被破坏,使得在返回时内核尝试进入 ARM 状态
 -------------------------------------------------------------------------------
 UNDEFINSTR   |  未定义指令
              |  1) 使用了当前 ARCH 不支持的指令
              |  2) 代码段中的数据被破坏
              |  3) 链接时加载了 ARM 目标码,请检查编译阶段的设置
              |  4) 指令对齐的问题。例如,在使用 GNU 工具链时,
                     忘记了在 .ascii 后使用 .align,就可能导致下一条指令没有对齐
 -------------------------------------------------------------------------------

硬 fault 状态寄存器(HSFR)提供的讯息

-------------------------------------------------------------------------------
        |     可能的原因
-------------------------------------------------------------------------------
 DEBUGEVF     |  因调试事件导致的 fault
-------------------------------------------------------------------------------
 FORCED       |  fault “上访” 为HardFault, 需要分析其他寄存器
-------------------------------------------------------------------------------
 VECTBL       |  取向量失败
              |  1) 在取向量过程中发生总线 fault
              |  2) 向量表偏移量设置有误
-------------------------------------------------------------------------------
文档内容是否对您有所帮助?
有帮助
没帮助