搜索
bottom↓
回复: 28

【100莫元】堆栈溢出导致的hardfault和数据访问违例异常

[复制链接]

出0入10汤圆

发表于 2014-12-18 20:56:46 | 显示全部楼层 |阅读模式
堆栈溢出后,内存被踩了(已经验证过),开始没事,踩完之后还是可以运行的,堆栈溢出真恐怖,接着运行,最后进入了硬fault。
被我找到一句进入hardfault的语句,然后查找到那句话的汇编是“STR      r3,[r0,#0xB4]”,然后就死了。
接着打印出硬fault的寄存器的值查得是“硬fault 是被上访的。上访者可以是总线fault、存储器管理 fault或是用法 fault”。
我再打印出其他的异常的寄存器,查得是总线fault的不精确的数据访问违例。
请大神们,联想下“STR      r3,[r0,#0xB4]”和这个异常是神马情况,这句汇编对应的C语言是一个赋值语句,而且赋值给的这个内存单元在堆栈溢出的时候被修改过。
只要回复好我这个,相当于在其他的帖子回复100个啊,有能力的赶紧回复下。

本帖子中包含更多资源

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

x

出0入10汤圆

 楼主| 发表于 2014-12-18 20:57:16 | 显示全部楼层
突然好心痛啊,发了个帖子丢了100莫元。

出0入17汤圆

发表于 2014-12-18 21:14:58 | 显示全部楼层
主要是指针错误;
这个只有你自己才能找到BUG

出0入10汤圆

 楼主| 发表于 2014-12-18 21:16:17 | 显示全部楼层
hhxb 发表于 2014-12-18 21:14
主要是指针错误;
这个只有你自己才能找到BUG

请大神明示。

出65入0汤圆

发表于 2014-12-18 21:20:45 | 显示全部楼层
在hardfault函数断点,打开Call stack,查看其中进入hardfault前的调用函数,就知道可能出现在哪个函数里了!主要关注指针溢出、内存访问溢出等等情况!当然调用不安全的库函数也会出问题!

出0入8汤圆

发表于 2014-12-18 21:23:50 | 显示全部楼层
本帖最后由 security 于 2014-12-18 21:43 编辑

这条语句是一赋值语句,
将R3的东西,赋值到R0作为基址,0xb4为偏移的内存地址。
这里的异常,属于暴力访问,通常是指向了非法的地址
在VC上,如果访问了非法地址,也会抛出类似异常

因此,你这边重点是 R0的内容,被篡改了
导致[R0, 0xB4]的地址非法了。

具体是谁动了R0,那就是你程序栈溢出影响到了
剩下,就等你继续分析,告知大家了
(不为莫元,只为积分,今天终于升级为中级会员了,喜大普奔啊)

出0入0汤圆

发表于 2014-12-18 22:00:14 | 显示全部楼层
可惜没学好汇编,看着100莫元好心动啊。替楼主顶一下,攒个人气,早日解决bug

出0入10汤圆

 楼主| 发表于 2014-12-18 22:11:18 | 显示全部楼层
security 发表于 2014-12-18 21:23
这条语句是一赋值语句,
将R3的东西,赋值到R0作为基址,0xb4为偏移的内存地址。
这里的异常,属于暴力访问 ...

我根据寄存器的值发现没有问题啊,访问的是一个数组首地址。

出300入477汤圆

发表于 2014-12-18 22:18:53 来自手机 | 显示全部楼层
偏移量b4很大啊,你有没有硬编码的访问一个数组的这个位置?或者访问一个这么大的结构体的成员?如果有跟这个偏移量对得上的,就算你已经找到这一行代码了!

出300入477汤圆

发表于 2014-12-18 22:41:48 来自手机 | 显示全部楼层
可能的语句好像不多,例如,写入xarray[45]其中xarray就是那个被破坏的指针;或者,写入p->ii,其中结构体成员ii的偏移量是45个整数大小,而p指针被破坏

出0入0汤圆

发表于 2014-12-18 23:17:43 | 显示全部楼层
本帖最后由 li.wen 于 2014-12-18 23:26 编辑

Impreciserr bus fault指这个错误是由好几个指令周期以前完成的任务造成的,而不是当下一条指令造成的。
如果是当下正在执行的一条指令造成的错误(preciserr),楼主可以通过堆栈什么的找到这个错误。

所以这个错误只能是正向的办法去找了。
即,你看看现在用了那些逻辑功能,一个个注释掉去发现问题的所在;个人觉得这是比较好的办法。
当然,你也可以看看堆栈,有啥提示性的线索。不过个人感觉希望不大。

楼主要坛友协助定位问题,最好还是讲讲做什么功能的。或者贴一些有可能有问题的代码上来。

PS:楼主似乎是参考Joseph Yiu《The Definitive Guide to the ARM Cortex M3》 里面有详细讲到Impreciserr,不过没讲有什么太好的定位问题的办法。

出0入10汤圆

 楼主| 发表于 2014-12-19 10:31:51 | 显示全部楼层
li.wen 发表于 2014-12-18 23:17
Impreciserr bus fault指这个错误是由好几个指令周期以前完成的任务造成的,而不是当下一条指令造成的。
如 ...

这是一个ucos-III的程序,我找到的最后的问题是因为堆栈溢出,堆栈溢出的时候是没事的,后面运行着才有事,我把附件上传上来,你帮忙看下,会的人实在不多,请帮忙下,特别是过程。
Task_Start这个任务堆栈溢出。
溢出语句是图中这个,楼主位说的是开启没有优化的时候测的。

想上传工程可是太大了。我把跑飞的那段代码放上来吧
  1. OS_MSG_QTY  OS_MsgQFreeAll (OS_MSG_Q  *p_msg_q)
  2. {
  3.     OS_MSG      *p_msg;
  4.     OS_MSG_QTY   qty;



  5.     qty = p_msg_q->NbrEntries;                              /* Get the number of OS_MSGs being freed                  */
  6.     if (p_msg_q->NbrEntries > (OS_MSG_QTY)0) {
  7.         p_msg                   = p_msg_q->InPtr;           /* Point to end of message chain                          */
  8.         p_msg->NextPtr          = OSMsgPool.NextPtr;
  9.         OSMsgPool.NextPtr       = p_msg_q->OutPtr;          /* Point to beginning of message chain                    */
  10.         OSMsgPool.NbrUsed      -= p_msg_q->NbrEntries;      /* Update statistics for free list of messages            */
  11.         OSMsgPool.NbrFree      += p_msg_q->NbrEntries;
  12.         p_msg_q->NbrEntries     = (OS_MSG_QTY)0;            /* Flush the message queue                                */
  13.         p_msg_q->NbrEntriesMax  = (OS_MSG_QTY)0;
  14.         p_msg_q->InPtr          = (OS_MSG   *)0;
  15.         p_msg_q->OutPtr         = (OS_MSG   *)0;
  16.     }
  17.     return (qty);
  18. }
复制代码
单独放出来就是下面这句
  1. OSMsgPool.NbrUsed -= p_msg_q->NbrEntries; /* Update statistics for free list of messages */
复制代码
下面是对应的汇编,死在0x0800302C
  1.    237:     qty = p_msg_q->NbrEntries;                              /* Get the number of OS_MSGs being freed                  */
  2.    238:     if (p_msg_q->NbrEntries > (OS_MSG_QTY)0) {
  3.    239:         p_msg                   = p_msg_q->InPtr;           /* Point to end of message chain                          */
  4. 0x08003018 8941      LDRH     r1,[r0,#0x0A]
  5.    231: {
  6.    232:     OS_MSG      *p_msg;
  7.    233:     OS_MSG_QTY   qty;
  8.    234:  
  9.    235:  
  10.    236:  
  11.    237:     qty = p_msg_q->NbrEntries;                              /* Get the number of OS_MSGs being freed                  */
  12.    238:     if (p_msg_q->NbrEntries > (OS_MSG_QTY)0) {
  13.    239:         p_msg                   = p_msg_q->InPtr;           /* Point to end of message chain                          */
  14. 0x0800301A B1B9      CBZ      r1,0x0800304C
  15.    240:         p_msg->NextPtr          = OSMsgPool.NextPtr;
  16. 0x0800301C 4B52      LDR      r3,[pc,#328]  ; @0x08003168
  17. 0x0800301E 6802      LDR      r2,[r0,#0x00]
  18. 0x08003020 F8D3C000  LDR      r12,[r3,#0x00]
复制代码








本帖子中包含更多资源

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

x

出0入8汤圆

发表于 2014-12-19 11:15:30 | 显示全部楼层
10xjzheng 发表于 2014-12-19 10:31
这是一个ucos-III的程序,我找到的最后的问题是因为堆栈溢出,堆栈溢出的时候是没事的,后面运行着才有事 ...

11楼的li.wen 已经说明了Impreciserr 和 preciserr总线错误的区别。
这是不精确的总线暴力访问异常,CPU无法给出精确的地址。

我觉得楼主不要纠结于这个了
首先楼主既然已经知道堆栈溢出了,那就去fix it。
对于堆栈溢出的话,有可能不会马上die,因为破坏的可能不是关键敏感的,可能不是下面短期内要执行的流程所依赖的。
此时,就不会立即die
而是运行一段时间,莫名其妙的死掉,此时才真正踩到地雷。
但不管怎样立即die,还是延迟die,这些都是要避免的。

你这边的截图
0x 0800 3024,将值存储到 R2所指向的内存,但你注意到了没有,R2的内容为0
这边是正常的吗?

这个问题,要去寻根问底,估计不好弄,CPU也给出不精确的异常报告。
我觉得还不如主动避免,这些莫名其妙的问题。
你说如何?

出0入10汤圆

 楼主| 发表于 2014-12-19 11:43:22 | 显示全部楼层
security 发表于 2014-12-19 11:15
11楼的li.wen 已经说明了Impreciserr 和 preciserr总线错误的区别。
这是不精确的总线暴力访问异常,CPU ...

恩,我觉得可能我深究这个问题可能会学到一些东西。
你说的R2=0,这个可能真的有问题耶,不过为什么不是在这行出问题?

出0入8汤圆

发表于 2014-12-18 20:56:47 | 显示全部楼层
10xjzheng 发表于 2014-12-19 11:43
恩,我觉得可能我深究这个问题可能会学到一些东西。
你说的R2=0,这个可能真的有问题耶,不过为什么不是 ...

其实你已经学到东西了
因为任务栈溢出的话,破坏的东东,你不能预知
任务是否马上die,我们也无法预知
因为这些东西,可能乱七八糟,对于我们而言是这样,对于CPU也是这样
因此,当踩到地雷时,CPU挂掉了,但是CPU自己却给出不精确的异常报告,说明CPU也莫名其妙。

所以要深究,到底哪个是源头,哪个点被破坏了,导致后续的die
还不如去抓罪魁祸首,最初的源头是 栈溢出导致的
这样,也不用费神啊

出0入10汤圆

 楼主| 发表于 2014-12-19 12:01:43 | 显示全部楼层
redroof 发表于 2014-12-18 22:41
可能的语句好像不多,例如,写入xarray[45]其中xarray就是那个被破坏的指针;或者,写入p->ii,其中结构体 ...

大神帮忙看下下面的!

出300入477汤圆

发表于 2014-12-19 12:19:42 | 显示全部楼层
10xjzheng 发表于 2014-12-19 12:01
大神帮忙看下下面的!

因为这是不精确中断,所以你见不到准确的地址,如果你知道是哪个任务的堆栈溢出,直接加大堆栈就行了。

出0入0汤圆

发表于 2014-12-19 12:57:53 | 显示全部楼层
10xjzheng 发表于 2014-12-19 10:31
这是一个ucos-III的程序,我找到的最后的问题是因为堆栈溢出,堆栈溢出的时候是没事的,后面运行着才有事 ...

讲一个可能性,你这个OS_MsgQFreeAll()是你主动调用的吗?
还是系统自动调用的。会不会有可能在你OSMsgFree的时候, 你还有其他进程在送Message过来。或者有处理一半的Message。
我曾经碰到过Message Push太多挂掉的,还有Free完以后还在Push Message导致挂掉的,不过不是在ucos里面碰见的。

定位的办法:
查一下有哪些用户在发送Message(系统发的除外)。然后查一下他们发送的频率。
先全部禁止用户发送,然后再一个个允许发送,排除法。

出0入0汤圆

发表于 2014-12-19 13:06:33 | 显示全部楼层
还有另外一个办法也可以试试:
就是通过IO口来判断执行时序。
例如,
OSMsgFree
{
        SetIO1High();
        //Do something;
        SetIO1Low();
}

OSMsgSend
{
        SetIO2High();
        //Do something;
        SetIO2Low();
}

然后,就是拿示波器器看看两个IO口的关系啦。
说不定就是在IO1高电平的时候,突然IO2也来一个高电平,那就不对了。正常的是两个应该错开的。

出0入10汤圆

 楼主| 发表于 2014-12-19 13:11:01 | 显示全部楼层
li.wen 发表于 2014-12-19 12:57
讲一个可能性,你这个OS_MsgQFreeAll()是你主动调用的吗?
还是系统自动调用的。会不会有可能在你OSMsg ...

不是你说的原因,我的系统才刚刚开始,没有很多东西。

出0入8汤圆

发表于 2014-12-19 13:41:42 | 显示全部楼层
10xjzheng 发表于 2014-12-19 11:43
恩,我觉得可能我深究这个问题可能会学到一些东西。
你说的R2=0,这个可能真的有问题耶,不过为什么不是 ...

R2 = 0,这边是栈溢出导致了逻辑上有问题,但CPU并不认为往这边写东西,有错误。

你如果要去深究的话,那么我建议,你还是从最开始入口
即,从栈溢出开始,一步步跟,看看栈都改写了什么,跟着CPU走
CPU告诉我们,这是个不精确的总线访问异常,手册上也没有见更详细的说明
我想要抓出来,难度系数挺大的

我还是觉得意义不是太大
因为系统代码不一样,栈溢出的时机不一样,破坏的东西不一样,表象也就不一样
但有一点是相同的:这是个要修复的bug。

你项目时间充裕的话,可以继续研究
等待你的结果了,再来教我下~


出0入10汤圆

 楼主| 发表于 2014-12-19 14:17:15 | 显示全部楼层
security 发表于 2014-12-19 13:41
R2 = 0,这边是栈溢出导致了逻辑上有问题,但CPU并不认为往这边写东西,有错误。

你如果要去深究的话, ...

今晚一位大神答应给我调调看,因为我还加了STemwin,我能说堆栈溢出是在GUI_Init中吗,而官方这个函数是没有源码的,汗!!后面我进行把堆栈调大到200后发现,这个函数让堆栈的使用达到了102,而之前我的堆栈大小设置为80

出0入8汤圆

发表于 2014-12-19 14:46:18 | 显示全部楼层
10xjzheng 发表于 2014-12-19 14:17
今晚一位大神答应给我调调看,因为我还加了STemwin,我能说堆栈溢出是在GUI_Init中吗,而官方这个函数是 ...

你的栈,不管是80,还是200
都略显小气了,我想硬件条件应该不至于这么寒碜啊

这么秀气的栈,除非你对栈的需求,非常清晰,才敢设置这么秀气的值
你可以看看,官方的启动代码之类的,基本也不会设置这么小
这么小,会让程序每一步都走得很辛苦~~~

出0入0汤圆

发表于 2015-4-8 11:21:16 | 显示全部楼层
楼主解决了没有啊

出0入10汤圆

 楼主| 发表于 2015-4-9 23:51:16 | 显示全部楼层
richyhuang 发表于 2015-4-8 11:21
楼主解决了没有啊

不了了之

出0入0汤圆

发表于 2015-4-10 10:29:58 | 显示全部楼层

数据访问违例异常 太烦了,调ucos会经常遇到.

出0入10汤圆

 楼主| 发表于 2015-4-10 10:51:15 | 显示全部楼层
richyhuang 发表于 2015-4-10 10:29
数据访问违例异常 太烦了,调ucos会经常遇到.

你把堆栈设置大一点试试

出0入0汤圆

发表于 2015-4-12 23:14:44 | 显示全部楼层
10xjzheng 发表于 2015-4-10 10:51
你把堆栈设置大一点试试

没有用,设10K都不行,就申请了一个semaphore,就不行了,不申请就没事,很奇怪啊。

出0入10汤圆

 楼主| 发表于 2015-4-14 20:15:12 | 显示全部楼层
richyhuang 发表于 2015-4-12 23:14
没有用,设10K都不行,就申请了一个semaphore,就不行了,不申请就没事,很奇怪啊。 ...

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

本版积分规则

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

GMT+8, 2024-4-29 21:03

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

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