结合AliOS Things谈嵌入式系统通用问题定位方法(3):问题定位思路

1、定位思路参考

各种各样的错误现场,使用的手段不尽相同。

正常问题有较固定的模式去一层层剥开现象,找到本质;

还有一些问题,需要定位者仔细观察发现每一处不合乎逻辑(代码逻辑、内存逻辑等)可疑点,忽略任意一点可疑点,极大概率就会导致错过真相,含有疑点地去下结论,误判的可能性极高。

还有一些复杂问题,看似毫无逻辑性,有时需要跳出固定思维,换个层面或者角度;

总之,大家在定位问题中都会有一些自己的心得,遇到过各种各样的情况。

此处从内核底层软件角度出发,提供一些基本有效的定位手段和分析方法,给大家参考。

 

1.1、找致命错误或者异常现场

从内核系统角度,在运行中会检测内存的异常状态。

首先要判断系统出现哪种问题,如下面是内核检测最常见的两种出错状态:

发现内存问题,如内存释放时检测内存踩踏,内存申请时,发现空间不足,即会报“!! Fatal Error !!”;

系统出现异常后,内核会进入异常处理流程,串口log会输出“!! Exception !!”。

 

1.2、内存释放检测致命错误问题

  • 看打印,找报错内存

WARNING, memory maybe corrupt!! 0x81a2c378

  • 串口可以输入,输入命令查看内存状态

p 0x81a2c378 32 4                  // 输入32个4字节大小数据

  • 搜 !used !free关键字,其为内核检测出被踩内存

  • 观察出问题内存的前一块,或者之前内存块,一般简单情况都是前一块尾部踩后一块内存头:

  • 通过汇编或者基本的调用栈,分析前面一块内存使用情况

重点关注前一块内存申请后的操作,是否有memset、memcpy动作,相关代码逻辑是否有合法性判断。从汇编来看是最准确的代码逻辑,不容易像C代码一样,可能存在各种宏开关之类的误导。但是逻辑复杂,看汇编则不合理,需要大家一起检视代码确认。

也会存在内存直接使用越界的情况,比如结构体强转后越界访问,此时可以通过编译、PC-lint告警之类简单排查,也可以直接检视汇编或者C代码。

检视相关后一致认为前面的内存没有异常使用的情况下,这种可能就是二次现场或者飞踩的情况。不同情况因地制宜,参考下面几种推荐方法:

  • 优先考虑加watchpoint监控内存;
  • p前后的内存值,找规律,尤其是看内存被改写成何值,有时可以关联被谁误改写;
  • 看当前的内存头状态,是否存在已经被释放即use-after-free的情况;
  • 看任务栈是否溢出:任务栈溢出会导致各种奇怪的问题,看当前可用任务栈是否已经很少;
  • 排查业务逻辑自身问题,尤其涉及模块代码规范性问题,异常状况分支处理
  • 排查多核多任务资源保护问题;
  • 加维测:在合理的位置、合适的判断条件加合适的维测,能达到让问题尽快暴露,输出更多有用信息的效果。

 

1.3、看任务栈sp是否溢出

内核中有任务栈溢出的检测,如果检测到栈溢出了,则会即使报错。但是由于不可能检测所有栈范围,用户的代码如果访问时,跨过了栈检测的魔术字位置,那系统就不能及时报错,从而导致后续奇怪的现场。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值