搜索
bottom↓
回复: 36

【BUG】定位+修复开源盖革计 v1.41a 死机漏洞(1)

[复制链接]

出200入2509汤圆

发表于 2020-10-29 03:10:33 | 显示全部楼层 |阅读模式
首先感谢坛主的鼎力开源,盖革计终于迎来了 v1.4x 版本。

然而 v1.41 版本有些出师不利,一开始就各种 BUG,最大的在于莫名死机/按键无响应。
今天尝试使用一些歪门手法进行定位+修复。

包含 BUG 的开源盖革计固件版本:v1.41a.


【BUG#1】
描述:Release 版本固件在 Ni-MH 电池供电时,莫名死机/按键无响应。

表现:
刷入 v1.41a-Release 版本 BIN 固件后,使用 Ni-MH 电池供电并拔下 USB,盖革计立即进入死机状态,
我手头总共有两台盖革计,第一台就复现了这个 BUG,索性拿来调试。

分析:
由于我不喜欢开盖拧螺丝,因而所有调试都是 USB-CH340E 串口固件更新,编译一直使用 Release 模式。
坛主在 v1.41a 版本中引入低功耗模式,PA/PB 端口的时钟都关了,神马信息都输出不来,给调试带来麻烦。
最终妥协保留 PA 时钟(BEEP信号用),使用声音信号进行位置打桩。

经过一系列打桩调试,定位锁死在 main.c 第 206 行: main : while(HV_State);



调试变量时使用板载蜂鸣器输出类似摩尔斯码,进而输出调试信息。
由于不是专业火腿,只能使用 Goldwave 把声音录下来再行翻译。
下图为死机时测试 HV_Time 变量,显然该变量数值有下降,证实 Systick 在锁死时走时正常:



再经过全局查找,HV_State 仅在 SysTick_Handler: HV_STOP 位置有关闭,才能解锁。
经过上述摩尔斯码调试,证实 HV_STOP 应该已经执行到了,但主函数还是莫名卡死。

然后偶然间看到了 HV_State 的定义,瞬间瀑布汗:居然没有 volatile (__IO) 修饰。
一个处于临界区的变量(SysTick_Handler vs main),忘记使用 voltaile 简直了。

修复:
在 main.c/.h 两个文件中,修改 HV_State 定义及声明,全都加上 volatile (__IO) 修饰,死机BUG解除:



结论:
v1.41a 莫名死机/按键不响应的 BUG,系 HV_State 遗漏 volatile (__IO) 定义所致。
临界区变量 HV_State 被 main.c 意外缓存优化,最终造成 main.c:while(HV_State) 锁死。
由于常规调试多使用 DEBUG 模式,因而不排除某些时候 HV_State 未被缓存优化,此时 BUG 暂不发作。


【BUG#2】
另一个BUG是系统稳定性的需求:v1.41a 在发布时,默认没有开启看门狗。
主函数第 104 行取消注释即可:



开启看门狗的好处在于:只要有类似上述 BUG1 的锁死,等个半分钟就可以自己 RESET 活过来,
进而可以继续插 USB 更新固件,还是为了不拧螺丝。


--------------------------------------------------------------------------

以上,定位并修复了 v1.41a 固件按键死机漏洞。发来供坛主及各位参考。

晚上奶茶喝多了,其他代码实在调不动了,目测还会有隐蔽的 BUG 待发现。

最后祝大家折腾愉快!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2020-10-29 07:06:26 来自手机 | 显示全部楼层
录音查bug,厉害了

出0入0汤圆

发表于 2020-10-29 07:27:43 来自手机 | 显示全部楼层
摩拜一下高手

出0入4汤圆

发表于 2020-10-29 08:01:28 | 显示全部楼层
感谢楼主,等有一个稳定版本再升级。

出0入0汤圆

发表于 2020-10-29 08:01:37 | 显示全部楼层
真棒,实在是佩服。

出130入111汤圆

发表于 2020-10-29 08:20:09 来自手机 | 显示全部楼层
楼主大神玩出花了

出0入16汤圆

发表于 2020-10-29 08:25:24 | 显示全部楼层
五体投地。                  

出0入0汤圆

发表于 2020-10-29 08:27:55 来自手机 | 显示全部楼层
大神,iap的Bootloader要如何调试?

出0入0汤圆

发表于 2020-10-29 08:37:45 | 显示全部楼层
楼主很专业,赞一个!

出0入16汤圆

发表于 2020-10-29 08:38:23 | 显示全部楼层
volatile的坑很隐蔽,不一定会发作。
与优化等级有关,与函数里变量使用次数及位置有关。

出0入0汤圆

发表于 2020-10-29 08:50:49 | 显示全部楼层
蜂鸣器debug,牛

出0入0汤圆

发表于 2020-10-29 09:08:46 | 显示全部楼层
楼主应该进CIA兼职数据分析员,太厉害了

出0入0汤圆

发表于 2020-10-29 09:12:24 | 显示全部楼层
厉害了 . . .

出1070入872汤圆

发表于 2020-10-29 09:14:30 | 显示全部楼层
这个位置昨晚我也定位到了,我是使用PA7翻转做为输出调试跟踪信号的,拿示波器数波形才定位到这个位置。昨天我的一块板子上的MCU是由问题的,会在ADC校准时死锁,结果就干扰了bug查找过程,以为已经搞定了。还发了个patch。晚上回来换块板子一试,又复现了。
这个volatile (__IO) 确实忘记加了,手残啊。但是我在没有加volatile (__IO) 的情况下,把while (HV_State);改成了while (HV_State) __NOP(); ,bug也消失了。这个bug在接着SWD单步调试的时候不会出现, 只有全速跑的时候才会出来,无论是Debug和Release都存在这个情况。所以要定位他变得异常艰难。
不过你想到用GodenWave录音来找bug真是绝了。

一会儿打包上传新的固件。

出0入8汤圆

发表于 2020-10-29 09:23:53 | 显示全部楼层
真的涨见识了,牛

出50入0汤圆

发表于 2020-10-29 09:47:06 | 显示全部楼层
录音查bug,厉害了

出0入8汤圆

发表于 2020-10-29 09:50:23 | 显示全部楼层
牛人,厉害

出0入169汤圆

发表于 2020-10-29 09:59:55 | 显示全部楼层
会玩,会玩

出200入2509汤圆

 楼主| 发表于 2020-10-29 11:22:17 | 显示全部楼层
lnso 发表于 2020-10-29 08:27
大神,iap的Bootloader要如何调试?

Bootloader 调试起来略麻烦,不过也逃不过用某些办法输出信息(例如 PA7:4 引脚)。

软件断点:
C 级别(用于有代码情况):while(1)
机器码级别(用于IDA直接改机器码情况):FE E7

然后怎么输出数据就看想象了,例如摩尔斯码

出200入2509汤圆

 楼主| 发表于 2020-10-29 11:23:12 | 显示全部楼层
感谢大家捧场,有幸能和坛主调到一样的故障位置: )

出0入0汤圆

发表于 2020-10-29 11:26:04 | 显示全部楼层
牛X,这样都能玩,并且玩到点上了。

出200入2509汤圆

 楼主| 发表于 2020-10-29 11:29:46 | 显示全部楼层
hecat 发表于 2020-10-29 08:38
volatile的坑很隐蔽,不一定会发作。
与优化等级有关,与函数里变量使用次数及位置有关。 ...

其实现有的固件还有个大坑:临界区原子操作。

目前看临界区涉及 uint32_t 和 uint8_t 类型,前者和 CPU 位宽一致还好些。

出200入2509汤圆

 楼主| 发表于 2020-10-29 11:36:23 | 显示全部楼层
Appcat 发表于 2020-10-29 09:14
这个位置昨晚我也定位到了,我是使用PA7翻转做为输出调试跟踪信号的,拿示波器数波形才定位到这个位置。昨 ...


坛主辛苦!

这样就放心了,至少帖子一起佐证了故障的位置。我是在死循环中周期发摩尔斯码的:

while( HV_State )
{
   // BEEP发摩尔斯码
   // 帧延时 2s
}

然后这个结构下触发了 HV_State 的缓存优化,BUG发作。如果和“NOP 时不发作”结合起来看的话,漏加 volatile 的 BUG 还真是看心情。

再写下去的话,可能需要注意临界区的原子操作问题。

出0入8汤圆

发表于 2020-10-29 11:53:19 | 显示全部楼层
厉害,从来没想过这种方法

出100入101汤圆

发表于 2020-10-29 12:22:07 来自手机 | 显示全部楼层
膜拜下大神

出1070入872汤圆

发表于 2020-10-29 13:48:23 | 显示全部楼层
t3486784401 发表于 2020-10-29 11:36
坛主辛苦!

这样就放心了,至少帖子一起佐证了故障的位置。我是在死循环中周期发摩尔斯码的:

阿莫才是坛主,我就是个版主
这个uint8_t确实是个问题,也是我自己的8位机后遗症。当年拿AVR来做DTU,是掰着手指头算堆空间和栈空间的,很多标志直接用位来表示,真是一个字节掰成8瓣用。
指令的架构还要修改,这个问题就带着一起修改吧。

出15110入5966汤圆

发表于 2020-10-29 13:53:57 | 显示全部楼层
精华,打赏!

出230入1566汤圆

发表于 2020-10-29 14:11:00 | 显示全部楼层
本帖最后由 cne53102 于 2020-10-29 14:15 编辑

蜂鸣器做输出绝了
我曾用软串口加到LED上做输出(对这个机器来说就是背光)
但还是需要个接收的玩意
楼主这个直接电脑录音就行了,更省事

出80入58汤圆

发表于 2020-10-29 22:30:06 来自手机 | 显示全部楼层
调试过程非常精彩,全栈大佬!

出0入8汤圆

发表于 2020-10-29 23:34:25 来自手机 | 显示全部楼层
GoldWave我也在用,不过都是剪辑音频用的,这个应用太666了

出0入0汤圆

发表于 2020-10-31 08:13:03 | 显示全部楼层
楼主牛X,这样的调试方法真的是开眼界了,估计还有更多大家没见过的技能待解锁

出0入0汤圆

发表于 2020-10-31 08:57:35 | 显示全部楼层
楼主全才啊。摩斯码也会

出200入2509汤圆

 楼主| 发表于 2020-10-31 13:30:07 | 显示全部楼层
powermeter 发表于 2020-10-31 08:57
楼主全才啊。摩斯码也会

感谢捧场,作为一名电工,ASK/OOK 还是得知道点的。

26字符的莫尔斯码表还是背不下来,只记得几个常用的,例如: ....   .   .-..   .-..   ---

出200入2509汤圆

 楼主| 发表于 2020-11-1 17:17:54 | 显示全部楼层

感谢站长!

出200入2509汤圆

 楼主| 发表于 2020-11-1 17:18:41 | 显示全部楼层
mcuz195 发表于 2020-10-31 08:13
楼主牛X,这样的调试方法真的是开眼界了,估计还有更多大家没见过的技能待解锁 ...

有些技能我自己也没见过,深藏于酒瓶

出200入2509汤圆

 楼主| 发表于 2020-11-1 17:19:52 | 显示全部楼层
cne53102 发表于 2020-10-29 14:11
蜂鸣器做输出绝了
我曾用软串口加到LED上做输出(对这个机器来说就是背光)
但还是需要个接收的玩意

家里的领导已经指出问题所在了:一晚上搁这里滴滴滴滴要闹哪样

出200入2509汤圆

 楼主| 发表于 2020-11-1 17:23:55 | 显示全部楼层
Appcat 发表于 2020-10-29 13:48
阿莫才是坛主,我就是个版主
这个uint8_t确实是个问题,也是我自己的8位机后遗症。当年拿AVR来做 ...

v1.53a+ 双语版已上传,坐等版主统一更新
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子论坛 -- 东莞阿莫电子网站 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2023-3-22 18:38

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表