




已阅读5页,还剩14页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2020/5/5,PSST系统工程部C语言软件编程规范工作组,公司常见软件编程低级错误:野指针,前言,这套材料作为编程规范的辅助材料,帮助大家理解编程规范背后的原理。C和C+语言是我司的主流编程语言,然而C/C+具有很多强大的语言特性,从而导致C/C+非常复杂,使得代码更容易出现BUG、难以阅读和维护。业界知名的编程规范都对C/C+容易出现问题的语言特性进行管理。例如MISRA(汽车工业软件可靠性联合会)制定的1998版的MISRAC规范指出,一些在C看来可以接受,却存在隐患的地方有127处之多。2004版的MISRAC规范将针对C语言的规则增加到了141条。对于程序员来说,能工作的代码并不等于“好”代码。“好”代码的指标很多,包括可读性、可维护性、可移植性和可靠性等。出现网上问题的代码,大多数是不良编程习惯引起的。不遵守编程规范的代码,往往也是最不可靠的代码。本胶片收集了常见的野指针案例,给出了相应的纠正措施。对应的编程规范:防止引用已经释放的内存空间,野指针:多模块调用的指针删除未赋NULL,【问题描述】当D服务执行过程完成后,最后一次修改内存数据库中的数据时发生coredump。【问题定位】D服务coredump处的代码如下:/new一个CChargEvent对象,用于向共享内存中写入数据pobjChargingEvent=newCChargingEvent;/使用m_pSessionContext将pobjChargingEvent传递给其他模块m_pSessionContext-setDestTLV(pobjChargingEventEx);deletepobjChargingEvent;/该行代码是读取操作内存数据库事务ID的,每当调用对内存数据库中的数据进行修改时,都会执行该行代码。TransactionKey=pCBSContext-getTransactionKey();/发生coredump处getTransactionKey的代码见下页,野指针:多模块调用的指针删除未赋NULL(续),voidCCBSSessionContext:setDestTLV(CChargingEvent*pChargingEvent)m_pDestTLV=pChargingEvent;ENIP:TInt8CCBSSessionContext:getTransactionKey()if(NULL=m_pDestTLV)return0;m_pDestTLV-getInt8Tag();【纠正措施】在D服务中语句“deletepobjChargingEvent;”之后加上语句“m_pSessionContext-setDestTLV(NULL);”即可。【举一反三】耦合度较强的模块互相调用时,一定要仔细考虑其调用关系,防止已经删除(析构)的对象被再次使用。,野指针:传递参数为局部变量,【问题描述】SWM在下载升级包操作中增加了一个版本号参数,在验证中发现,对版本的校验中使用的版本号并非传入的版本号,而是被截断了,只保留了前20位,造成比较结果不一致。【问题定位】根据命令执行流程,在参数传递的每一个环节增加调试打印。发现是在调用VOS_CreateTask创建下载任务的环节,传入的版本号参数被截断。代码如下:VOS_CHARacSoftVerSWM_VERSION_LEN=0;.aulArgs0=(VOS_UINT32)pTmpFtpInfo;aulArgs1=enFileType;aulArgs2=(VOS_UINT32)pInMsg;aulArgs3=(VOS_UINT32)acSoftVer;/*Createanewtaskforloading*/ulRet=VOS_CreateTask(SWM_COMM,由于acSoftVer是局部变量,在VOS_CreateTask函数执行退出后便被释放,已经变成一个野指针。而SWM_OMUFtpTask函数和SWM_DldVerPkg函数却仍在使用,这就造成了指针所指内容被破坏。【纠正措施】acSoftVer改为动态分配内存,在SWM_OMUFtpTask函数退出前释放。,临时对象产生野指针(1),【问题描述】报文结果中总是随机出现乱码,过一会儿又正常了。【问题定位】检视代码发现使用临时对象:constTCHAR*pTempSave=(g_pSmuMEControl-GetErrInfoByID().c_str();SMU_PARA_COPY(pTemp,pTempSave);GetErrInfoByID返回的是该函数内部定义的临时string变量,当函数调用过程完成后,临时变量的生命期就结束,变量将被删除。所以pTempSave指向内存已释放(野指针),继续使用,有时正常,有时出错。【纠正措施】将临时对象赋值给变量,修改代码如下:conststring,临时对象产生野指针(2),【问题描述】代码飞检发现如下代码:std:ostringstreamoStream;constchar*cValue=oStream.str().c_str();.【问题定位】oStream.str()返回临时对象,他们将在表达式结尾析构。指针cValue指向内存已释放,变成了野指针。【纠正措施】将临时对象赋值给变量,修改代码如下:std:ostringstreamoStream;conststring,野指针:操作已发送消息的内存,【问题描述】在测试产品单板倒换功能时候,测试人员拔掉工作板,发现业务中断了。【问题定位】检查代码,发现:Rc=piDmmMb-AllocMsg(void*)(,未捕获异常导致野指针,【问题描述】产品A在测试中偶然发现XXX模块乱core,产品A运行环境是solaris平台。【问题定位】dbx分析;发现这些core都和变量m_mapMapedAlarmConds相关。MAPm_mapAllAlarmConds;Core的共同点是:从m_mapAllAlarmConds取得某一个CAlarmCond对象指针,调用该对象方法时core;而且这种core很随机和偶然,并不是每一次上述操作都会core。据此,怀疑m_mapAllAlarmConds中存在CAlarmCond*的野指针。检视CAlarmCond*相关维护代码,发现如下代码可疑:intCAlarmCondManager:AddCond(constSAlarmPara,未捕获异常导致野指针(续一),if(m_mapAllAlarmConds.end()=m_mapAllAlarmConds.find(nNewAlarmID)m_mapAllAlarmCondsnAlarmID=ptrAlarmCond.get();nAlarmID=nNewAlarmID;if(0ucSubSystemNo,/*/*pucHead的值是数组pRcvDataInfo-aucValue0的值,而不是pRcvDataInfo-aucValue,当访问pucHead指向的数据时会得到意想不到的结果*/【纠正措施】通过将pRcvDataInfo-aucValue赋给局部变量,并将该局部变量的地址作为函数HPU_RcvDataFromAtm的参数,问题得到解决。pucBuf=pRcvDataInfo-aucValue;HPU_RcvDataFromAtm(pRcvDataInfo-ucSubSystemNo,野指针:返回局部对象指针,【问题描述】在上线过程中,在前台装机入网界面中,点击选号按钮,选中某一号码时提示内存访问异常,同时后台服务coredump一次,之后服务被自动重启,反复进行这个选号过程,问题有时候出现、有时候结果是正常的。【问题定位】通过代码进行白盒测试,发现:char*CPreSelNbrDM:GetParameterByIDAddData(CActor*Actor,constchar*paraID,constchar*AddID)CDBConnectm_DBConnect;。returnm_DBConnect.GetString(ParamValue);分析上述函数的代码很容易发现,定义了一个局部的DBConnect对象,而这个对象的分配空间将在函数退出的时候被释放。而在调用的地方,对返回的char*类型的返回值进行atoi的操作。试图得到一个int型的结果。访问了非法的内存。【纠正措施】将函数的返回值改为int型。intCPreSelNbrDM:GetParameterByIDAddData(CActor*Actor,constchar*paraID,constchar*AddID)CDBConnectm_DBConnect;。returnatoi(m_DBConnect.GetString(ParamValue);,重复释放内存,【问题描述】在Diameter项目组开发时,碰到了一个core的问题,经过gdb跟踪,发现是在执行下面的语句(斜体表示)时出现的core:IDiamTransport*pConnector=NULL;pConnector=m_pIDiamTransportManager-create(ptTCPConnector,tPeerData.connId);CDiamPeerEntity*pPeerEntity=NULL;NEW(pPeerEntity,CDiamPeerEntity);DInt4nErr=pPeerEntity-initialize(tPeerData,pConnector,this,m_pLogger,pIDiamTimer,m_pIDiamBaseStackInner,bServer);/peerEntity的初始化函数if(DIAM_SUCCESS!=nErr)DELETE(pPeerEntity);if(NULL!=pConnector)m_pIDiamTransportManager-destroy(pConnector);/出现core现象pConnector=NULL;returnDIAM_FAILED;上面m_pIDiamTransportManager-destroy(pConnector)语句,在执行之前判断了pConnector是否为NULL,应该属于正常的内存释放,但这里出现了core现象,实在比较让人费解。,重复释放内存(续一),【问题定位】在跟踪pPeerEntity-initialize(tPeerData,pConnector,this,m_pLogger,pIDiamTimer,m_pIDiamBaseStackInner,bServer)函数的实现时,发现了下面的语句:m_pConnector=pConnector;并且CDiamPeerEntity类的析构函数中有下面的语句:if(NULL!=m_pPeerManager-getTransportManager()导致了core的产生。,重复
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 福建省莆田市仙游第一中学2025-2026学年高二上学期开学质量检测政治试题(含解析)
- 2025年光伏行业投资策略分析报告:长风破浪会有时策施暖霭起新程
- 幸福航空安全培训课件
- 2025年公募QDII 香港互认基金投资策略分析报告:多管齐下机遇全球 资产
- 巡察宣传课件
- 岩土工程勘察安全培训课件
- 输液速度课件
- 电商平台跨境电商用户权益保护合同
- 互联网医疗平台股权投资与医疗服务协议
- 城市综合体商铺代理销售与商业品牌组合合同
- 蔬菜抗营养成分流失工艺考核试卷及答案
- 极端天气下灾害风险评估方案
- 民警培训安全驾驶简报课件
- 消毒灭菌效果监测报告
- 2025年软工导论期末试题及答案
- 2024统编版八年级历史上册全册知识点复习提纲
- 虚拟服装培训教程课件
- 2025年国防教育知识竞赛试题(附答案)
- 电能计量装置安装接线规则
- 心律失常介入培训教材课后练习及答案
- 大小球分拣传送机械控制系统设计
评论
0/150
提交评论