通业开发人论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 412|回复: 0

list链表未加保护锁导致链表指针失效,程序崩溃

[复制链接]
发表于 2015-6-9 18:21:18 | 显示全部楼层 |阅读模式
psr: 0x41000000
pc: 0x08019896
lr: 0x0800b1ef
r12: 0x00001268
r03: 0xff28da00
r02: 0x53b442a5
r01: 0x20006c74
r00: 0x00000000
hard fault on thread: logic
thread  pri  status      sp     stack size max used   left tick  error
-------- ---- ------- ---------- ---------- ---------- ---------- ---
console  0x0f ready   0x00000080 0x00000400 0x00000080 0x00000001 -02
pm_tx    0x08 suspend 0x00000080 0x00000400 0x00000080 0x00000005 000
inv_tx   0x08 suspend 0x00000080 0x00000400 0x00000080 0x00000005 000
inv_rx   0x08 suspend 0x00000080 0x00000400 0x00000080 0x00000005 000
tidle    0x1f ready   0x0000005c 0x00000400 0x00000064 0x00000011 000
tshell   0x14 suspend 0x00000094 0x00000800 0x00000094 0x00000009 000
logic    0x09 ready   0x00000078 0x00000400 0x00000088 0x00000005 000
flash    0x14 suspend 0x00000080 0x00000800 0x00000080 0x00000005 000
relay    0x02 suspend 0x00000080 0x00000400 0x00000080 0x00000005 000
ad       0x01 suspend 0x00000080 0x00000400 0x00000080 0x00000005 000


代码段如下:

void FailureCheck::ResetFaulture()
{
        failureList.Begin();
        Failure * tmp = failureList.Next();
        while (tmp != NULL)
        {
            tmp->Reset();
            tmp = failureList.Next();
        }
        fault = 0;
}
其中 pc: 0x08019896指针指向Next()函数,但是Next函数的this指针已经指向0xff28da00的非法地址.

分析经过

void FailureCheck::ResetFaulture()
{
        failureList.Begin();
        Failure * tmp = failureList.Next();
        Failure * bak = tmp;
        Failure * start = tmp;
        while (tmp != NULL)
        {
            tmp->Reset();
            bak = tmp; //1
            tmp = failureList.Next();
            ASSERT((start  < tmp)  && (tmp > null));//程序与此处assert失败//2
        }
        fault = 0;
}
1处的指针正常
2处指针为0指针指向的地址,不等于1处的下一个数据
经分析,在1处和2处之间,程序被跳转到别处执行操作failureList链表.也就是说别的程序中执行了failureList.Next();操作,且执行到链表结束.

解决方案

void FailureCheck::ResetFaulture()
{
    if(!listLock)//添加一个简单的list锁.如果不允许被跳开,一般情况下不需要.但如果真需要,请加线程阻塞操作.请写各自应用的人自行添加.
    {
        listLock = true;
        failureList.Begin();
        Failure * tmp = failureList.Next();
        while (tmp != NULL)
        {
            tmp->Reset();
            tmp = failureList.Next();
        }
        fault = 0;
        listLock = false;
    }
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|TongYe R&D Inc.

GMT+8, 2024-4-28 14:16 , Processed in 0.117007 second(s), 15 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2000-2022, Tongye. 粤ICP备17061194号

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