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

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

  1. “全栈2019”Java异常第十五章:异常链详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  2. “全栈2019”Java异常第十四章:将异常输出到文本文件中

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  3. 20190901 On Java8 第十五章 异常

    第十五章 异常 要想创建健壮的系统,它的每一个构件都必须是健壮的. 异常概念 C++的异常处理机制基于 Ada,Java 中的异常处理则建立在 C++的基础之上(尽管看上去更像 Object Pasc ...

  4. javaSE第十五天

    第十五天    117 1. 对象数组(掌握)    117 (1)定义:    117 (2)对象数组的内存图解    117 (3)案例:    117 2. 集合(Collection)(掌握) ...

  5. JAVA之旅(三十五)——完结篇,终于把JAVA写完了,真感概呐!

    JAVA之旅(三十五)--完结篇,终于把JAVA写完了,真感概呐! 这篇博文只是用来水经验的,写这个系列是因为我自己的java本身也不是特别好,所以重温了一下,但是手比较痒于是就写出了这三十多篇博客了 ...

  6. Gradle 1.12 翻译——第十五章. 任务详述

    有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...

  7. Python第十五天 datetime模块 time模块 thread模块 threading模块 Queue队列模块 multiprocessing模块 paramiko模块 fabric模块

    Python第十五天  datetime模块 time模块   thread模块  threading模块  Queue队列模块  multiprocessing模块  paramiko模块  fab ...

  8. [原]Jenkins(十五)---jenkins插件之deploy

    /** * lihaibo * 文章内容都是根据自己工作情况实践得出. *如有错误,请指正 * 版权声明:本博客欢迎转发,但请保留原作者信息! http://www.cnblogs.com/horiz ...

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

    第三百五十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy信号详解 信号一般使用信号分发器dispatcher.connect(),来设置信号,和信号触发函数,当捕获到信号时执行 ...

随机推荐

  1. 搭建 Telegraf + InfluxDB + Grafana 监控遇到几个小问题

    1:如果同一台服务器上安装有多个MongoDB实例,telegraf.conf 中关于 MongoDB 如何配置?配置数据在[INPUT PLUGINS的[[inputs.mongodb]]]部分. ...

  2. Linux:用户权限管理

    用户与用户组的概念 超级用户 拥有对系统的最高管理权限,默认是 root 用户 普通用户 只能对自己目录下的文件进行访问和修改,具有登录系统的权限. 虚拟用户 也叫"伪"用户,这类 ...

  3. go语言设计模式之factory

    factory.go package factory import ( "errors" "fmt" ) const ( Cash = 1 DebitCard ...

  4. 剑指Offer-36.数字在排序数组中出现的次数(C++/Java)

    题目: 统计一个数字在排序数组中出现的次数. 分析: 给定一个已经排好序的数组,统计一个数字在数组中出现的次数. 那么最先想到的可以遍历数组统计出现的次数,不过题目给了排序数组,那么一定是利用了排序这 ...

  5. cartographer 3D scan matching 理解

    cartographer 3D scan matching没有论文和其它资料,因此尝试通过源码理解其处理方法,理解不当之处还请指正. 目录: 0.2D 匹配方法简介 1.real time corre ...

  6. 17个经典的Spring面试问答

    Q1.什么是Spring Framework? Spring是Java企业版应用程序开发中使用最广泛的框架.Spring的核心功能可用于开发任何Java应用程序. 我们可以使用它的扩展来在Java E ...

  7. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 5

    18.5  使用PDO对象 PDO扩展类库为PHP访问数据库定义了一个轻量级.一致性的接口,它提供了一个数据访问抽象层,这样,无论使用什么数据库,都可以通过一致的函数执行查询和获取数据,大大简化了数据 ...

  8. IT兄弟连 Java语法教程 数组 什么是数组

    数组是编程语言中最常见的一种数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的值.Java语言的数组则具有其特有的特征, ...

  9. Do Deep Nets Really Need to be Deep?

    url: https://arxiv.org/pdf/1312.6184.pdf year: NIPS2014 浅网络学习深网络的函数表示, 训练方法就是使用深网络的 logits(softmax i ...

  10. hive引擎的选择:tez和spark

    背景 mr引擎在hive 2中将被弃用.官方推荐使用tez或spark等引擎. 选择 tez 使用有向无环图.内存式计算. spark 可以同时作为批式和流式的处理引擎,减少学习成本. 问题& ...