liteos 异常接管(十五)

1 概述

1.1 基本概念

异常接管是操作系统对在运行期间发生异常的情况进行处理的一系列动作,譬如打印异常发生时当前函数调用栈信息、 cpu现场信息、任务的堆栈情况等。

异常接管作为一种调测手段,可以在系统发生异常时提供给用户有用的异常信息,譬如异常的类型、发生异常时系统的状态等,方便用户定位分析问题。

Huawei LiteOS的异常接管,在系统发生异常时的处理动作是显示异常发生时正在运行的任务信息(包括任务名、任务号、堆栈大小等),以及cpu现场等信息。

  • R11:可以用作通用寄存器,在开启特定编译选项时可以用作帧指针寄存器,可以用来实现栈回溯功能。

gcc默认将R11作为存储变量的通用寄存器使用,因而默认情况下无法使用FP的栈回溯功能。为支持调用栈解析功能,需要在编译参数中添加-fno-omit-frame-pointer选项,提示编译器将R11作为FP使用

  • FP寄存器(Frame Point),帧指针寄存器,根据该寄存器可以实现追溯程序调用栈的功能,用来展示函数间的调用关系。

FP寄存器指向当前执行函数的栈回溯结构。返回的FP值是指向由调用了这个当前函数的函数(父函数)建立的栈回溯结构的指针。而这个结构中的返回FP值是指向调用了父函数的函数的栈回溯结构的指针,以此类推。

当运行发生异常时,系统打印FP寄存器内容,用户可以据此追溯函数间的调用关
系,帮助定位异常的原因。

堆栈分析原理如图1所示。

图中不同颜色的寄存器表示不同的函数,通过FP寄存器,栈回溯到了异常函数的父函数,从而使调用关系更清楚,方便用户定位问题。

1.2 调用栈关系

在上图1,可以看到函数调用过程中,栈帧寄存器的保存;因此可以按照规律对栈进行解析就可以推出函数调用执行关系,具体步骤如下:

  1. 获取当前FP寄存器的值。
  2. FP寄存器减去4字节得到当前PC值。通过PC值可以参考elf文件或者编译生成asm文件得到函数名称。
  3. FP寄存器减去24字节,得到上次函数的调用栈帧的起始地址; FP寄存器减去16字节得到上次函数调用结束时SP的地址,那么FP到SP之间的栈就是一个函数调用的栈帧。
  4. 通过每一层栈帧中的PC指针,就知道函数调用的关联。

2 开发指导

2.1 功能

异常接管为用户提供以下几种异常类型:

异常名称 描述
OS_EXCEPT_UNDEF_INSTR 未定义的指令异常 1
OS_EXCEPT_SWI 软中断异常 2
OS_EXCEPT_PREFETCH_ABORT 预指取指令异常 3
OS_EXCEPT_DATA_ABORT 数据中止异常 4
OS_EXCEPT_FIQ FIQ异常 5

2.2 开发流程

异常接管一般的定位步骤如下:

  1. 打开编译器编译后生成的.asm 文件。
  2. 搜索PC指针在.asm中的位置。
  3. 根据LR值查找对应的调用函数。
  4. 重复步骤3,找到异常的任务函数。

具体的定位方法会在编程实例中举例说明。

3 注意事项

  • 要查看调用栈信息,必须添加编译选项宏-fno-omit-frame-pointer支持stack frame,否则编译默认是关闭FP寄存器.

4 编程实例

4.1 实例描述

使用panic 命令手动触发了一个软中断异常,异常函数为LOS_Panic,下面两个代码test_panic 为触发异常命令函数,另一个为异常调用栈打印信息.

uwExcType 2为软中断异常。

定位步骤如下:

  1. 打开编译器编译后生成的 xxx.asm 文件。
  2. 搜索PC指针 80121234 在asm文件位置(去掉0x)。
  3. 根据 LR值查找对应的调用函数。
  4. g_RunningTask 为当前异常时任务函数
UINT32 test_panic(UINT32 argc, CHAR **args)
{
    LOS_Panic("*****Trigger an exception\n");
    return;
}
Huawei LiteOS# panic
*****Trigger an exception
uwExcType = 2
puwExcBuffAddr pc = 0x80121234
puwExcBuffAddr lr = 0x80121234
puwExcBuffAddr sp = 0x80e63400
puwExcBuffAddr fp = 0x80e6340c
*******backtrace begin*******
traceback 0 -- lr = 0x80138d04
traceback 0 -- fp = 0x80e635d4
traceback 1 -- lr = 0x80138d88
traceback 1 -- fp = 0x80e635e4
traceback 2 -- lr = 0x801247d4
traceback 2 -- fp = 0x80e635f4
traceback 3 -- lr = 0x801217c4
traceback 3 -- fp = 0x11111111
R0 = 0x1c
R1 = 0x800dba3a
R2 = 0x1b
R3 = 0xfe
R4 = 0x80e634a0
R5 = 0x0
R6 = 0x800cc7f8
R7 = 0x7070707
R8 = 0x8080808
R9 = 0x9090909
R10 = 0x10101010
R11 = 0x80e6340c
R12 = 0x1b
SP = 0x80e63400
LR = 0x80121234
PC = 0x80121234
CPSR = 0x60000013
g_pRunningTask->pcTaskName = shellTask
g_pRunningTask->uwTaskPID = 6
g_pRunningTask->uwStackSize = 12288

原文地址:https://www.cnblogs.com/linhaostudy/p/11043655.html

时间: 2024-11-02 23:13:24

liteos 异常接管(十五)的相关文章

20190901 On Java8 第十五章 异常

第十五章 异常 要想创建健壮的系统,它的每一个构件都必须是健壮的. 异常概念 C++的异常处理机制基于 Ada,Java 中的异常处理则建立在 C++的基础之上(尽管看上去更像 Object Pascal). 基本异常 异常参数 所有标准异常类都有两个构造器:一个是无参构造器:另一个是接受字符串作为参数,以便能把相关信息放入异常对象的构造器. Throwable 是异常类型的根类. 自定义异常 对异常来说,最重要的部分就是类名. 异常与记录日志 对于异常类来说,getMessage() 方法有点

第十五章 文件属性类的实现

                  第十五章    文件属性类的实现        根用户的权限也不能是无限大.必须考虑到保护用户的隐私!用户的文件内容.程序代码可设置为根用户也不能观看,只能是文件拥有者可以查看.修改.但根用户可以删除一切非根用户的文件.也可以查看用户的目录.所以,i_mode字符更改如下:      BU16 i_mode; // 描述文件的访问权限:文件的读.写.执行权限  // i_mode.15-13  ftype; 文件类型: 0-符号软连接文件, // 1-硬连接文

java(第十五章)

第十五章 一.字符串类String 1.String是一个类,位于java.lang包中 2.创建一个字符串对象的2种方式: String 变量名="值"; String 对象名=new String("值"); 3.字符串的常用方法 3.1 字符串长度--length() 3.2 判断值是否相等 equals() 3.3 判断字符串对象地址是否相同 == 3.4 忽略 大小写 判断 equalsIgnoreCase() 3.5 大小写转换 toLowerCase(

十四、十五天笔记总结

1. LineNumberReader:  *public int getLineNumber():获取行号  *public void setLineNumber(int lineNumber):设置起始行号   String readLine():读取一行    案例:读取文件,每次读取一行打印并且加上行号    packagecom.edu_01;   import java.io.FileNotFoundException; import java.io.FileReader; impo

安卓第十五天笔记-图形图像一些简单处理

安卓第十五天笔记-图形图像一些简单处理 多媒体编程简介--图形的一般处理 1.计算机中图形计算的大小 一般白色就是0,黑色就是1 单色位图: 8位表示一个字节, 大小:长*宽/8,表示大小,还有一些文件信息如创建时间,什么工具创建之类的 24位位图 一个像素表示24位 大小:长*宽*24/8 256色 1个像素可以表示256种颜色 一个字节它的长度刚好是256 ,那么一个像素点就是一个字节 大小:长*宽 安卓中默认使用32位的 位图的缺陷 放大到一定的比例会出会出现失真与锯齿形状 占用很大的存储

第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解

第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲-scrapy信号详解 信号一般使用信号分发器dispatcher.connect(),来设置信号,和信号触发函数,当捕获到信号时执行一个函数 dispatcher.connect()信号分发器,第一个参数信号触发函数,第二个参数是触发信号, signals.engine_started当Scrapy引擎启动爬取时发送该信号.该信号支持返回deferreds.signals.engine_stopped当Scrapy引擎停止时发送

C++ Primer Plus学习:第十五章

第十五章 友元.异常和其他 友元 友元类 表 0-1 class Tv { public: friend class Remote; } Remote类可以使用Tv的数据成员,Remote类在Tv类后定义 . 友元成员函数 表 0-2 class Tv; //前向声明 class Remote { public: void chanup(Tv &t); } class Tv { public: friend void Remote::set_chan(Tv& t, int c); } 异常

读书笔记 - 《沸腾十五年》

这是一本在网上偶然看到推荐的书,早已绝版,在网上也很那找到,好不容易在微盘上找到了pdf版才得以一度全貌,郁闷的是pdf在手机上观看效果非常之差.没想到断断续续看完之后才发现,对于希望创业的我来说,这本书非常难得.通过看大佬们的前世今生,对于完全茫然的未来道路多了几分方向感.待合适的时候还是要去淘一本,实在找不到影印本也好.如书名所示,这本书按照编年的方式记述了从1995年中国互联网开通的元年,直到中国互联网蓬勃发展的2009年共计十五年,对于那些在中国互联网中留下身影的人.公司.事做了描述.整

linux内核奇遇记之md源代码解读之十五bitmap原理

转载请注明出处:http://blog.csdn.net/liumangxiong 为人不识陈近南,走遍江湖也枉然.做raid不识bitmap,通通都是走过场. 那么bitmap究竟是何许人物,能够在raid5的场子里混得风生水起呢?话说最早raid5是没有bitmap这位门客的,突然有一天跑raid5的系统异常掉电了,客户发现异常掉电之后再写数据就出现了数据不一致的情况.查来查去发现raid5本身设计就有一个缺陷:raid5每次写至少要写两个磁盘,写过程中异常掉电的时候就会发现一个磁盘写完成而