Chinaunix首页 | 论坛 | 博客
  • 博客访问: 573837
  • 博文数量: 493
  • 博客积分: 2891
  • 博客等级: 少校
  • 技术积分: 4960
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 17:11
文章分类

全部博文(493)

文章存档

2010年(493)

分类:

2010-05-12 19:01:42

在设计这部分代码的时候,由于SUN的机器的new操作的性能不佳,为了减少new操作,尽量减少计数器对server性能的影响,所以在处理数组的方式上完全摒弃了C++的vector,使用的是C中的数组下标操作;这样在初始化的时候只需要一次性的分配一个比较大的堆内存,通过指针的偏移来进行数组操作;这样的操作优点是性能比较高,但是缺点是必须对指针的偏移量进行判断,所以在红色的代码部分对指针的偏移量进行了判断,以保证不会出现内存越界的情况。          
但是忙中出错,蓝色的部分却没有做判断,由于偏移的初始值是iSDAccountNameCode = -1,但是又没有做判断,所以iCurPos = DEF_MMS_FETCH_MM4_SND_SDACCOUNT_CURRENT(iSDAccountNameCode);得到的是一个负数,通过下标的移位,超出了这个数组实际的范围,本来是想对蓝色的内存区域进行读写,但是实际却对不属于自己的红色的内存区域进行了读写。
     如果在进行读写内存的时候,这个红色的区域并没有分配给其他的线程,那么不会出现coredump,但是如果这个时候这块区域已经分配给其他的线程了,那么对这块内存的写操作会改变内存中实际存储的内容,很容易使得那个线程由于读到了一个非法的值,造成server core。
3 结论:解决方案及效果
最后这个问题的解决也非常简单,只在蓝色的代码部分对iSDAccountNameCode做了一个判断,判断其是不是一个合法的值:
       如下:
          if (iSDAccountNameCode < DEF_MMS_FETCH_MM4_RCV_SDACCOUNT_START
                   || iSDAccountNameCode > DEF_MMS_FETCH_MM4_RCV_SDACCOUNT_END)
          {
               continue;
          }
          iCurPos = DEF_MMS_FETCH_MM4_SND_SDACCOUNT_CURRENT(iSDAccountNameCode);
          //Begin Added by xuxiaoyu 42480 on 20050908 for NYGD06059                    
(*(it_main->second))[iCurPos].SetAccountDataNameCode(iSDAccountNameCode);                     
(*(it_main->second))[iCurPos].SetSrcMMSCID(iSrcMMSCID);                     
(*(it_main->second))[iCurPos].SetDestMMSCID(iDestMMSCID);
         //End Added by xuxiaoyu 42480 on 20050908 for NYGD06059
          iAccount = (*(it_main->second))[iCurPos].GetAccount() + (*it_vector).GetAccount();                     
(*(it_main->second))[iCurPos].SetAccount(iAccount);
}
 
自从添加了红色的代码以后,由这个原因引起的server的core从此消失。
4 经验总结:预防措施和规范建议
         在进行数组的下标操作的时候需要注意的问题是必须对其下标进行判断,避免内存越界的问题,否则会出现一堆乱七八糟的错误让定位无所适从。
5 备注
6 考核点
数组下标操作
7 试题
请选择下面哪段代码可能会引起程序core A、C、D
A.
CDistable distables[MAX__DISTABLE_NUM];
CDistable GetDistableByIndex(int nIndex)
{
    return distables[nIndex];
}
B.
CDistable distables[MAX__DISTABLE_NUM];
CDistable GetDistableByIndex(int nIndex)
{
    if ((nIndex >= 0) && (nIndex < MAX__DISTABLE_NUM))
    {
        return distables[nIndex];
    }
   
    return NULL;
}
C.
CDistable distables[MAX__DISTABLE_NUM];
CDistable GetDistableByIndex(int nIndex)
{
    if ((nIndex >= 0) && (nIndex <= MAX__DISTABLE_NUM))
    {
        return distables[nIndex];
    }
   
    return NULL;
}
D.
CDistable distables[MAX__DISTABLE_NUM];
CDistable GetDistableByIndex(int nIndex)
{
    if (nIndex < MAX__DISTABLE_NUM)
    {
        return distables[nIndex];
    }
   
    return NULL;
}
阅读(378) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~