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,可以看到函数调用过程中,栈帧寄存器的保存;因此可以按照规律对栈进行解析就可以推出函数调用执行关系,具体步骤如下:
- 获取当前FP寄存器的值。
- FP寄存器减去4字节得到当前PC值。通过PC值可以参考elf文件或者编译生成asm文件得到函数名称。
- FP寄存器减去24字节,得到上次函数的调用栈帧的起始地址; FP寄存器减去16字节得到上次函数调用结束时SP的地址,那么FP到SP之间的栈就是一个函数调用的栈帧。
- 通过每一层栈帧中的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 开发流程
异常接管一般的定位步骤如下:
- 打开编译器编译后生成的.asm 文件。
- 搜索PC指针在.asm中的位置。
- 根据LR值查找对应的调用函数。
- 重复步骤3,找到异常的任务函数。
具体的定位方法会在编程实例中举例说明。
3 注意事项
- 要查看调用栈信息,必须添加编译选项宏-fno-omit-frame-pointer支持stack frame,否则编译默认是关闭FP寄存器.
4 编程实例
4.1 实例描述
使用panic 命令手动触发了一个软中断异常,异常函数为LOS_Panic,下面两个代码test_panic 为触发异常命令函数,另一个为异常调用栈打印信息.
uwExcType 2为软中断异常。
定位步骤如下:
- 打开编译器编译后生成的 xxx.asm 文件。
- 搜索PC指针 80121234 在asm文件位置(去掉0x)。
- 根据 LR值查找对应的调用函数。
- 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
liteos 异常接管(十五)的更多相关文章
- “全栈2019”Java异常第十五章:异常链详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- “全栈2019”Java异常第十四章:将异常输出到文本文件中
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- 20190901 On Java8 第十五章 异常
第十五章 异常 要想创建健壮的系统,它的每一个构件都必须是健壮的. 异常概念 C++的异常处理机制基于 Ada,Java 中的异常处理则建立在 C++的基础之上(尽管看上去更像 Object Pasc ...
- javaSE第十五天
第十五天 117 1. 对象数组(掌握) 117 (1)定义: 117 (2)对象数组的内存图解 117 (3)案例: 117 2. 集合(Collection)(掌握) ...
- JAVA之旅(三十五)——完结篇,终于把JAVA写完了,真感概呐!
JAVA之旅(三十五)--完结篇,终于把JAVA写完了,真感概呐! 这篇博文只是用来水经验的,写这个系列是因为我自己的java本身也不是特别好,所以重温了一下,但是手比较痒于是就写出了这三十多篇博客了 ...
- Gradle 1.12 翻译——第十五章. 任务详述
有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...
- Python第十五天 datetime模块 time模块 thread模块 threading模块 Queue队列模块 multiprocessing模块 paramiko模块 fabric模块
Python第十五天 datetime模块 time模块 thread模块 threading模块 Queue队列模块 multiprocessing模块 paramiko模块 fab ...
- [原]Jenkins(十五)---jenkins插件之deploy
/** * lihaibo * 文章内容都是根据自己工作情况实践得出. *如有错误,请指正 * 版权声明:本博客欢迎转发,但请保留原作者信息! http://www.cnblogs.com/horiz ...
- 第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解
第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解 信号一般使用信号分发器dispatcher.connect(),来设置信号,和信号触发函数,当捕获到信号时执行 ...
随机推荐
- Zimbra
第一步:利用XXE读取配置文件 这里利用了CVE-2019-9670漏洞来读取配置文件,你需要在自己的VPS服务器上放置一个dtd文件,并使该文件能够通过HTTP访问.为了演示,我在GitHub上创建 ...
- 团队项目之团队展示&选题
团队博文:https://www.cnblogs.com/blackpanda/p/11734448.html 一. 团队展示 1. 队名: Black Panda 2. 队员: 郑伟金 3117 ...
- 通过Shell脚本来创建批量服务器上的MySQL数据库账号
1.项目背景 因监控需要,我们需要在既有的每个MySQL实例上创建一个账号.公司有数百台 MySQL 实例,如果手动登入来创建账号很麻烦,也不现实.所以,我们写了一个简单的shell脚本,用来创建批量 ...
- PyCharm批量修改变量名
方法和 PyCharm重命名文件时更改引用的地方相同
- 多个git合并,并保留log历史记录
面临的需求是:将多个git仓库作为一个单独目录,整合到一个新的git仓库中:并且保留历史记录. 1. 新建一个summary仓库 新建一个summary仓库,用于整合一系列git仓库. git clo ...
- [Linux]线程分离状态的理解
在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached).一个可结合的线程能够被其他线程收回其资源和杀死:在被其他线程回收之前,它的存储器资源(如栈)是不释放的.相反, ...
- onload()方法只能在body标签中调用吗?怎么调用多个多个方法?
第一个问题: onload()方法并非只能在body标签中调用的,还可以在js中用window.onload = function() {函数名};来调用:另外img等标签也支持onload方法. 支 ...
- IDEA debug工具使用
参考:https://www.cnblogs.com/jajian/p/9410844.html
- 微信公众号开发 ,redirect_uri域名还是与后台配置不一致
测试账号地址: https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index https ...
- SQLServer某个库log日志过大,无法收缩日志文件 ,因为该文件结尾的逻辑日志文件正在使用
问题描述: 今天看到user库日志备份方面很久,然后查看到user库这个log日志很大 图片是我已经解决了,然后现在可以收缩的大小 解决方法: 1.先备份user库日志,因为很大,所以要等很久,这个只 ...