Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
CmBacktrace
rt-thread 工具讲解系列(二) 之 如何排查系统 bug
发布于 2021-09-08 13:00:49 浏览:3567
订阅该版
[tocm] ## 前言 上一篇,我简单列举了几种情况,对 CmBacktrace 进行了简单评估,整体印象是否定的。今天聊聊这个神器无能为力的时候,我们还有啥方法排查异常问题。 ### 方法论 使用 CmBacktrace 也是一种方法。上一篇批判了它,并不代表我不推荐使用它。 最笨的也是最有效的。以下几种方法和 CmBacktrace 比起来都显得那么古老,low,没科技含量又笨拙。但是,我告诉你,它们都是很有效的方法。 #### 排除法 1. 以内核层,驱动层,应用层,外设接口,第三方包等等为划分依据,将项目分解成一个个模块,以模块为基本单位进行增删。 2. 或者从庞大系统往下裁,或者从最小系统添加。 3. 各个模块有先后顺序之分,从可能性最高的应用部分代码开始往下裁。或者在最小系统基础上先添加必要的出错概率最小的部分。 4. 根据出问题的可能性大小以及重要性,相关性分组排序。先去掉那些久经考验比较稳定的部分,减少无关项影响。 经过反复添加删除,将问题的范围缩小到某个模块内,然后重点检查那部分程序。 #### 对比法 使用对比法,我们有以下几个方面可以搜集对比对象。 1. 对比以往的经验 2. 对比其它地方的相同用法,或者同一个接口的不同用法之间对比。 3. 甚至,一个大家普遍使用的和自己的对比。 一个经常会有人遇到的问题,添加一句 printf 就正常运行,修饰掉就 coredump 。这个问题曾困扰过俩前同事。他们把关注点儿放到这句 printf 调用上,忘记了一个浅显的道理——全球那么多人在用的东西,这么容易被你发现这么严重的 bug ?但凡你能这么想,就不会把关注点儿放在 printf 前后的代码上了。 排除法和对比法两种方法很少单独出现,往往是相辅相成,交替使用。经过对比可以排除无关项,排除某个模块前后的运行状态进行比较也能发现一些端倪... #### 单步调试 单步调试可能是让我们看到细枝末节的唯一一种方法了。需要查看几条语句执行情况,或者内存变化情况。让程序暂停,我们可以品着茶喝着咖啡慢慢瞧。 用这个有一个注意的地方就是,有些流程不允许中间打断。比如发送命令,接收数据这个过程,发送命令之后,在完整接收数据之前,一个断点暂停可能会让接收的数据不完整,进而影响后续判断工作。 #### printf 大法 虽然 printf 很笨,但是它比断点单步调试能更快跟踪程序调用流程,而且对系统影响最少,特别是对时间有要求的地方,打断点看数据的时间导致数据缺失就得不偿失了。 在别人热衷于使用各种高端 debug 手法的时候,我更喜欢用 printf 输出到终端,或者写到 log 文件的方式。 没有什么方法是可以一竿子戳到底的,具体问题需要具体分析,更要求工程师对项目整体了解。从顶层把控整个项目,在遇到问题时才有更多思考空间选择排查方法和确定排查方向。 没有亘古不变的,适合自己的就是最好的。 ### 编码规范论 说完几个我常用的排查问题的方法后,说一点儿经常引起问题的,和编码规范相关的。 1. 0 warning 要求是有一定的原因的。特别是未初始化的局部变量,局部指针变量。如果是先读后写,极大可能要出现非预期结果的(也有运行复合预期的时候)。 2. 数组或列表等容器索引越界, rt-thread 等 rtos 系统不像 linux 有物理内存地址和虚拟内存地址之分,所有任务和内核调度共享内存地址,其中一个任务对内存的非法写将可能影响到其它任何任务(或者很长时间都相安无事)。这就要求我们使用任何容器时一定判断是否会越界。 虽然不严格要求每个项目编译都是 0 warning,但是,warning 并不代表 ok。未初始化的变量会有警告,**未写先引用**的操作也会有警告。但是**未写先引用的警告可以是致命的!,这种警告必须当作 error 处理** ### 认识论 有的时候,我们对问题的认知局限了思考,在狭小的思维空间内转不开身。有几种对待问题的态度千万要不得。 1. 眼光局限在有限几行代码中。认为问题暴露点就是问题根源,往往在无关紧要的代码语句上浪费时间和精力。 2. 固化的排查方案。不存在没有 bug 的代码,只有暂时没有暴露问题的程序。当排查工作陷入僵局的时候,适时调整模块排查优先顺序是明智的。 3. 不可知论。没有排查方向的 debug 是最要不得的。 ### 排查方向 在排除法里,我们将系统划分成一个个小模块了。针对具体的模块需要有具体的排查方向。 暂时我能想到的排查方向有: - 配置是否正确; - 初始化工作是否完整; - 业务流程和代码逻辑是否符合预期; - 还有就是语法问题,是不是有语法用错自己没有察觉出来。 - 排查所有线程栈,初始配置给了多少,稍微多一点儿功能的项目不建议 1024 以下。 - 排查所有数组读写地方的索引值是否越界,或者是否有越界可能。 - 排查所有声明的指针,和所有函数实参是指针调用的地方。核实是否有野指针,写错实参,写错内存长度等等。 ## 结尾 个人水平有限,并不能枚举所有的可行性。大家有什么建议意见,欢迎一同讨论。 相关文章: [rt-thread 工具讲解系列(一) 之 CmBacktrace](https://club.rt-thread.org/ask/article/3019.html) [rt-thread 工具讲解系列(二) 之 如何排查系统 bug](https://club.rt-thread.org/ask/article/3027.html) [rt-thread 工具讲解系列(三) 之 env scons 命令初探](https://club.rt-thread.org/ask/article/3036.html)
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
出出啊
恃人不如自恃,人之为己者不如己之自为也
文章
43
回答
1517
被采纳
342
关注TA
发私信
相关文章
1
使用CmBacktrace定位错误异常,请教分析原因
2
cm_backtrack 使用ulog时,不能打印最后的堆栈调用信息
3
rtthread studio 中使用 cm_backtrace没有正常输出
4
rt thread studio下nano工程如何使用Cmb组件
5
cmBackTrace定位后无法分析出问题原因
6
程序运行一段时间后出现hardfault?CmBacktrace需要的是啥文件?
7
keil5 移植 finsh 串口打印 hard fault on thread
8
hard fault on thread: mqtt0,请教怎么解决
9
rt1052 移植cm_backtrace库,无法定位错误
10
有没有人能帮忙解决一下hard fault on main
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
MicroPython
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
15
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部