您的位置:控制工程论坛网论坛 » 软件与程序 » 软件编程经典培训实例 2、防止指针/数组操作越界 案例1

xilinxue

xilinxue   |   当前状态:在线

总积分:16186  2024年可用积分:0

注册时间: 2008-06-26

最后登录时间: 2020-03-22

空间 发短消息加为好友

软件编程经典培训实例 2、防止指针/数组操作越界 案例1

xilinxue  发表于 2008/11/5 18:30:54      1705 查看 3 回复  [上一主题]  [下一主题]

手机阅读


        在香港项目测试中,发现ISDN话机拨新业务号码时,若一位一位的拨至18位,不会有问题。但若先拨完号码再成组发送,会导致MPU死机。
        
处理过程:
        查错过程很简单,按呼叫处理的过程检查代码,发现某一处的判断有误,本应为小于18的判断,写成了小于等于18。           

结  论:
         代码编写有误。

思考与启示:
 1、极限测试必须注意,测试前应对某项设计的极限做好充分测试规划。
          2、测试极限时还要注意多种业务接入点,本例为ISDN。对于交换机来说,任何一种业务都要分别在模拟话机、ISDN话机、V5话机、多种形式的话务台上做测试。对于中继的业务,则要充分考虑各种信令:TUP、ISUP、PRA、NO1、V5等等。

1楼 0 0 回复
  • xilinxue

    xilinxue   |   当前状态:在线

    总积分:16186  2024年可用积分:0

    注册时间: 2008-06-26

    最后登录时间: 2020-03-22

    空间 发短消息加为好友

    xilinxue   发表于 2008/11/5 18:30:04


     对某交换类进行计费测试,字冠011对应1号路由、1号子路由,有4个中继群11,12,13,14(都属于1#模块),前后两个群分别构成自环。其中11,13群向为出中继,12,14群向为入中继,对这四个群分别进行计费设置,对出入中继都计费。电话60640001拨打01160010001两次,使四个群都有机会被计费,取话单后浏览话单发现对11群计费计次表话单出中继群号不正确,其它群的计次表中出中继群号正常。


    处理过程:
     与开发人员在测试组环境多次重复以上步骤,发现11群的计次表话单有时正常,有时其出中继群号就为一个随机值,发生异常的频率比较高。为什么其它群的话单正常,唯独11群不正常呢?11群是四个群中最小的群,其中继计次表位于缓冲区的首位,打完电话后查询内存发现出中继群号在内存中是正确的,取完话单后再查就不正确了。


    结  论:
     话单池的一个备份指针Pool_head_1和中继计次表的头指针重合,影响到第一个中继计次表的计费。


    思考与启示:
     随机值的背后往往隐藏着指针问题,两块内存缓冲区的交界处比较容易出现问题,在编程时是应该注意的地方。

    2楼 回复本楼

    引用 xilinxue 2008/11/5 18:30:04 发表于2楼的内容

  • xilinxue

    xilinxue   |   当前状态:在线

    总积分:16186  2024年可用积分:0

    注册时间: 2008-06-26

    最后登录时间: 2020-03-22

    空间 发短消息加为好友

    xilinxue   发表于 2008/11/5 18:30:30

    案例 3
              在接入网产品A测试中,在内存数据库正常的情况下的各种数据库方面的操作都是正常的。为了进行数据库异常测试,于是将数据库内容人为地破坏了。发现在对数据库进行比较操作时,出现程序跑死了现象。
     经过跟踪调试发现问题出现在如下一段代码中:   
    1 for(i=0; i<pSysHead->dbf_count; i++)
    2 {
    3             pDBFat = (_NM_DBFAT_STRUC *)(NVDB_BASE + DBFAT_OFFSET + i*DBFAT_LEN);
    4  if(fat_check(pDBFat) != 0)
    5  {
    6                 pSysHead->system_flag = 0;
    7                  head_sum();
    8                 continue;
    9             }
    10             if(strlen(dbf->dbf_name) != 0 && strncmp(dbf->dbf_name, pDBFat->dbf_name, strlen(dbf->dbf_name)) == 0)
    11             {
    12                 dbf_ptr1 = (_UC *)pDBFat->dbf_head;
    13                 filesize = pDBFat->dbf_fsize;
    14                  break;
    15            }
    16    }
            在测试时发现程序死在循环之中,得到的错误记录是"Bus Error"(总线出错),由此可以说明出现了内存操作异常。
     经过跟踪变量值发现循环变量i的阀值pSysHead->dbf_count的数值为0xFFFFFFFF,该值是从被破坏的内存数据库中获取的,正常情况下该值小于127。而pDBFat是数据库的起始地址,如果pSysHead->dbf_count值异常过大,将导致pDBFat值超过最大内存地址值,随后进行的内存操作将导致内存操作越界错误,因而在测试过程中数据库破坏后就出现了主机死机的现象。
     上面的问题解决起来很容易,只需在第一行代码中增加一个判断条件即可,如下:
     for(i=0; i<pSysHead->dbf_coun && i < MAX_DB_NUM; i++)
           // MAX_DB_NUM=127


     这样就保证了循环变量i的值在正常范围内,从而避免了对指针pDBFat进行内存越界的操作。


      从上面的测试过程中,我们可以看到:如此严重的问题,仅仅是一个简单的错误引起的。实际上,系统的不稳定往往是由这些看似很简单的小错误导致的。这个问题给我们教训的是:在直接对内存地址进行操作时,一定要保证其值的合法性,否则容易引起内存操作越界,给系统的稳定性带来潜在的威胁。 

    3楼 回复本楼

    引用 xilinxue 2008/11/5 18:30:30 发表于3楼的内容

  • xilinxue

    xilinxue   |   当前状态:在线

    总积分:16186  2024年可用积分:0

    注册时间: 2008-06-26

    最后登录时间: 2020-03-22

    空间 发短消息加为好友

    xilinxue   发表于 2008/11/5 18:30:54

     近日在CDB并行测试中发现一个问题:我们需要的小区负荷话统结果总是为零,开始还以为小区负荷太小,于是加大短消息下发数量,但还为零,于是在程序中加入测试代码,把收到的数据在BAM上打印出来,
     结果打印出来的数据正常,不可能为零,仔细查看相关代码,问题只可能在指针移位上有问题,果然在函数中发现一处比较隐蔽的错误。


    /* 功能:一个BM模块内所有小区CDB侧广播消息忙闲情况     */
    /*************************************************************/
    void Cell_CBCH_Load_Static(struct MsgCB FAR *pMsg)
          {
     。。。
     
     memcpy((_UC *)&tmp_msg,pMsg,sizeof(tmp_msg));
     pMsg=pMsg+sizeof(tmp_msg);//sizeof(tmp_msg)=10;本意是想移动10个字节,可是实际上指针移动了10*sizeof(struct MsgCB)个字节;
     CellNum=tmp_msg.usCellNum;
     。。。
          }
    1
          所以结构指针传入函数后,如要进行指针移动操作,最好先将其转化为_UC型再说。总之指针操作要小心为上。


     

    4楼 回复本楼

    引用 xilinxue 2008/11/5 18:30:54 发表于4楼的内容

总共 , 当前 /