搜索
bottom↓
回复: 48

分享一个HardFault分析软件,,初始版本

  [复制链接]

出0入25汤圆

发表于 2017-12-24 12:39:14 | 显示全部楼层 |阅读模式
本帖最后由 XIVN1987 于 2017-12-24 13:18 编辑

HardFault,,搞Cortex-M单片机的都清楚,,我就不介绍了

一、先看下软件执行效果:
Keil中显示的Call Stack:


我这个小工具的解析结果:



二、使用方法
1、通过某种方式知芯片已进入HardFault(比如在HardFault_Handler()中点亮个LED,指示已发生HardFault)
2、HardFault_Handler()程序中不能有栈操作,即要保护进入HardFault的环境
3、将JLink连接到发生HardFault的芯片上,打开HFView软件并设置JLinkARM.dll路径、和工程.map文件路径
4、需要设置Keil工程生成反汇编文件,且反汇编文件需要和.map文件在相同路径下,,可通过如下配置生成

5、点击按钮“读取 & 解析”就可以看到结果了

三、实现方法简析
0、最基本的原理是Python通过JLinkARM.dll文件控制JLink,从而对单片机进行读写控制
更详细的说明可以看这里:Python实现RTT客户端,源码+详细讲解,绝对原创!申请置酷!

1、能够通过JLink读写控制单片机,那么实现对单片机CPU寄存器和栈内容的读取就非常简单了,,基本就是体力劳动
读CPU寄存器并显示


CPU寄存器的编号可以在JLink的控制面板上查到:


读栈内容并显示

上面还根据读到的CPU寄存器的值判断了当前是否在HardFault状态、进入HardFault时使用的哪个栈寄存器(MSP、PSP),并检查了是否发生栈溢出
其中Stack_Limit、Stack_Top的值是通过解析.map文件的内容得到的

2、已经读到了CPU寄存器和栈的内容,,下面就是最关键的部分了,即分析Call Stack,,也就是发生HardFault前函数是怎么一层、一层调用的,,想要分析出这个调用层次,,就必须要对单片机程序本身的结构足够了解
经分析发现,Keil编译生成的.map文件和反汇编生成的反汇编文件中有函数调用结构的详细,,因此要解析这两个文件、获得单片机程序的结构信息
其中.map文件主要记录了每个函数的名称、地址、大小:


反汇编文件记录了每个函数在某个地址调用另一个函数的信息,,从而也可以分析出一个函数可能被哪几个函数调用


这些信息都是通过正则表达式来提取的,比如对.map文件的信息提取:


3、现在已经知到了程序的结构,那么当在栈底发现一个函数时,怎么分析它是怎么被调用的呢??
首先分析出这个函数是哪个函数(比如叫funcA),然后找出所有会调用这个函数的函数(比如有funcB funcC funcD三个),,然后逐次从栈底向栈顶找这几个函数的地址,,如果找到了其中一个(比如funcC),则说明funcA是被funcC调用的,,然后再按照这个方法找出所有可能调用funcC的函数,继续向栈顶寻找调用funcC的函数的地址

当然,,这个方法也是可能会产生错误的,,因为栈里不只有函数地址,还有数据,有可能有个数据恰好和funcD的地址完全一样,,那么就会误判成funcD调用了funcA,,这样整个Call Stack就分析错了,,,不过现在也没想到更好的方法,,只能先这么搞了

4、还有一个更麻烦的事情:栈里不光有函数调用和数据,还可能有中断嵌套导致的中断压栈,,这个就完全没有办法用前面的方法分析了,,因为中断可能发生在任何时候,,
这个问题暂时使用的下面这个方法解决:中断压栈的结构是固定的

最后三个字依次LR、PC和XPSR,,这三个值有一些特征:LR和PC都在程序空间范围内,且LR肯定是奇数、PC肯定是偶数,XPSR的第24位肯定是1,,现在每向栈顶 分析递进一个字,就先按照这三个特征判断接下来的这8个字是否是中断栈帧,,如果是则解析之,如果不是则按照第三步的函数调用解析

个人感觉这种方法挺容易和数据冲突,,不过暂时也没想到更好的判断方法,


程序源码:
第一版本,刚刚写完,,还不太完善,,欢迎各位大神一起研究、搞出更加健壮、方便的HardFault分析工具

运行需要安装Python 2.7 和 PyQt4,,都可去官网下载,,我就不浪费论坛的宝贵网盘空间了 ,,欢迎坛友试用,,

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2017-12-24 13:51:07 | 显示全部楼层
沙发,调试神器!大神辛苦了

出0入0汤圆

发表于 2017-12-24 14:08:52 | 显示全部楼层
之前也尝试过,不同Coertx-M内核,尤其是带浮点和不带浮点,很难做兼容处理,中断栈也不好处理,耗时太久做兼容性了,所以放弃了。自己人肉去查,反而更容易弄好

出0入0汤圆

发表于 2017-12-24 14:13:56 | 显示全部楼层
可以通过LR和SP,找到PUSH和PUSHW、VPUSH.32、VPUSH.64指令,过滤栈里面的数据,仅保留函数。
而中断栈,浮点数,还有如果调用一些外部非map里的函数,也比较麻烦的

出0入0汤圆

发表于 2017-12-24 14:23:33 | 显示全部楼层
研究很深入,但是一般人看着还是挺难的,lz能最终搞出一个比较方便的分析软件造福大伙就好了

出0入0汤圆

发表于 2017-12-24 18:15:58 | 显示全部楼层
大神。。。膜拜。。。

出0入25汤圆

 楼主| 发表于 2017-12-24 19:49:01 | 显示全部楼层
山外メ雲ジ 发表于 2017-12-24 14:13
可以通过LR和SP,找到PUSH和PUSHW、VPUSH.32、VPUSH.64指令,过滤栈里面的数据,仅保留函数。
而中断栈,浮 ...


通过分析指令分析压栈、弹栈??实现难度指数级提升啊

出425入0汤圆

发表于 2017-12-24 19:58:17 | 显示全部楼层
如果用IAR这个编译软件,可以使用吗?

出0入25汤圆

 楼主| 发表于 2017-12-24 20:04:04 | 显示全部楼层
guolun 发表于 2017-12-24 19:58
如果用IAR这个编译软件,可以使用吗?


不可以,因为分析Call Stack需要提取Keil生成的.map文件和反汇编文件中的信息,,IAR的.map文件和反汇编文件格式应该跟Keil不一样,,

出0入0汤圆

发表于 2017-12-24 22:26:23 | 显示全部楼层
好东西,感谢楼主!

出0入0汤圆

发表于 2017-12-24 23:25:56 | 显示全部楼层
这个思路真厉害

出0入8汤圆

发表于 2017-12-24 23:44:43 来自手机 | 显示全部楼层
好帖  iar支持就好了

出0入0汤圆

发表于 2017-12-25 09:42:51 | 显示全部楼层
如果仿真器能试到,也是很容易分析得到,就怕是像以前我们软件,客户就很容易试到,我们自己就试不到,
最后去到客户那里连接仿真器之后跟踪了好长时间才分析出来,像LZ的需要MCU也不加密才行,我们的代码都加密了的

出0入8汤圆

发表于 2017-12-25 09:57:14 | 显示全部楼层
解题思路挺新颖的,关注一下黑科技。

出0入8汤圆

发表于 2017-12-25 10:04:45 | 显示全部楼层
bailangcn 发表于 2017-12-25 09:42
如果仿真器能试到,也是很容易分析得到,就怕是像以前我们软件,客户就很容易试到,我们自己就试不到,
最 ...

是的,
很多情况,只能靠 log 来溯源的。

对应的,可以看看这边「【开源】ARM Cortex-M 错误追踪库,让 HardFault 不再可怕 」。
对此,并没有完美的解决方案,这些只是辅助手段,最终要靠 log trace + 我们的人工智能来解决。

出0入25汤圆

 楼主| 发表于 2017-12-25 10:17:27 | 显示全部楼层
bailangcn 发表于 2017-12-25 09:42
如果仿真器能试到,也是很容易分析得到,就怕是像以前我们软件,客户就很容易试到,我们自己就试不到,
最 ...


程序加密把SW口封掉,出了hardfault在HardFault_Handler()中软件再把SW口打开怎么样??
反正有HardFault的程序也不怕别人拷贝、盗版

出0入0汤圆

发表于 2017-12-25 10:28:33 | 显示全部楼层
XIVN1987 发表于 2017-12-25 10:17
程序加密把SW口封掉,出了hardfault在HardFault_Handler()中软件再把SW口打开怎么样??
反正有HardFaul ...

不是封掉SW口 而是RPD了。。。

出0入0汤圆

发表于 2017-12-25 10:33:42 来自手机 | 显示全部楼层
还是mdk调用窗口直接观察简单粗暴吧 在故障中断放断点

出0入0汤圆

发表于 2017-12-25 10:35:27 来自手机 | 显示全部楼层
遇到过的故障一个是硬件浮点没开 一个是U8缓冲没跟U16对齐

出0入25汤圆

 楼主| 发表于 2017-12-25 10:38:09 | 显示全部楼层
本帖最后由 XIVN1987 于 2017-12-25 11:03 编辑
bailangcn 发表于 2017-12-25 10:28
不是封掉SW口 而是RPD了。。。



RDP是保护Flash不被读取的,,分析HardFault只需要读取CPU寄存器和RAM中的栈,,不受RDP影响

出0入0汤圆

发表于 2017-12-25 10:41:33 | 显示全部楼层
XIVN1987 发表于 2017-12-25 10:38
RDP是包含Flash不被读取的,,分析HardFault只需要读取CPU寄存器和RAM中的栈,,不受RDP影响 ...

照你的意思,是不是就算我RDP了 也是可以用RTT的?一直想把RTT加到程序里面

出0入25汤圆

 楼主| 发表于 2017-12-25 10:42:36 | 显示全部楼层
huangqi412 发表于 2017-12-25 10:33
还是mdk调用窗口直接观察简单粗暴吧 在故障中断放断点


这个软件的作用是将分析过程用上位机代码实现,,这样不用每次HardFault都从头分析,,
当然,现在还是初始阶段、功能还不完善,,

出0入25汤圆

 楼主| 发表于 2017-12-25 10:43:59 | 显示全部楼层
bailangcn 发表于 2017-12-25 10:41
照你的意思,是不是就算我RDP了 也是可以用RTT的?一直想把RTT加到程序里面 ...


可以啊,RTT又不读Flash,,不过批量产品一般会把SW口封掉吧,那就没法用SEGGER-RTT了

出0入0汤圆

发表于 2017-12-26 09:58:35 | 显示全部楼层
厉害,支持支持

出0入0汤圆

发表于 2017-12-26 11:53:00 | 显示全部楼层
之前在GitHub上看到一个也是分析Cortex M的hardfault项目,不过它需要直接将源码嵌入到项目中,hardfault后会自动将所有信息存储到flash,重启时再分析。

出0入198汤圆

发表于 2017-12-26 12:08:08 | 显示全部楼层
厉害啊~~兄弟

这个工具一直是我想要的,之前我在做 CmBacktrace ( https://github.com/armink/CmBacktrace ) 时,也有过类似想法,毕竟 CmBacktrace 还需要 addr2line 工具来二次分析函数调用栈,属于半自动。

你这个全自动分析方式太实用了。

出0入25汤圆

 楼主| 发表于 2017-12-26 12:31:11 | 显示全部楼层
sunnydragon 发表于 2017-12-26 12:08
厉害啊~~兄弟

这个工具一直是我想要的,之前我在做 CmBacktrace ( https://github.com/armink/CmBacktrac ...


多谢支持!!

我这个工具锁了SW就没法用了(大批量的产品估计很多都会锁SW),所以两个工具各有长处

另外,我也在加入脚本调用“addr2line”来解析更多信息出来显示,,不过现在还有问题,输出的路径汉字都是乱码,,还在调,,

出0入16汤圆

发表于 2017-12-26 13:04:15 | 显示全部楼层
这个不错。当年我从国外论坛转了用过寄存器查找hardfault的方法,9年过去了,可惜看到的人不多
https://www.amobbs.com/thread-2013982-1-1.html

不过这种方法不太适合M0这种内核,如果是M0就别浪费时间折腾了

出0入0汤圆

发表于 2017-12-26 13:18:21 | 显示全部楼层
mark, 谢谢分享

出0入8汤圆

发表于 2017-12-27 22:03:29 来自手机 | 显示全部楼层
你这个对最新的jlink驱动库支持么,有有没有jlinkarm.dll的接口函数   真想自己vc弄个

出0入25汤圆

 楼主| 发表于 2017-12-27 22:48:08 | 显示全部楼层
justdomyself 发表于 2017-12-27 22:03
你这个对最新的jlink驱动库支持么,有有没有jlinkarm.dll的接口函数   真想自己vc弄个 ...


只要JLinkARM.dll的API不变,应该就能支持

接口函数的话,你可以参考下这个:c#的 JLINK API,自己用的

出0入0汤圆

发表于 2017-12-28 09:23:48 | 显示全部楼层
沙发,调试神器!大神辛苦了

出0入0汤圆

发表于 2017-12-28 09:41:56 | 显示全部楼层
这个很牛啊!

出0入8汤圆

发表于 2017-12-28 15:21:03 | 显示全部楼层
XIVN1987 发表于 2017-12-27 22:48
只要JLinkARM.dll的API不变,应该就能支持

接口函数的话,你可以参考下这个:c#的 JLINK API,自己用的 ...

我看过这个帖子,

也用defend分析过6.16和之前4.28的dll的函数接口,多了好多函数。

现在急需搞定6.16的接口函数参数列表及用法。

出0入25汤圆

 楼主| 发表于 2017-12-28 15:29:10 | 显示全部楼层
justdomyself 发表于 2017-12-28 15:21
我看过这个帖子,

也用defend分析过6.16和之前4.28的dll的函数接口,多了好多函数。


这个我没有,,

不过我想只用其中一小部分API也能实现很多功能了,,不一定非要所有函数API

出0入8汤圆

发表于 2017-12-28 16:59:24 | 显示全部楼层
XIVN1987 发表于 2017-12-28 15:29
这个我没有,,

不过我想只用其中一小部分API也能实现很多功能了,,不一定非要所有函数API ...

我用c++ 搞的,每次程序一上来就调用JLINKARM_ReadMem函数读取固定内存的值,但是每次运行前总是跑出这个界面,怎么破,是不是应该先调用某个初始化或者建立连接之类的函数




选好芯片信号就可以正确的读取内存中的值了。

就差一步了。。。。。

本帖子中包含更多资源

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

x

出0入25汤圆

 楼主| 发表于 2017-12-28 18:08:35 | 显示全部楼层
本帖最后由 XIVN1987 于 2017-12-28 18:28 编辑
justdomyself 发表于 2017-12-28 16:59
我用c++ 搞的,每次程序一上来就调用JLINKARM_ReadMem函数读取固定内存的值,但是每次运行前总是跑出这个 ...


找到了,,在Python里的方法如下:

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2017-12-31 10:34:33 来自手机 | 显示全部楼层
能同时装py2.7+pyqt4和py3.6+pyqt5吗。

出0入25汤圆

 楼主| 发表于 2017-12-31 11:19:04 | 显示全部楼层
huy666 发表于 2017-12-31 10:34
能同时装py2.7+pyqt4和py3.6+pyqt5吗。


可以啊,,我就装了py2.7和py3.6两个版本

本帖子中包含更多资源

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

x

出0入8汤圆

发表于 2018-1-2 10:46:36 | 显示全部楼层
XIVN1987 发表于 2017-12-28 18:08
找到了,,在Python里的方法如下:

按照你说的弄可以了,感谢之情无以言表。。。。。
你那边有没有主要函数的接口文档之类的。

出0入0汤圆

发表于 2018-1-2 10:57:50 | 显示全部楼层
看到这里,我想起了一个事情。以前做过一个堆栈分析的文档。可以在异常的时候打印出程序的栈情况。这样就不用模拟仿真就能分析异常的地方了

出0入25汤圆

 楼主| 发表于 2018-1-2 10:58:45 | 显示全部楼层
justdomyself 发表于 2018-1-2 10:46
按照你说的弄可以了,感谢之情无以言表。。。。。
你那边有没有主要函数的接口文档之类的。 ...


我没有接口文档,,我都是参考别人的代码找到的操作方法
之前参考的jlink.py
https://github.com/markrages/jlinkpy


JLINKARM_ExecCommand()函数是在pylink里面找到的,,似乎pylink比jlink.py里面的内容多很多
https://github.com/square/pylink


本帖子中包含更多资源

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

x

出425入0汤圆

发表于 2018-1-7 13:07:32 | 显示全部楼层
hardfault时不时会遇到。就是习惯了IAR,瞧不起MDK。无法用了。

出0入0汤圆

发表于 2018-1-7 21:59:00 | 显示全部楼层
mark一下

出0入0汤圆

发表于 2018-1-7 22:01:47 | 显示全部楼层
感觉好强大

出0入0汤圆

发表于 2018-6-23 13:57:30 | 显示全部楼层
XIVN1987 发表于 2017-12-28 18:08
找到了,,在Python里的方法如下:

非常感谢

出0入4汤圆

发表于 2018-6-26 13:30:48 | 显示全部楼层
mark一下

出0入0汤圆

发表于 2018-6-28 23:57:52 来自手机 | 显示全部楼层
可惜我用的是iar

出0入0汤圆

发表于 2020-11-20 06:08:48 | 显示全部楼层
好东西,感谢楼主,收藏
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-29 17:19

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

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