如何分析物联网设备问题,看懂这篇文章就够了

简介: 对于运行Linux系统的物联网设备而言,这个问题的答案简单而美好——“银弹”存在且有很多。诸如linux自身的coredump以及强大的valgrind等等,显然linux的成熟与强大为开发者提供了足够多的银弹。但更多的物联网设备中,尤其轻量级设备是无法运行linux的。本文便专注于讨论在这些设备上如何分析遇到的各种问题。

> 来源 | HaaS技术社区

不看这几篇好文,就别说自己了解物联网

真的存在问题分析的“银弹”吗?

写过代码的开发人员都明白,软件bug是无法避免的。当代码中出现bug时,可能导致系统出现异常崩溃、内存泄漏等现象。因此软件开发人员需要具备强大的诊断能力将这些问题抓出来,而掌握这些诊断能力便成为软件开发人员成为高手的必经之路。

对于运行Linux系统的物联网设备而言,这个问题的答案简单而美好——“银弹”存在且有很多。诸如linux自身的coredump以及强大的valgrind等等,显然linux的成熟与强大为开发者提供了足够多的银弹。但更多的物联网设备中,尤其轻量级设备是无法运行linux的。本文便专注于讨论在这些设备上如何分析遇到的各种问题。

通常这样的轻量级物联网设备会运行在特定的RTOS上,部分设备甚至直接落跑没有OS。更有甚者,很多开发人员拿到的开发环境中唯一可以依赖的就是打印(没有JTAG无法使用GDB工具)。本文针对这样的艰苦环境,给出足够多的“银弹”,方便开发者分析各种问题。由于篇幅有限,所以每种“银弹”都以技术思路阐述为主,不再具体到讨论代码。

![image.png](https://ucc.alicdn.com/pic/developer-ecology/2cce60074f064e6bb0a8e6d25816ce24.png)

感受“银弹”的魅力

银弹”的魅力在于,一个bug出现后开发人员依靠它可以不用连仿真器、不用打开gdb单步调试的情况下能快速找到bug原因。我们先看看一些例子:

  1. 代码中访问了非法内存(比如:在不可写的地址处写了数据)导致系统奔溃。
    死机诊断“银弹”,可以记录访问非法内存时的pc值,告诉用户挂在了那个函数的哪一行;
  2. 代码跑飞了(pc=0),直接触发异常。
    栈回溯“银弹”+ 死机诊断“银弹”,可以将整个栈回溯打印出来,找到A->B->C的函数调用过程;
  3. 版本过大导致内存或者flash消耗太大。
    静态内存统计“银弹”,可以方便的分析整个版本的静态内存消耗,找出ram或flash消耗的罪魁祸首;
  4. 内存申请时malloc 失败,出现内存不足。
    动态内存统计“银弹”,可以记录用户的历史过往数据,根据用户是在哪个任务或模块中申请的内存、从系统启动开始内存的申请情况等信息,帮助用户查看是否有组件申请了过大内存但没有释放等内存泄漏的情况;
  5. 设备长时间运行后出现内存不足。
    内存泄漏分析“银弹”,可以对比两个时间点的动态内存变化,找到已申请未释放的内存,实现内存泄露问题的定位
  6. 已经有明显的踩内存现象,但是无法具体定位踩内存根因。
    内存踩踏检查“银弹”,可以设置指定的内存区域属性为不可访问,从而制造memory访问异常,结合异常现场打印,快速定位踩内存的元凶;
  7. 系统挂死、串口没有打印,问题分析无从下手。
    主动异常触发“银弹”,通过串口命令等手段主动触发系统异常,在异常处理中追溯初被打断之前的程序现场,实现问题的定位。

如何使用这些“银弹”?

RTOS领域大部分系统的诊断能力都十分薄弱,需要开发者自己学会并掌握大量的诊断能力。本章节给出这些诊断能力即“银弹”的实现思路,供读者参考。

栈回溯

栈回溯的目的是根据函数栈的内容,分析初函数调用关系。以嵌入式最常见的ARM架构为例,每一级函数调用都会把函数返回地址进行压栈(LP寄存器),开发者要做的就是在出现问题时,通过PC寄存器找到函数,通过SP寄存器找到栈的位置,然后一层层向上找到栈中保存的返回地址。思路如下图:

![image.png](https://ucc.alicdn.com/pic/developer-ecology/55c6f24b87b6452ca1a2ced98ab5d111.png)

linux等其他桌面级OS也具备栈回溯能力,但其是通过-mapcs-frame或-funwind-tables编译选项实现的。这些选项对性能和代码体积都有影响,且嵌入式很多bsp代码并不开源,无法加入编译选项重编。所以这里讨论的是不依赖编译选项的栈回溯能力。

这里面给出一些启发性的关键技术点:

  1. 开发者可以手动分析或者写程序自动完成栈回溯;
  2. 分析时的输入,栈内容与反汇编代码;
  3. 开发者需要熟悉CPU架构中使用的压栈指令,对照反汇编寻找这些指令;
  4. 寻找时从PC开始向上寻找,找到函数入口处的压栈指令,从栈中找到LR,如此往复向上寻找;

死机诊断

类似中断处理,当系统出现异常时会进入特定的向量处理流程。

对于开发者来说,如果使用OS本身已经接管了异常,并在异常发生时进行了必要的打印,那么最重要的就是如何理解这些异常信息了。以ARM的Cortex-M 3/4/7为例,可以参考这篇文档,分析异常原因。

Using Cortex-M3/M4/M7 Fault Exceptions

这里面最核心的思路时,通过异常时的PC找到出问题的指令,通过上述文档提及的下列关键寄存器的值,找到异常的原因。

![image.png](https://ucc.alicdn.com/pic/developer-ecology/4aeb353ca88741f7b6064696de12e9a1.png)

还有,通常PC地址不足以分析出问题。比如异常出现在free函数中,那是谁调用了free导致问题就变得非常重要。此时可以结合上一节的“栈回溯”实现向上追溯,完成问题分析。

如果开发者使用的OS碰巧异常时打印的信息太少,那就需要自行补充异常处理代码了。从相关vector开始走读代码,并再合适的位置加上打印,这里篇幅有限不再详细展开。

静态内存统计

对于嵌入式物联网设备,内存占用总是非常敏感的。当出现问题时,RAM或者Flash已经不足,那么开发者应该怎么入手分析问题呢?本小节先从静态内存统计入手,分析编译时已经确定的Flash与RAM消耗,找到耗内存大户。

静态内存分析方法的核心是利用好链接时产生的map文件,map文件通过连接选项‘-Map=xxx.map’可以产生。如果使用gcc进行链接,需要使用‘-Wl,-Map=output.map’编译选项,将其传递给链接器。

有了Map文件如何查看?map文件中罗列了每个函数、变量、只读数据的大小。对于小型嵌入式设备,函数与只读数据(比如字符串、初始化的data数据)是放入Flash中的,变量则是放入RAM中的。

可以使用python写一个分析map的脚本,实现类似这样的效果:

![image.png](https://ucc.alicdn.com/pic/developer-ecology/b70596e29a2941f4b7401c2c310a47bf.png)

该脚本从map文件中提取各个函数、变量与只读数据的信息,并按照从大到小进行排序,最终输出到excle中。如上图所示,开发者就可以很方便查看这些超大的数据从何而来,进而实现静态内存优化的目的。

笔者会将该python脚本配套专门的文章发出,请持续关注本社区。

动态内存统计

内存统计的核心是替换原有平台提供的malloc与free接口,增加辅助信息进行统计。这里给出一个简单的思路:

  1. 实现new_malloc/new_free。原先外部调用malloc/free的地方替换成new_malloc/new_free。
  2. new_malloc中将传入的size加16,然后调用malloc申请内存。得到ptr后预留16的offset返回个上一层。最后进行内存统计。
  3. 这保留的16字节用来记录函数返回地址、当前任务ID、内存块大小等信息,方便内存块追查。
  4. new_free中对应进行16字节的偏移,再调用free接口。最后进行内存统计。
  5. 可选:可以维护一个链表把已申请内存串起来。

由此便可以实现:

  1. 任意时刻可以得知动态内存的占用情况,得知高内存占用的任务;
  2. 甚至对于大的内存块,可以获取到调用者的信息;
  3. 当出现内存不足时,可以根据调用者信息进行分类,找到大量申请内存的代码。

另一个思路,便是重新实现OS的malloc与free算法,这里篇幅有限不再详细展开。

内存泄漏分析

想做到内存泄漏分析,首先需要对申请到的内存进行追踪,增加如下的TraceInfo信息。

![image.png](https://ucc.alicdn.com/pic/developer-ecology/15eddf5a3f004d2ea2ca2061ec61fc79.png)

然后,找到系统内存稳定的时间点。比如一个物联网设备启动之后,做起点A,然后触发一个完整业务,等业务停止后,记作结尾B。接下来对比A与B之间的内存差异,类似如下流程。

![image.png](https://ucc.alicdn.com/pic/developer-ecology/4685bd3706ab4c3fb2b06023f9116756.png)

上图橙色部分就是需要开发者为内存泄漏分析能力而增加的软件功能。最终找到 LEAK_CHECK Start(即例子中的A)与LEAK_CHECK End(即例子中的B)两个时间点之间,所有已申请未释放的内存。

开发者根据这些内存的栈回溯信息,便能找到代码中内存泄漏的点了。

内存踩踏检查

内存踩踏问题的第一步是找到稳定复现的场景,然后增加诊断信息复现问题,最终捕获踩踏内存的元凶。

这里各处一些大致思路:

  1. 首先,需要找到一种内存被踩就系统停止的方法。以ARM Cortex-M为例有两种方式,硬件断点或MPU内存保护单元;
  2. 硬件断点适合小内存范围的监控,MPU适合大范围的内存监控,具体实现方式需要参考ARM文档;
  3. 利用这样的硬件特性,代码就可以实现watchpoint功能,通过相关API在指定地址增加监控;
  4. 以栈越界为例,通过下图(左边是原问题版本,右边是增加监控的版本)方式便可以抓出来是那个函数出现了栈越界;

![image.png](https://ucc.alicdn.com/pic/developer-ecology/adc7ab73fa8446d7b41cc88547a1b715.png)

主动异常触发

当系统出现意外的代码死循环时,可能导致串口没有任何打印,这种问题非常难以定位。即使对于有命令行交互的OS,也可能因为中断被屏蔽,无法执行命令,进而毫无定位问题的手段。问题如下图所示

![image.png](https://ucc.alicdn.com/pic/developer-ecology/18bcc0c1e0c64f9f82cd7f9fa3225293.png)

这里笔者给出一种主动异常触发的机制,通过特殊的串口命令(或者其他中断)触发CPU跑到特殊的中断向量中,该向量主动执行非法指令进而触发系统异常。最终系统在异常处理中打印出完整的系统体检报告。

![image.png](https://ucc.alicdn.com/pic/developer-ecology/3a44a0a5ba534813b75c954fdfca4867.png)

该技术的一些关键点:

  1. 需要找到一个中断承接打断系统的工作;
  2. 将该中断优先级设定成最高;
  3. 重新实现系统的开关中断操作,将“关闭所有中断”替换成“关闭特殊中断外的所有中断”;
  4. 特殊中断处理流程直接执行非法指令,比如ARM的udf指令,触发异常;
  5. 异常处理中获取系统信息,恢复出特殊中断之前的系统现场,分析卡死原因。

有没有更简单的方案?

与其让开发人员一步步自己实现这些银弹,能否提供更简便直接使用这些银弹的方法?

答案是有,只要使用阿里云旗下的物联网操作系统AliOS Things,配合配套SmartTrace工具。便直接可以用上上述各种银弹法宝了。

![image.png](https://ucc.alicdn.com/pic/developer-ecology/c85e895c950e4783b06b3c5dcb931cd6.png)

AliOS Things开源在这里:


后续本社区会陆续更新一些SmartTrace相关的诊断维测系列文章,教会开发者使用AliOS Things时如何快速定位各种疑难杂正问题,成为bugfix高手。拥有“银弹”,享受开发的乐趣~~

更多精品好文

漫谈农业物联网与互联网技术的结合

传感器,物联网时代的智能硬件数字化入口

如何快速搭建一个像“天猫精灵”的智能语音助手?

物联网之IP Camera解决方案简介

从语音交互历史浅看它是否会是物联网行业的一个爆点?

带你走进多媒体世界:视频文件是怎么播放出来的

物联网云端一体AI方案的探索

物联网设备连接的下一个引爆点:4G Cat.1

物联网教育现状和前景

一文看懂蓝牙在物联网中的应用场景

下一个智能硬件爆品是什么?

华为、阿里、小米都在用的全屋智能技术

为什么物联网领域使用Rust的项目越来越多?

开源硬件的前世今生

物联网碎片化的一些思考

边缘计算在物联网行业的应用

物联网太难 ? 不妨试试用Python来开发

5G会给物联网行业带来哪些变化?

必须要了解的物联网安全知识

ARMv9能给ARM带来新一轮腾飞吗?(安全篇)

ARMv9能给ARM带来新一轮腾飞吗?(人工智能篇)

国产物联网操作系统的出路在哪里?

RISC-V架构能否引领物联网时代?

物联网到底为什么这么火?

谁才是物联网连接技术中的王者?

物联网平台大量出现能否将行业带入爆发式发展

脚本语言适合物联网开发吗

从“嵌入式”到“物联网”的四大转变

物联网发展新趋势

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
相关文章
|
16天前
|
物联网 5G 智能硬件
物联网卡:物联网卡不支持语音通话,是如何实现设备间的数据传输和通信的?
物联网卡(IoT SIM卡)通常被设计用于支持物联网(IoT)设备之间的数据传输,而不直接支持语音通话功能。这是因为物联网设备主要关注的是数据的收集、传输和处理,而不是语音通信。为了实现设备间的数据传输和通信,物联网卡及其背后的技术采用了多种方法,主要包括但不限于以下几种方式:
物联网卡:物联网卡不支持语音通话,是如何实现设备间的数据传输和通信的?
|
18天前
|
传感器 机器学习/深度学习 存储
物联网设备精细化管理系统解决方案
随着科技的进步,物联网技术作为新一代信息技术的核心部分,正在深刻改变各行业的生产和管理方式。其在资产管理、智慧城市、能源管理和智慧医疗等多个领域的广泛应用,不仅提高了运营效率,还促进了资源优化配置和精细化管理。本文详细介绍了物联网的基础概念及其在设备精细化管理系统中的具体应用方案,展示了如何通过智能感知层建设、数据处理分析平台以及精细化管理应用,实现设备的实时监控、预测性维护和能耗管理等功能,从而帮助企业提升竞争力,降低成本,并推动社会向更智能化、绿色化的方向发展。
52 2
物联网设备精细化管理系统解决方案
|
1天前
|
物联网
物联网卡不能使用在什么设备上
“物联网卡不能使用在什么设备上”这一操作或规定,通常基于物联网卡的特性、使用条款以及设备兼容性等因素。以下是对这一问题的详细分析和操作建议:
|
4天前
|
存储 监控 物联网
医疗物联网设备精细化管理系统解决方案
华汇数据智慧医院物联网管理系统解决方案是一种集物联网、云计算、大数据和人工智能等先进技术于一体的综合性解决方案,旨在提升医院的运营效率、医疗质量和患者满意度。
21 3
|
9天前
|
安全 物联网
物联网卡不能更换设备使用吗
物联网卡(IoT SIM卡)是否允许更换设备使用,这主要取决于物联网服务提供商的具体政策和服务条款。通常,物联网卡是为特定设备或应用场景设计的,因此一些服务提供商会限制卡的更换使用,主要是出于安全、管理、网络优化和避免滥用等考虑
|
17天前
|
物联网 数据安全/隐私保护
物联网:物联网卡不能使用在什么设备上
物联网卡是专为物联网设备设计的SIM卡,旨在连接非传统的、嵌入式或远程的设备到互联网。由于其特定的用途和设计,物联网卡并不适用于所有类型的设备,尤其是在以下几个方面,物联网卡通常不能或不建议使用在以下设备上:
|
1月前
|
安全 物联网 定位技术
2G网络和基站的撤销对物联网设备的影响
2G网络和基站的撤销对物联网设备的影响是多方面的,以下是对这一影响的详细分析:
2G网络和基站的撤销对物联网设备的影响
|
17天前
|
物联网 智能硬件
物联网卡:当物联网设备用卡使用在非物联网设备上会被管控吗
当设备物联网卡被检测到在非物联网设备上使用时,可能会遇到一系列的反应或后果,这主要取决于运营商的政策和物联网卡的设计目的。物联网卡通常是为非物联网设备(如智能家居设备、智能城市基础设施、车联网设备等)设计的,其流量套餐、网络连接速度、服务协议以及费用结构都与普通SIM卡有所不同。以下是一些可能发生的情况:
|
19天前
|
消息中间件 存储 NoSQL
物联网设备频繁断网,如何打赢智慧社区的流量洪峰之战?
本文详细介绍了智慧社区中物联网(IOT)技术的应用,重点讨论了物联网流量洪峰的处理方法。文章分析了上行和下行消息的特点,并提出了上下行拆分、多泳道消息队列、实时消息优先处理、连接计算存储分离及推拉结合的消息策略,以优化消息队列,确保系统稳定运行。通过这些技术手段,智慧社区的物联网设备能在各种场景中保持高效运作。
32 2
|
6天前
|
安全 网络协议 物联网
物联网僵尸网络和 DDoS 攻击的 CERT 分析
物联网僵尸网络和 DDoS 攻击的 CERT 分析

相关产品

  • 物联网平台