




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
{員工培訓(xùn)制度}華為軟件編程規(guī)范培訓(xùn)案例和練習(xí)軟件編程規(guī)范培訓(xùn)實(shí)例與練習(xí)第一版深圳市華為技術(shù)有限公司說(shuō)明本文分為兩部分,第一部分為中研《關(guān)于規(guī)范開(kāi)發(fā)人員設(shè)計(jì)編碼行為、含來(lái)自測(cè)試人員總結(jié)的大量的包括件編程規(guī)范教學(xué)使用。案例與練習(xí)第一部分深圳市華為技術(shù)有限公司研發(fā)管理辦公室文件關(guān)于規(guī)范開(kāi)發(fā)人員設(shè)計(jì)編碼行為、提高軟件質(zhì)量的通知知,請(qǐng)各開(kāi)發(fā)部門(mén)遵照?qǐng)?zhí)行。>接口類>維護(hù)類>可測(cè)試性。本通知中羅列問(wèn)題如再次出現(xiàn),將進(jìn)行通報(bào)批評(píng)并記入干部部關(guān)鍵事件庫(kù)。問(wèn)題分類邏輯類問(wèn)題(A類)-指設(shè)計(jì)、編碼中出現(xiàn)的計(jì)算正確性和一致性、程序邏輯控嚴(yán)重問(wèn)題;B/局部變量或數(shù)據(jù)變量之間的數(shù)據(jù)/控制傳輸不匹配的問(wèn)題,在系統(tǒng)中起重要作用,將導(dǎo)致模塊間配合失效等嚴(yán)重問(wèn)題;維護(hù)類問(wèn)題(C類)-指設(shè)計(jì)、編碼中出現(xiàn)的對(duì)軟件系統(tǒng)的維護(hù)方便程度造成影上升;可測(cè)試性問(wèn)題(D類)-指設(shè)計(jì)、編碼中因考慮不周而導(dǎo)致后期系統(tǒng)可測(cè)試性差的問(wèn)題。處罰辦法問(wèn)題發(fā)生率:P=D/SD=DA+0.5DB+0.25DC其中:P-問(wèn)題發(fā)生率D-1個(gè)季度內(nèi)錯(cuò)誤總數(shù)DA-1個(gè)季度內(nèi)A類錯(cuò)誤總數(shù)DB-1個(gè)季度內(nèi)B類錯(cuò)誤總數(shù)DC-1個(gè)季度內(nèi)C類錯(cuò)誤總數(shù)S-1個(gè)季度內(nèi)收到問(wèn)題報(bào)告單總數(shù)1)當(dāng)D≥3時(shí),如果P≥3%,將進(jìn)行警告處理,并予以公告;2)當(dāng)D≥5時(shí),如果P≥5%,將進(jìn)行罰款處理,并予以公告。目錄第5頁(yè)一、邏輯類代碼問(wèn)題1、變量/指針在使用前就必須初始化第5頁(yè)【案例1.1.1】第5頁(yè)2、防止指針/數(shù)組操作越界第5頁(yè)【案例1.2.1】第5頁(yè)【案例1.2.2】第6頁(yè)【案例1.2.3】第7頁(yè)【案例1.2.4】第8頁(yè)3、避免指針的非法引用第9頁(yè)【案例1.3.1】第9頁(yè)4、變量類型定義錯(cuò)誤第10頁(yè)【案例1.4.1】第10頁(yè)5、正確使用邏輯與&&、屏蔽&操作符第17頁(yè)【案例1.5.1】第17頁(yè)6、注意數(shù)據(jù)類型的匹配第18頁(yè)【案例1.6.1】第18頁(yè)【案例1.6.2】第18頁(yè)第20頁(yè)7、用于控制條件轉(zhuǎn)移的表達(dá)式及取值范圍是否書(shū)寫(xiě)正確【案例1.7.1】第20頁(yè)【案例1.7.2】第21頁(yè)【案例1.7.3】第22頁(yè)8、條件分支處理是否有遺漏第24頁(yè)【案例1.8.1】第24頁(yè)9、引用已釋放的資源第26頁(yè)【案例1.9.1】第26頁(yè)10、分配資源是否已正確釋放第28頁(yè)【案例1.10.1】第28頁(yè)【案例1.10.2】第29頁(yè)【案例1.10.3】第30頁(yè)【案例1.10.4】第32頁(yè)【案例1.10.5】第33頁(yè)【案例1.10.6】第35頁(yè)【案例1.10.7】第38頁(yè)11、防止資源的重復(fù)釋放第39頁(yè)【案例1.11.1】第39頁(yè)12、公共資源的互斥性和競(jìng)用性第40頁(yè)【案例1.12.1】第40頁(yè)【案例1.12.2】第40頁(yè)第43頁(yè)二、接口類代碼問(wèn)題1、對(duì)函數(shù)參數(shù)進(jìn)行有效性檢查第43頁(yè)【案例2.1.1】第43頁(yè)【案例2.1.2】第43頁(yè)【案例2.1.3】第44頁(yè)【案例2.1.4】第46頁(yè)【案例2.1.5】第47頁(yè)【案例2.1.6】第48頁(yè)2、注意多出口函數(shù)的處理第49頁(yè)【案例2.2.1】第49頁(yè)第51頁(yè)三、維護(hù)類代碼問(wèn)題1、統(tǒng)一枚舉類型的使用第51頁(yè)【案例3.1.1】第51頁(yè)2、注釋量至少占代碼總量的20%第51頁(yè)第51頁(yè)【案例3.2.1】對(duì)XXX產(chǎn)品BAM某版本部分代碼注釋量的統(tǒng)計(jì)第52頁(yè)四、產(chǎn)品兼容性問(wèn)題1、系統(tǒng)配置、命令方式第52頁(yè)【案例4.1.1】第52頁(yè)【案例4.1.2】第53頁(yè)2、設(shè)備對(duì)接第54頁(yè)【案例4.2.1】第54頁(yè)3、其他第55頁(yè)【案例4.3.1】第55頁(yè)第58頁(yè)五、版本控制問(wèn)題1、新老代碼中同一全局變量不一致第58頁(yè)【案例5.1.1】第58頁(yè)第59頁(yè)六、可測(cè)試性代碼問(wèn)題1、調(diào)試信息/打印信息的正確性第59頁(yè)【案例6.1.1】第59頁(yè)一、邏輯類代碼問(wèn)題1、變量/指針在使用前就必須初始化【案例1.1.1】C語(yǔ)言中最大的特色就是指針。指針的使用具有很強(qiáng)的技巧性和靈活性,但同時(shí)也帶來(lái)了很大的危險(xiǎn)性。在XXX的代碼中有如下一端對(duì)指針的靈活使用:......_UC*puc_card_config_tab;......Get_Config_Table(AMP_CPM_CARD_CONFIG_TABLE,&ul_card_config_num,&puc_card_config_tab,use_which_data_area);......b_middle_data_ok=generate_trans_middle_data_from_original_data(puc_card_config_tab,Ul_card_config_num).......其中紅色部分巧妙的利用指向指針的指針為指針puc_card_config_tab賦值,而在蘭色部分使用該指針。但在Get_Config_Table函數(shù)中有可能失敗返回而不給該指針賦值。因此,以后使用的可能是一個(gè)非法指針。指針的使用是非常靈活的,同時(shí)也存在危險(xiǎn)性,必須小心使用。指針使用的危險(xiǎn)性舉世共知。在新的編程思想中,指針基本上被禁止使用(JAVA中就是這樣),至少也是被限制使用。而在我們交換機(jī)的程序中大量使用指針,并且有增無(wú)減。2、防止指針/數(shù)組操作越界【案例1.2.1】1在香港項(xiàng)目測(cè)試中,發(fā)現(xiàn)ISDN話機(jī)撥新業(yè)務(wù)號(hào)碼時(shí),若一位一位的撥至18位,不會(huì)有問(wèn)題。但若先撥完號(hào)碼再成組發(fā)送,會(huì)導(dǎo)致MPU死機(jī)。處理過(guò)程:小于18的判斷,寫(xiě)成了小于等于18。結(jié)論:代碼編寫(xiě)有誤。思考與啟示:1、極限測(cè)試必須注意,測(cè)試前應(yīng)對(duì)某項(xiàng)設(shè)計(jì)的極限做好充分測(cè)試規(guī)劃。2、測(cè)試極限時(shí)還要注意多種業(yè)務(wù)接入點(diǎn),本例為ISDN。對(duì)于交換機(jī)來(lái)說(shuō),任何一種業(yè)務(wù)都要分別在模擬話機(jī)、ISDN話機(jī)、V5對(duì)于中繼的業(yè)務(wù),則要充分考慮各種信令:TUP、ISUP、PRA、NO1、V5等等?!景咐?.2.2】對(duì)某交換類進(jìn)行計(jì)費(fèi)測(cè)試,字冠011對(duì)應(yīng)1號(hào)路由、1號(hào)子路由,有4個(gè)中繼群11,12,13,14(都屬于1#模塊)11,13群向?yàn)槌鲋欣^,12,14話1撥打兩次,使四個(gè)群都有機(jī)會(huì)被計(jì)費(fèi),取話單后瀏覽話單發(fā)現(xiàn)對(duì)11群計(jì)費(fèi)計(jì)次表話單出中繼群號(hào)不正確,其它群的計(jì)次表中出中繼群號(hào)正常。處理過(guò)程:與開(kāi)發(fā)人員在測(cè)試組環(huán)境多次重復(fù)以上步驟,發(fā)現(xiàn)11群的計(jì)次表話單有時(shí)正常,11群不正常呢?11群是四個(gè)群中最小的群,其中繼計(jì)次表位于緩沖再查就不正確了。結(jié)論:話單池的一個(gè)備份指針Pool_head_1和中繼計(jì)次表的頭指針重合,影響到第一個(gè)中繼計(jì)次表的計(jì)費(fèi)。思考與啟示:在編程時(shí)是應(yīng)該注意的地方?!景咐?.2.3】【正文】在接入網(wǎng)產(chǎn)品A測(cè)試中,在內(nèi)存數(shù)據(jù)庫(kù)正常的情況下的各種數(shù)據(jù)庫(kù)方面的操作都對(duì)數(shù)據(jù)庫(kù)進(jìn)行比較操作時(shí),出現(xiàn)程序跑死了現(xiàn)象。經(jīng)過(guò)跟蹤調(diào)試發(fā)現(xiàn)問(wèn)題出現(xiàn)在如下一段代碼中:1for(i=0;i<pSysHead->dbf_count;i++)2{3pDBFat=(_NM_DBFAT_STRUC*)(NVDB_BASE+DBFAT_OFFSET+i*DBFAT_LEN);4if(fat_check(pDBFat)!=0)5{6pSysHead->system_flag=0;7head_sum();8continue;9}10if(strlen(dbf->dbf_name)!=0&&strncmp(dbf->dbf_name,pDBFat->dbf_name,strlen(dbf->dbf_name))==0)11{12dbf_ptr1=(_UC*)pDBFat->dbf_head;13filesize=pDBFat->dbf_fsize;14break;15}16}在測(cè)試時(shí)發(fā)現(xiàn)程序死在循環(huán)之中,得到的錯(cuò)誤記錄是"BusError"(總線出錯(cuò)),由此可以說(shuō)明出現(xiàn)了內(nèi)存操作異常。i的閥值pSysHead->dbf_count的數(shù)值為0xFFFFFFFF,該值是從被破壞的內(nèi)存數(shù)據(jù)庫(kù)中獲取的,正常情況下該值小于127。而pDBFat是數(shù)據(jù)庫(kù)的起始地址,如果pSysHead->dbf_count值異常過(guò)大,將導(dǎo)致pDBFat值超過(guò)程中數(shù)據(jù)庫(kù)破壞后就出現(xiàn)了主機(jī)死機(jī)的現(xiàn)象。for(i=0;i<pSysHead->dbf_coun&&i<MAX_DB_NUM;i++)//MAX_DB_NUM=127這樣就保證了循環(huán)變量i的值在正常范圍內(nèi),從而避免了對(duì)指針pDBFat進(jìn)行內(nèi)存越界的操作。否則容易引起內(nèi)存操作越界,給系統(tǒng)的穩(wěn)定性帶來(lái)潛在的威脅?!景咐?.2.4】近日在CDB并行測(cè)試中發(fā)現(xiàn)一個(gè)問(wèn)題:我們需要的小區(qū)負(fù)荷話統(tǒng)結(jié)果總是為零,加入測(cè)試代碼,把收到的數(shù)據(jù)在BAM上打印出來(lái),結(jié)果打印出來(lái)的數(shù)據(jù)正常,不可能為零,仔細(xì)查看相關(guān)代碼,問(wèn)題只可能在指針移位上有問(wèn)題,果然在函數(shù)中發(fā)現(xiàn)一處比較隱蔽的錯(cuò)誤。/*功能:一個(gè)BM模塊內(nèi)所有小區(qū)CDB側(cè)廣播消息忙閑情況*//*************************************************************/voidCell_CBCH_Load_Static(structMsgCBFAR*pMsg){。。。memcpy((_UC*)&tmp_msg,pMsg,sizeof(tmp_msg));pMsg=pMsg+sizeof(tmp_msg);//sizeof(tmp_msg)=10;本意是想移動(dòng)10個(gè)字節(jié)可是實(shí)際上指針移動(dòng)了10*sizeof(structMsgCB)個(gè)字節(jié);CellNum=tmp_;。。。}所以結(jié)構(gòu)指針傳入函數(shù)后,如要進(jìn)行指針移動(dòng)操作,最好先將其轉(zhuǎn)化為_(kāi)UC型再說(shuō)??傊羔槻僮饕⌒臑樯?。3、避免指針的非法引用【案例1.3.1】【正文】HONET系統(tǒng)的主機(jī)復(fù)位了,工作了。我憑記憶,判斷應(yīng)該是與當(dāng)時(shí)正在測(cè)試的DSL板的端口配置有關(guān)。于是將板上所有端口配置為普通2B+D定位為主機(jī)在DSL端口處理過(guò)程中有重大錯(cuò)誤。數(shù)據(jù),加載后立即重現(xiàn)。并注意到,當(dāng)DSL端口激活時(shí),主機(jī)復(fù)位。仔細(xì)比較兩種數(shù)據(jù)的差別,發(fā)現(xiàn)出現(xiàn)主機(jī)復(fù)位問(wèn)題的數(shù)據(jù)中DSL板配置了MNT/MLT沒(méi)有做DSL端口之間的半永久數(shù)據(jù)。于是在程序中不斷加打印語(yǔ)句,通過(guò)后臺(tái)的DBWIN調(diào)試程序跟蹤,最后終于定位為:每當(dāng)執(zhí)行到portdsl.c的DeviceDslMsgProc()函數(shù)中處理U口透?jìng)鞯膇f(SPC_STATE_OK==pSpcCB->bySpcState)語(yǔ)句時(shí),主機(jī)復(fù)位。但是該語(yǔ)句似乎并無(wú)不妥。再分析整個(gè)函數(shù),pSpcCB在函數(shù)前部分已經(jīng)被賦值,pSpcCB=SpcCB+(PortTable+index)->spcNo;但由于得到indexMNT/MLT(PortTable+index)->spcNo有可能為NULL_WORDpSpcCB可能為非法值。此時(shí)主機(jī)在取進(jìn)行判斷,就不知會(huì)導(dǎo)致什么后果了。代碼為:if((PortTable+index)->spcNo!=NULL_WORD){pSpcCB=SpcCB+(PortTable+index)->spcNo;if(SPC_STATE_OK==pSpcCB->bySpcState){。。。}}修改后,問(wèn)題不再重現(xiàn)。的,再進(jìn)行分析。因?yàn)閱?wèn)題很隱蔽,直接分析海一樣的代碼是很難發(fā)現(xiàn)的。4、變量類型定義錯(cuò)誤【案例1.4.1】【正文】在FRI板上建幾條FRPVC,其DLCI類型分別為:10Bit/2bytes、10bit/3bytes、16bit/3bytes、17bit/4bytes、23bit/4bytes。相應(yīng)的DLCI值為:16、234、991126975MUXPVCDLCI值為16234和991的PVCDLCI=126975的PVC恢復(fù)的數(shù)據(jù)錯(cuò)誤為61439DLCI=的PVC完全沒(méi)有恢復(fù)。對(duì)于17/4類型,DLCI=126975的PVC在恢復(fù)時(shí)變成61439,根據(jù)這條線索,查找原126975-61439=65535把原數(shù)據(jù)的第一個(gè)1給忽略了。此時(shí)第一個(gè)想法是:在程序處理中,把無(wú)符號(hào)長(zhǎng)17bit/4bytes類型又1)先建PVC,DLCI=65535,然后保存,重起MUX,觀察PVC的恢復(fù)情況,發(fā)現(xiàn)PVC能夠正確恢復(fù);(2PVCDLCI=65536MUXPVCPVC不能正確恢復(fù)。碼中有問(wèn)題:int_GetFrDlci(DWORD*dwDlci,char*str,DWORDdwDlciType,DWORDdwPortType,DWORDdwSlotID,DWORDdwPortID){DWORDtempDlci;charszArg[80];1charszLine[80];IDLowPVCEP;DWORDdwDlciVal[5][2]={{16,1007},{16,1007},{1024,64511},{2048,129023},{131072,}};...}typedefstructtagFrPppIntIWF{...WORDwHdlcPort;WORDwHdlcDlci;WORDwPeerHdlcDlci;WORDwPeerOldAtmPort;...}SFrPppIntIWFData;DWORDSaveFrNetIntIWFData(DWORD*pdwWritePoint){BYTEbSlotID,bPeerSlotID;DWORDdwCCID,dwPeerCCID;WORDwHdlcPort,wAtmPort,wIci,wPeerIci,wPeerHdlcPort;WORDwCount;...}DWORDSaveFrNetExtIWFData(DWORD*pdwWritePoint){BYTEbSlotID;DWORDdwCCID,dwPeerCCID;WORDwHdlcPort,wAtmPort,wIci;WORDwCount;...[wCount].bSlotID=bSlotID;[wCount].wHdlcPort=wHdlcPort;[wCount].wHdlcDlci=gFrPVCEP[bSlotID][gFrPVCC[bSlotID][dwCCID].dwLoPVCEP].dwDLCI;[wCount].wOldAtmPort=wAtmPort;[wCount].wAtmDlci=gFrPVCEP[bSlotID][gFrPVCC[bSlotID][dwCCID].dwHiPVCEP].dwDLCI;[wCount].dwMapMode=gFrPVCC[bSlotID][dwCCID].dwMapMode;...}DWORDRestoreFrNetExtIWFData(WORDwSlotID,BYTE*pReadPoint){WORDwCount,wTotalNetIWF;BYTEbSlotID,bHdlcDlciType,bAtmDlciType;WORDwOldAtmPort,wAtmDlci,wHdlcPort,wHdlcDlci;DWORDdwMapMode,dwCIR,dwBe;DWORDdwCCID,dwResult,dwAtmPort;wTotalNetIWF=g_.wFrNetExtIWFNum;...}DWORDRestoreFrHdlcIntIWFData(WORDwSlotID,BYTE*pReadPoint){WORDwCount,wTotalHdlcIWF;DWORDdwCCID,dwPeerCCID,dwAtmPort,dwPeerAtmPort;DWORDdwResult;BYTEbSlotID,bPeerSlotID;WORDwHdlcPort,wOldAtmPort,wCIR;WORDwPeerHdlcPort,wPeerOldAtmPort;...}其中涉及DLCI值的變量都為WORD現(xiàn)WORD和DWORD(無(wú)符號(hào)長(zhǎng)整型)類型在一句中同時(shí)存在的情況,至此可以判斷DLCI值在不同類型時(shí)的取值范圍不同,前三種類型的取值范圍為16~9912048~126975131072~當(dāng)采用前三種DLCI類型時(shí),采用WORD類型最大值為65535,已經(jīng)完全夠用了;而對(duì)于第四種類型時(shí),其取值在超過(guò)65535時(shí),獲取DLCI值的函數(shù)_GetFrDlci()采用DWORD類型,而負(fù)責(zé)保存和恢復(fù)的兩個(gè)函數(shù)SaveFrNetExtIWFData()和RestoreFrNetExtIWFDataDLCI的值當(dāng)作WORD類型進(jìn)行處理,因此導(dǎo)致DLCIDLCIDLCI65536DRAM中,程序運(yùn)行直接從DRAM中獲取數(shù)據(jù),程序不會(huì)出錯(cuò);當(dāng)FRI板復(fù)位或插拔后,需要從FLASH中讀取數(shù)據(jù),此時(shí)恢復(fù)函數(shù)的錯(cuò)誤就表現(xiàn)出來(lái)。另一個(gè)問(wèn)題是為什么23/4類型的DLCI數(shù)據(jù)不能恢復(fù)?這是由于對(duì)于23/4類型的PVC,其DLCI131072~,而程序強(qiáng)制轉(zhuǎn)換并恢復(fù)的數(shù)據(jù)最大只能是65535,所以這條PVC不能恢復(fù)。至此,DLCIDLCI的類型改為DWORD造成很嚴(yán)重的后果?!景咐?.4.2】【正文】在FRI板上建幾條FRPVC,其DLCI類型分別為:10Bit/2bytes、10bit/3bytes、16bit/3bytes、17bit/4bytes、23bit/4bytes。相應(yīng)的DLCI值為:16、234、991126975MUXPVCDLCI值為16234和991的PVCDLCI=126975的PVC恢復(fù)的數(shù)據(jù)錯(cuò)誤為61439DLCI=的PVC完全沒(méi)有恢復(fù)。對(duì)于17/4類型,DLCI=126975的PVC在恢復(fù)時(shí)變成61439,根據(jù)這條線索,查找原126975-61439=65535把原數(shù)據(jù)的第一個(gè)1給忽略了。此時(shí)第一個(gè)想法是:在程序處理中,把無(wú)符號(hào)長(zhǎng)17bit/4bytes類型又1)先建PVC,DLCI=65535,然后保存,重起MUX,觀察PVC的恢復(fù)情況,發(fā)現(xiàn)PVC能夠正確恢復(fù);(2PVCDLCI=65536MUXPVCPVC不能正確恢復(fù)。碼中有問(wèn)題:int_GetFrDlci(DWORD*dwDlci,char*str,DWORDdwDlciType,DWORDdwPortType,DWORDdwSlotID,DWORDdwPortID){DWORDtempDlci;charszArg[80];charszLine[80];IDLowPVCEP;DWORDdwDlciVal[5][2]={{16,1007},{16,1007},{1024,64511},{2048,129023},{131072,}};...}typedefstructtagFrPppIntIWF{...WORDwHdlcPort;WORDwHdlcDlci;WORDwPeerHdlcDlci;WORDwPeerOldAtmPort;...}SFrPppIntIWFData;DWORDSaveFrNetIntIWFData(DWORD*pdwWritePoint){BYTEbSlotID,bPeerSlotID;DWORDdwCCID,dwPeerCCID;WORDwHdlcPort,wAtmPort,wIci,wPeerIci,wPeerHdlcPort;WORDwCount;...}DWORDSaveFrNetExtIWFData(DWORD*pdwWritePoint){BYTEbSlotID;DWORDdwCCID,dwPeerCCID;WORDwHdlcPort,wAtmPort,wIci;WORDwCount;...[wCount].bSlotID=bSlotID;[wCount].wHdlcPort=wHdlcPort;[wCount].wHdlcDlci=gFrPVCEP[bSlotID][gFrPVCC[bSlotID][dwCCID].dwLoPVCEP].dwDLCI;[wCount].wOldAtmPort=wAtmPort;[wCount].wAtmDlci=gFrPVCEP[bSlotID][gFrPVCC[bSlotID][dwCCID].dwHiPVCEP].dwDLCI;[wCount].dwMapMode=gFrPVCC[bSlotID][dwCCID].dwMapMode;...}DWORDRestoreFrNetExtIWFData(WORDwSlotID,BYTE*pReadPoint){WORDwCount,wTotalNetIWF;BYTEbSlotID,bHdlcDlciType,bAtmDlciType;WORDwOldAtmPort,wAtmDlci,wHdlcPort,wHdlcDlci;DWORDdwMapMode,dwCIR,dwBe;DWORDdwCCID,dwResult,dwAtmPort;wTotalNetIWF=g_.wFrNetExtIWFNum;...}DWORDRestoreFrHdlcIntIWFData(WORDwSlotID,BYTE*pReadPoint){WORDwCount,wTotalHdlcIWF;DWORDdwCCID,dwPeerCCID,dwAtmPort,dwPeerAtmPort;DWORDdwResult;BYTEbSlotID,bPeerSlotID;WORDwHdlcPort,wOldAtmPort,wCIR;WORDwPeerHdlcPort,wPeerOldAtmPort;...}其中涉及DLCI值的變量都為WORD現(xiàn)WORD和DWORD(無(wú)符號(hào)長(zhǎng)整型)類型在一句中同時(shí)存在的情況,至此可以判斷DLCI值在不同類型時(shí)的取值范圍不同,前三種類型的取值范圍為16~9912048~126975131072~當(dāng)采用前三種DLCI類型時(shí),采用WORD類型最大值為65535,已經(jīng)完全夠用了;而對(duì)于第四種類型時(shí),其取值在超過(guò)65535時(shí),獲取DLCI值的函數(shù)_GetFrDlci()采用DWORD類型,而負(fù)責(zé)保存和恢復(fù)的兩個(gè)函數(shù)SaveFrNetExtIWFData()和RestoreFrNetExtIWFDataDLCI的值當(dāng)作WORD類型進(jìn)行處理,因此導(dǎo)致DLCIDLCIDLCI65536DRAM中,程序運(yùn)行直接從DRAM中獲取數(shù)據(jù),程序不會(huì)出錯(cuò);當(dāng)FRI板復(fù)位或插拔后,需要從FLASH中讀取數(shù)據(jù),此時(shí)恢復(fù)函數(shù)的錯(cuò)誤就表現(xiàn)出來(lái)。另一個(gè)問(wèn)題是為什么23/4類型的DLCI數(shù)據(jù)不能恢復(fù)?這是由于對(duì)于23/4類型的PVC,其DLCI131072~,而程序強(qiáng)制轉(zhuǎn)換并恢復(fù)的數(shù)據(jù)最大只能是65535,所以這條PVC不能恢復(fù)。至此,DLCIDLCI的類型改為DWORD造成很嚴(yán)重的后果。5、正確使用邏輯與&&、屏蔽&操作符【案例1.5.1】C語(yǔ)言中位與比求模效率高,因而系統(tǒng)設(shè)計(jì)時(shí),對(duì)于模128的地方都改為與127,系統(tǒng)定義的宏為#defineMOD128127和#defineW_MOD127(定義的宏的名字易引起誤解),但實(shí)際程序中還是采取求模,從而引起發(fā)送窗口欲重花了不少時(shí)間?!咎幚磉^(guò)程】:處理過(guò)程如下:#defineMOD128127//隊(duì)列長(zhǎng)128,當(dāng)隊(duì)頭到128時(shí),上其返回。#defineW_MOD127//發(fā)送窗口隊(duì)列,意義同上。在函數(shù)L2_TO_L1()中,有如下語(yǔ)句:linkstate_ptr->=(head+1)%W_MOD;這里當(dāng)head=126=0復(fù)位;另外,在重發(fā)函數(shù)voidINVOKE_RETRANSMISSION(_USlogic_link,_USn_r)中,有如下語(yǔ)句:retran_num=(LinkState[logic_link].Vs+MOD128-(_UC)n_r)%MOD128;w_head=(LinkState[logic_link].+W_MOD-retran_num)%W_MOD;Vs小于n_r位置錯(cuò)開(kāi),從而引起鏈路復(fù)位。上面三個(gè)語(yǔ)句應(yīng)該做如下改動(dòng):linkstate_ptr->=(head+1)&W_MOD;retran_num=(LinkState[logic_link].Vs+MOD128+1-(_UC)n_r)&MOD128;w_head=(LinkState[logic_link].+W_MOD+1-retran_num)&W_MOD;【結(jié)論】:由于鏈路通信對(duì)系統(tǒng)效率要求很高,算法采用效率最高的,但位與(&)和求模(%)這小小的區(qū)別,造成的竟是鏈路復(fù)位這種嚴(yán)重的錯(cuò)誤。一點(diǎn)往往能發(fā)現(xiàn)問(wèn)題,但在測(cè)試中來(lái)定位這種問(wèn)題,花費(fèi)的時(shí)間往往更長(zhǎng)。6、注意數(shù)據(jù)類型的匹配【案例1.6.1】【案例描述】下面通過(guò)測(cè)試中的一個(gè)例子來(lái)說(shuō)明這個(gè)問(wèn)題:命令DSPN7C是用來(lái)顯示NO7電路狀態(tài)的,其參數(shù)設(shè)備類型DID支持TUP和ISUP,參數(shù)信道號(hào)BSN支持多值輸入(最多支持32來(lái)了。1、首先試BSN參數(shù)越界情況,即參數(shù)BSN超過(guò)32路查詢,選了幾個(gè)數(shù)據(jù)段,問(wèn)題0&&300和0&&256對(duì)后者返回執(zhí)行成功。2、對(duì)于參數(shù)DID,選定一種設(shè)備類型(TUP或ISUPBSN所包含的32路電路跨越TUP和ISUP,兩次結(jié)果是不一致的?!咎幚磉^(guò)程】反饋到開(kāi)發(fā)人員那里,第一個(gè)問(wèn)題是BAM的問(wèn)題,第二個(gè)問(wèn)題是SM的問(wèn)題?!窘Y(jié)論】1、為數(shù)據(jù)超出范圍溢出造成,int值賦值給BYTE,造成數(shù)據(jù)丟失。2TUPISUP電路查詢。ISUP的維護(hù)處理函數(shù)判斷第一個(gè)信道不是ISUP信道,認(rèn)為整個(gè)的PCM不是ISUP類型的PCM,返回全部的電路狀態(tài)為未安裝。消息處理不合理。TUP也會(huì)產(chǎn)生如此錯(cuò)誤?!舅伎寂c啟示】我們的MML命令并不是無(wú)懈可擊的,許多表面上的小問(wèn)題,往往隱藏著代碼的缺陷和錯(cuò)誤。【案例1.6.2】【正文】當(dāng)我們使用PC-LINT檢查代碼時(shí),會(huì)發(fā)現(xiàn)大量的數(shù)據(jù)類型不匹配的告警,些情況下,也許會(huì)產(chǎn)生嚴(yán)重的問(wèn)題:情況:1、直接賦值,比如,把一個(gè)WORD型變量賦給一個(gè)INT型變量,如果WORD型變量大于32767,INT型變量得到的就是一個(gè)負(fù)值了。SDH送的告警在BAMFile(XXX),Line(XXX):Invalidalarmid,from:7,AlarmId:65463經(jīng)過(guò)檢查數(shù)據(jù)發(fā)現(xiàn),并沒(méi)有ID為65463的告警,分析上報(bào)的數(shù)據(jù)幀,發(fā)現(xiàn)上報(bào)的告警ID為B7,原來(lái)代碼中有一處強(qiáng)制類型轉(zhuǎn)換:=(WORD)RecvBuffer[iTmpLen+5];char型強(qiáng)制轉(zhuǎn)換成WORD型。B7就變成了FFB765463char是有符號(hào)型,B7的第8位為1,所以轉(zhuǎn)換后為FFB7,而不是代碼作者希望的00B7,如果第8位是0,或該變量是BYTE型,轉(zhuǎn)換就不會(huì)有問(wèn)題了。2、函數(shù)形參和實(shí)參不一致,實(shí)際上和第一種情況本質(zhì)上是一樣的,只是表現(xiàn)的形式不太一樣,這種情況也是代碼中經(jīng)常出現(xiàn)的問(wèn)題,下面例子是測(cè)試中曾經(jīng)發(fā)現(xiàn)的一個(gè)小問(wèn)題:file01中的INTDebugMsgProc(charbyMsg0,charbyMsg1)個(gè)形參都是char型,而實(shí)際傳入的參數(shù)都是BYTE型,結(jié)果函數(shù)中的如下語(yǔ)句:PrintfE(PID_RED,"%dtickstimeout!",byMsg1);在byMsg1大于127時(shí),輸出錯(cuò)誤的結(jié)果。二、不同數(shù)據(jù)類型之間的比較操作個(gè)例子是該類錯(cuò)誤的兩種典型情況:【例三】file02文件中某函數(shù)中如下代碼,可能造成死循環(huán):......inti;WORD*pCheck=(WORD*)p;WORDwCheckSum=*pCheck;pCheck++;for(i=1;i<dwLen/2;i++){wCheckSum^=(*pCheck);pCheck++;}//binlenhadalreadywordalignmentreturn(wCheckSum);......該段代碼是在DOS環(huán)境下用BCi是int2dwLen是DWORD型(4個(gè)字節(jié)),如果dwLen大于65536,那么該函數(shù)就是死循環(huán)了。上面的例子是不同類型變量之間直接比較操作,還有一種情況是函數(shù)的返回值與另一不同類型的變量比較,見(jiàn)下面例子:【例四】file03.c文件中某函數(shù)中如下代碼,while(ftell(fp)<Part[3]){.....}ftell返回longPart是DWORD成死循環(huán)。類似的例子還有很多,類型不匹配的問(wèn)題還有許多種情況,都是代碼中以利用PC-LINT工具對(duì)代碼進(jìn)行細(xì)致的檢查。7、用于控制條件轉(zhuǎn)移的表達(dá)式及取值范圍是否書(shū)寫(xiě)正確【案例1.7.1】【案例描述】:在測(cè)試主機(jī)MPUMPUDT板進(jìn)行一號(hào)對(duì)接,MPU備份倒換卻發(fā)生斷話。具體現(xiàn)象為:如果DT板的第1個(gè)PCM系統(tǒng)電路為故障,則MPU倒換時(shí)復(fù)位該DTDT板的第2個(gè)PCMMPU倒換時(shí)復(fù)位下一塊DT?!咎幚磉^(guò)程】:據(jù)查,MPU32錯(cuò)復(fù)位了下一個(gè)PCM系統(tǒng)32路電路?!窘Y(jié)論】:如此嚴(yán)重問(wèn)題為什么到今天才發(fā)現(xiàn)?因?yàn)槲覀冊(cè)趯?shí)驗(yàn)室中一般采用同一單板的2個(gè)PCM系統(tǒng)自環(huán)進(jìn)行測(cè)試,則不會(huì)在某單板上有故障和空閑電路共存,自環(huán)屏蔽了錯(cuò)誤?!舅伎寂c啟示】:工作應(yīng)盡量模擬網(wǎng)上的實(shí)際環(huán)境進(jìn)行?!景咐?.7.2】如下命令:LSTAMA:TP=NRM,SD=1999&7&1,SA=YES;當(dāng)瀏覽了大約10萬(wàn)張?jiān)敿?xì)話單后,終端與BAM的連接關(guān)閉。重建連接后,發(fā)現(xiàn)話BAMCPU50%以上的利用率,說(shuō)明原來(lái)的任務(wù)仍在執(zhí)行。需要關(guān)一下話單臺(tái)才能恢復(fù)正常。重復(fù)上述步驟,當(dāng)終端與BAM的連接尚未關(guān)閉時(shí)主動(dòng)斷開(kāi)此次連接,結(jié)果同上。多輸出200張?jiān)拞?,這是為了防止過(guò)多話單的輸出顯示會(huì)增加BAM低BAM的性能。查看一下源代碼,問(wèn)題就發(fā)現(xiàn)了。話單臺(tái)控制最多輸出200張?jiān)拞纬绦蛉缦聎hile(timeCur<=timeEnd){timeCur+=tsOneDay;//加一天while((&rpt,sizeof(CBillReport))==sizeof(CBillReport)){.....................//只輸出滿足條件的前200張?jiān)拞蝘f(++wBillCount==200){break;}}//一個(gè)文件查詢結(jié)束}//所有文件查詢結(jié)束在話單輸出200張之后,程序只退出一層循環(huán),仍然會(huì)從下一天話單繼續(xù)輸出,導(dǎo)致向MML發(fā)幀過(guò)多,造成MML和話單臺(tái)都被堵死。修改ProcessQueryBill()函數(shù)//只輸出滿足條件的前200張?jiān)拞蝘f(++wBillCount==200){timeCur=timeEnd+tsOneDay;//退出第二層循環(huán),while(timeCur<=timeEnd)break;}作上述修改后問(wèn)題就不再出現(xiàn)了。一些MML命令從完成的功能來(lái)講可能是沒(méi)什么問(wèn)題的,但其執(zhí)行對(duì)系統(tǒng)性能的影響我們?cè)跍y(cè)試時(shí)時(shí)往往給忽視了。在我們目前的BAM方案中,存在著多個(gè)終端協(xié)同工作,如果某個(gè)終端發(fā)出的命令在BAM中長(zhǎng)時(shí)間獨(dú)占著大部分系統(tǒng)資源,造成的后果是嚴(yán)重的。這是在設(shè)計(jì)時(shí)要避免的,在測(cè)試中要注意的問(wèn)題?!景咐?.7.3】【正文】在判斷模擬用戶端口是否反極性時(shí)有這樣一段程序:if((bsn>=g_wASL32StartPSN)&&(((bsn-g_wASL32StartPSN)%32)==15||((bsn-g_wASL32StartPSN)%32==16)))returnTRUE;if((bsn%16)==7||(bsn%16)==8)returnTRUE;returnFALSE;作者的本意是如果是3215和16路,如果是,就是反極性端口,返回TRUE,否則就不是,應(yīng)該返回FALSE。但代32路用戶板并且端口號(hào)是15或16就返回真值,否則還要執(zhí)行下邊語(yǔ)句。當(dāng)端口在32路用戶板上,但端口號(hào)不是15或16時(shí),不同的32路端口的起始地址g_wASL32StartPSN1516端口被誤認(rèn)為是反極性端口。舉個(gè)例子,當(dāng)g_wASL32StartPSN的值為3000時(shí),端口號(hào)為3000(第一塊板上的第0個(gè)端口)就被認(rèn)為是反極性端口,這與作者的意圖完全相悖。可以將代碼修改如下:if((bsn>=g_wASL32StartPSN){if(((bsn-g_wASL32StartPSN)%32)==15||((bsn-g_wASL32StartPSN)%32==16)))returnTRUE;}elseif((bsn%16)==7||(bsn%16)==8)returnTRUE;returnFALSE;應(yīng)的測(cè)試用例。判斷條件較多時(shí)開(kāi)發(fā)人員也應(yīng)該適當(dāng)分開(kāi)寫(xiě),既使代碼更易讀,又不容易出錯(cuò)。8、條件分支處理是否有遺漏【案例1.8.1】【現(xiàn)象】dbquery.c的DBQ_Init_ANType函數(shù)中如下代碼段缺少應(yīng)有的條件分支,在數(shù)據(jù)異常的情況下,會(huì)產(chǎn)生較嚴(yán)重的問(wèn)題?!咎幚磉^(guò)程】該錯(cuò)誤比較隱蔽,現(xiàn)在說(shuō)明如下:Max2B1QStatTime最大統(tǒng)計(jì)時(shí)間Max2B1QStatPortNum最大統(tǒng)計(jì)端口數(shù)MAX_2B1Q_STAT_PSN最大統(tǒng)計(jì)內(nèi)存分配數(shù)量其中:Max2B1QStatTime(最大統(tǒng)計(jì)時(shí)間)和Max2B1QStatPortNum(最大統(tǒng)計(jì)端口數(shù))的乘積不能大于MAX_2B1Q_STAT_PSN程序如下://查詢數(shù)據(jù)庫(kù),獲得Max2B1QStatTime的值=10;error_code=DB_Query(RID_OTHERS_PARA_INFO,1,(LPDBCondition)&directQueryCond,(BYTEFAR*)&tempstruct0);//查詢數(shù)據(jù)庫(kù)成功if(error_code==DB_SUCCESS){//tempstruct0.data是數(shù)據(jù)庫(kù)中為Max2B1QStatTime配置的值if(tempstruct0.data>MAX_2B1Q_STAT_PSN)Max2B1QStatTime=MAX_2B1Q_STAT_PSN;elseif(tempstruct0.data!=0)Max2B1QStatTime=tempstruct0.data;}//查詢數(shù)據(jù)庫(kù),獲得Max2B1QStatPortNum的值=11;error_code=DB_Query(RID_OTHERS_PARA_INFO,1,(LPDBCondition)&directQueryCond,(BYTEFAR*)&tempstruct0);//查詢數(shù)據(jù)庫(kù)成功if(error_code==DB_SUCCESS){//tempstruct0.data為數(shù)據(jù)庫(kù)中為Max2B1QStatPortNum和Max2B1QStatTime乘積值大于MAX_2B1Q_STAT_PSN的話:if((tempstruct0.data*Max2B1QStatTime)>MAX_2B1Q_STAT_PSN)Max2B1QStatPortNum=MAX_2B1Q_STAT_PSN/Max2B1QStatTime;//如果在合理范圍內(nèi)且不為0的話:elseif(tempstruct0.data!=0)Max2B1QStatPortNum=tempstruct0.data;}此處if-elseif分支沒(méi)有判斷值為0Max2B1QStatPortNum配置的值為0:tempstruct0.data==0,則Max2B1QStatPortNum就為缺省值32?!窘Y(jié)論】由于內(nèi)存限制,Max2B1QStatTime(最大統(tǒng)計(jì)時(shí)間)和Max2B1QStatPortNum(最大統(tǒng)計(jì)端口數(shù))的乘積不能大于MAX_2B1Q_STAT_PSN,如果從數(shù)據(jù)庫(kù)中得到Max2B1QStatTime為MAX_2B1Q_STAT_PSN計(jì)端口數(shù)恰好為0,由于上述代碼沒(méi)有對(duì)tempstruct0.data==0的情況進(jìn)行判斷,Max2B1QStatPortNum為缺省值32,這樣Max2B1QStatTime和Max2B1QStatPortNum乘積已經(jīng)是32倍MAX_2B1Q_STAT_PSN了,遠(yuǎn)遠(yuǎn)超過(guò)了設(shè)計(jì)內(nèi)存的限制。造成這種錯(cuò)誤的原因是判斷語(yǔ)句對(duì)條件判斷不完整?!舅伎寂c啟示】不完全造成的。9、引用已釋放的資源【案例1.9.1】【正文】在計(jì)費(fèi)測(cè)試的過(guò)程中,用呼叫器進(jìn)行大話務(wù)量呼叫測(cè)試。30路話路通過(guò)TUP自環(huán)呼叫另外30路話路,計(jì)費(fèi)數(shù)據(jù)的設(shè)定是這樣的:通過(guò)計(jì)費(fèi)情況索引對(duì)主叫計(jì)費(fèi),單正常,則開(kāi)始呼叫。30路每次呼叫總會(huì)出現(xiàn)一張告警話單,其余話單正常,該告警話單相對(duì)于話路來(lái)說(shuō)是隨機(jī)出現(xiàn)的。間隔只有幾秒鐘,排除了人為修改數(shù)據(jù)的可能。開(kāi)發(fā)人員認(rèn)為是CCB的問(wèn)題,后來(lái)一查果然如此。當(dāng)中繼選線發(fā)生了同搶需要重新選線時(shí),CCB的reset_CCB_for_reseatch_called_location()計(jì)費(fèi)情況分析失敗,產(chǎn)生計(jì)費(fèi)費(fèi)用為0的告警話單。更正reset_CCB_for_reseatch_called_location()中繼時(shí)不清除被叫用戶這部分屬性。思考與啟示:12、計(jì)費(fèi)測(cè)試僅僅打幾次電話往往達(dá)不到效果,越接近用戶實(shí)際使用的情況越可能發(fā)現(xiàn)問(wèn)題。【案例1.9.2】【案例描述】在進(jìn)行128模塊V5用戶CENTREXV5ST用戶只開(kāi)放MCT權(quán)限,在進(jìn)行惡意呼叫追查時(shí),有一次報(bào)惡意呼叫追查成功20種問(wèn)題?!咎幚磉^(guò)程】出現(xiàn)這個(gè)問(wèn)題后,及時(shí)與開(kāi)發(fā)人員A取得了聯(lián)系,并一起試圖重現(xiàn)這個(gè)問(wèn)題,通過(guò)許多次的反復(fù)操作,又出現(xiàn)了一次這種情況。確認(rèn)問(wèn)題后,A表現(xiàn)出高度的責(zé)任心,馬上駕調(diào)試環(huán)境,反復(fù)調(diào)測(cè),終于在當(dāng)天就逮住了狐貍尾巴:1、當(dāng)用戶接聽(tīng)惡意呼叫者的電話,并啟動(dòng)惡意呼叫追查業(yè)務(wù)后,在V5_CR_VOICETONE狀態(tài)下,MCT音的用戶用脈沖方式撥任意一個(gè)數(shù)字,則立即停止送MCT音,而將用戶切換回與惡意呼叫者的通話.但是程序中沒(méi)有對(duì)撥號(hào)類型作判斷,導(dǎo)致用戶若用音頻撥號(hào)也會(huì)作同樣的處理。2、除了取消此次MCT服務(wù),將用戶切換回與惡意呼叫者的通話外,如果不釋放MCT_HANDLE,由于每個(gè)模塊只有一個(gè)這樣的資源,則下一次使用MCT業(yè)務(wù)的用戶不能成功,MCT_HANDLE時(shí)失敗,V5ST模塊在這個(gè)地方處理都有問(wèn)題,沒(méi)有將MCT_HANDLE釋放掉,對(duì)于V5用戶會(huì)聽(tīng)新業(yè)務(wù)失敗音,對(duì)于ST用戶會(huì)聽(tīng)音樂(lè)。V5MCT業(yè)務(wù)時(shí),有時(shí)在聽(tīng)音時(shí),可能由于網(wǎng)板有雜音等原因或),DTR收到一位號(hào),MCT服務(wù),用戶會(huì)聽(tīng)到MCT送音突然中斷,然后恢復(fù)了與惡意呼叫者的通話.而下次再用MCT時(shí),由于上面所述的原因,會(huì)聽(tīng)到新業(yè)務(wù)失敗音,此次失敗后,無(wú)論MCT_HANDLE分配成功與否,MCT1,所以在用戶掛機(jī)時(shí),MCT_HANDLE資源釋放掉.則以后該功能又可以正常實(shí)現(xiàn)。在追查這個(gè)問(wèn)題時(shí),開(kāi)發(fā)人員A又發(fā)現(xiàn)了一個(gè)可能導(dǎo)致死機(jī)的嚴(yán)重問(wèn)題:在用戶啟動(dòng)MCT服務(wù),正在聽(tīng)報(bào)追查號(hào)碼的MCT音時(shí),若惡意用戶此時(shí)掛機(jī),CCB的處理中,STDISCONNECT,V5STRELEASE消息,V5X收到此消息后,將該V5ST用戶的cr2清除掉,V5_USER_TALBE[].cr2變?yōu)?xFFFF,這樣在V5_CR_VOICETONE超時(shí)后,程序中會(huì)檢查cr2的狀態(tài)是否為HOLD,當(dāng)取cr2的內(nèi)容時(shí),由于cr2已被清除,會(huì)發(fā)生指針越界的GP錯(cuò)誤?!窘Y(jié)論】通過(guò)調(diào)測(cè)發(fā)現(xiàn)、定位并解決問(wèn)題?!舅伎寂c啟示】舍的工作。10、分配資源是否已正確釋放【案例1.10.1】【正文】在對(duì)接入網(wǎng)A產(chǎn)品的網(wǎng)管軟件測(cè)試中,發(fā)現(xiàn)了一個(gè)WINDSOWS資源損耗的的問(wèn)題:當(dāng)網(wǎng)管軟件運(yùn)行幾天后,WINDOWS總會(huì)出現(xiàn)“資源不夠”的告警提示。如果網(wǎng)管軟件不關(guān)掉再重新啟動(dòng)的話,就會(huì)出現(xiàn)WINDOWS資源完全耗盡的現(xiàn)象,最終網(wǎng)管系統(tǒng)反應(yīng)很慢,無(wú)法正常工作。這種資源耗盡是一個(gè)緩慢的過(guò)程。如何定位這個(gè)問(wèn)題呢?定位這種問(wèn)題可以利用WINDOWSWindows件/系統(tǒng)工具/資源狀況”,這是一個(gè)系統(tǒng)資源、用戶資源、和GDI資源的實(shí)時(shí)監(jiān)視工具。工具有了,那么如何發(fā)現(xiàn)導(dǎo)致不斷消耗資源的特定操作呢?樣就縮小了監(jiān)視范圍,避免沒(méi)有范圍的碰運(yùn)氣,否則如大海撈針。監(jiān)視前,首先重新啟動(dòng)WINDOWS,最好不運(yùn)行其他的程序,打開(kāi)“系統(tǒng)狀況”這個(gè)監(jiān)視工具,然后運(yùn)行網(wǎng)管軟件,記下此時(shí)的資源狀況數(shù)據(jù)。然后針對(duì)一個(gè)可疑的操作,快速大量地重復(fù)進(jìn)行。這種重復(fù)性的操作可以利用QArunQArun可以記錄操作者的一次操作步驟,然后按照設(shè)定的次就可斷定此項(xiàng)操作會(huì)引起資源耗盡。對(duì)其它可疑的操作和操作組合重復(fù)以上過(guò)程?,F(xiàn)引起資源耗盡原因有:內(nèi)存泄露,畫(huà)筆和畫(huà)刷資源用完后未釋放等?!景咐?.10.2】【正文】某產(chǎn)品后臺(tái)軟件版本,是用C++寫(xiě)的,程序員在寫(xiě)代碼時(shí),經(jīng)常在構(gòu)造函數(shù)中申請(qǐng)一塊內(nèi)存,而不釋放,在程序其他代碼中也經(jīng)常只管申請(qǐng),不管釋放。例如:voidWarnSvr::SaveWarnData(){......for(intm=0;m<RecordsInBuffer[EVENT_ALARM];m++){HISTORY_FILTER_INDEX*item=newHISTORY_FILTER_INDEX;item->Csn=Buffer[EVENT_ALARM][m].Csn;item->Position=m+(RecordsInHistoryFile-RecordsInBuffer[EVENT_ALARM]);//IfawarnwithacertainCsnisnotinEventFilterIndex//itisnotnecessarytobeaddedtoHistoryFilterIndexintitem_total=();BOOLfind_flag=false;for(intk=0;k<item_total;k++)if(EventFilterIndex[k]->Csn==item->Csn){find_flag=true;break;}if(find_flag){(item);if(())ClearIndexEntry();}//建議在此處加上://else//deleteitem;}。重大事故。然而,長(zhǎng)時(shí)間累計(jì)起來(lái),必然會(huì)造成資源緊張而出現(xiàn)故障。行幾天。這個(gè)地方不注意也是原因之一吧。【案例1.10.3】【正文】漏錯(cuò)誤,供測(cè)試人員在代碼審查中參考:1.常處理時(shí)容易出現(xiàn)這種錯(cuò)誤。下面的代碼段就是這樣的例子:.....pRecord=newchar[pTable->GetRecordLength()];assert(pRecord!=NULL);if(pTable->GoTop(FALSE)!=DBIERR_NONE)return;//如果從這里返回,pRecord將得不到釋放.....pTable->Close();1delete[]pRecord;}2.的內(nèi)存將丟失。請(qǐng)看如下代碼段:....structFileInfo*pdbffile=newstructFileInfo;pdbffile->pfileinfo=newstructffblk;pdbffile->srcname=srcRootPath;pdbffile->desname=desRootPath;pdbffile->prev=NULL;pfile=pdbffile;//賦值之前沒(méi)有檢查一下pfilepfile指向的內(nèi)存丟失。dbf_start_needed=FALSE;dbf_Finish=FALSE;flag_begined=TRUE;if(FALSE==Copy(TRUE)){dbf_start_needed=TRUE;WarnMsgOut("Erroroccurswhilecopyingfilesindirectory<dbf>,tryingagain.");}}3.內(nèi)存。....pMsgDB_DEV=(PDBDevMsg)GetBuff(sizeof(DBDevMsg),__LINE__);if(pMsgDB_DEV==NULL)return;pMsgDBApp_To_Logic=(LPDBSelfMsg)GetBuff(sizeof(DBSelfMsg),__LINE__);if(pMsgDBApp_To_Logic==NULL)return;//此處返回造成pMsgDB_DEV指向的內(nèi)存丟失....4.沒(méi)有釋放應(yīng)釋放的內(nèi)存,這種情況一般是缺少應(yīng)有的elseswitch語(yǔ)句的default分支沒(méi)有應(yīng)有的處理。staticvoidOncePowerCmdHandle(structHT_Appmsg*msg){......pPower_test_answer=(struct_oncepower_test_answer*)GetBuff(sizeof(struct_oncepower_test_answer),__LINE__);if(pPower_test_answer==NULL_PTR)return;......if(TSS_State[testpsn].state==TEST_DEV_BUSY||TSS_State[testpsn].state==TEST_DEV_ERROR){...}elseif(TSS_State[testpsn].state==TEST_DEV_IDLE){...}//缺少else分支,可能造成pPower_test_answer得不到釋放}造成內(nèi)存泄漏的情況很多,以上是幾種典型的情況。的健壯性降低。測(cè)試人員在作代碼審查時(shí),對(duì)上述幾種情況要尤其注意?!景咐?.10.4】【正文】在進(jìn)行SAR的PDU包發(fā)收的測(cè)試過(guò)程中要同時(shí)考慮幾個(gè)邊界值,即發(fā)送包大小范圍[0-Nmax],SAR的PDU包接收的最大值Kmax,MBUF塊的大小M.在實(shí)測(cè)中,將SAR的PDU包接收的最大值設(shè)為2000(Kmax=2000B),MBUF的塊長(zhǎng)設(shè)為512(M=512B),則發(fā)送包大小的正確分支的取值為下限0,上限Nmax=2000,然后在0與2000之間隨機(jī)取若干值,MBUF的塊長(zhǎng),M倍數(shù)的若干選值及其附近值.以上是測(cè)試的一般思路,但由于很偶然的機(jī)會(huì)選擇包長(zhǎng)2000,及Kmax=2000B,才發(fā)現(xiàn)問(wèn)題原因如下:MBUF塊長(zhǎng)512,但塊中實(shí)際存放數(shù)據(jù)的只有500(MBUF頭上有2個(gè)長(zhǎng)字,尾部有1個(gè)長(zhǎng)字共12B只用于塊控制),而發(fā)送的包長(zhǎng)正好是500的整數(shù)倍4,由于是整數(shù)倍,所以SAR(BT8230)從FREE鏈上摘成5個(gè)MBUF(原因從略),而SAR驅(qū)動(dòng)只知道有4個(gè)這樣到上層用戶時(shí),4MBUF,1MBUF,經(jīng)過(guò)很短一段時(shí)間后,內(nèi)存即被耗盡.(此問(wèn)題非常嚴(yán)重,因?yàn)樵趯?shí)際運(yùn)用中,500PDU包的概率較小,但一旦出現(xiàn)就會(huì)發(fā)生一次內(nèi)存泄漏,這樣經(jīng)過(guò)若干天或若干月的運(yùn)行后會(huì)使系統(tǒng)崩潰)以前未發(fā)現(xiàn)此問(wèn)題的原因是因?yàn)樵瓉?lái)使用的緩沖塊長(zhǎng)為2048,12B的控制信息,實(shí)際存放數(shù)據(jù)的長(zhǎng)度為2036.由于只考慮了2048這個(gè)值,忽略了2036,所以在選取上下限中的若干值時(shí),2036的倍數(shù)的概率就非常小,因而未發(fā)現(xiàn)該問(wèn)題.由于測(cè)試中一般很難將取值范圍中的所有值覆蓋全,所以在選取上下限中的若干取值時(shí)要格外仔細(xì),考慮的方面盡可能全,因?yàn)楹苡锌赡芷渲心承┲稻褪菧y(cè)試邊界值.凡是涉及的數(shù)字盡量選取,0,2000,512及其整數(shù)倍,500及其整數(shù)倍,12及其整數(shù)倍等值,它們是必測(cè)的邊界值,而非可測(cè)可不測(cè)的隨機(jī)選取的所謂若干選值.【案例1.10.5】【正文】中的函數(shù)rel_ABIS_CCB_conn()中,在進(jìn)行消息鏈表Msg_Queue[ces]的拆鏈操作CCBCCB對(duì)應(yīng)的消息節(jié)點(diǎn)不止一個(gè)的情況就會(huì)出現(xiàn)大量節(jié)點(diǎn)不能釋放的問(wèn)題。if(Msg_Queue[ces].msghead!=NULL_PTR)//messagebuffernotempty{//getfirstmessagerecordpMsgRecord=Msg_Queue[ces].msghead;//releasebuffer-messagesconcerningwithccb_nofor(index=0;index<MSGBUFFERNUM;index++){//這里要對(duì)pMsgRecord的值進(jìn)行判斷if((pMsgRecord!=NULL_PTR)&&pMsgRecord->CCB_no==ccb_no){//freethemessagebufferif(pMsgRecord==Msg_Queue[ces].msghead)//headMsg_Queue[ces].msghead=pMsgRecord->pnext;elseif(pMsgRecord==Msg_Queue[ces].msgtail)//tail{Msg_Queue[ces].msgtail=pPrevMsgRecord;Msg_Queue[ces].msgtail->pnext=NULL_PTR;}else//notheadandtail{pPrevMsgRecord->pnext=pMsgRecord->pnext;}//putbufferbacktobufferpoolif(Msg__num==0){Msg_=Msg_=pMsgRecord;pMsgRecord->pnext=NULL_PTR;//這里將pMsgRecord->pnext置為空Msg__num++;}else{Msg_->pnext=pMsgRecord;pMsgRecord->pnext=NULL_PTR;//這里將pMsgRecord->pnext置為空Msg_=pMsgRecord;Msg__num++;}elseif(pMsgRecord==NULL_PTR)break;//endofif//getnextmessagerecordpPrevMsgRecord=pMsgRecord;pMsgRecord=pMsgRecord->pnext;//這時(shí)pMsgRecord為NULL_PTR將跳出for循環(huán)語(yǔ)句}//endoffor}//endofifpMsgRecordNULL_PTR這樣將不能保證所有與同一個(gè)CCBCCB對(duì)直接影響系統(tǒng)的建鏈過(guò)程,給系統(tǒng)的穩(wěn)定帶來(lái)隱患。決方案,消除了該隱患?!景咐?.10.6】【正文】1、建立一個(gè)呼叫,并保持通話。在AM控存監(jiān)控操作界面中觀察通話建立在哪一塊FBI板上。2FBI察AM控存監(jiān)控操作界面和E3M板2K網(wǎng)界面,發(fā)現(xiàn)AM側(cè)因?yàn)闄z測(cè)到光纖已斷,將通話在CTN、E3M板上占用的時(shí)隙置為空閑,即在AM控存監(jiān)控操作界面和E3M板2K網(wǎng)界面觀察不到時(shí)隙占用情況。3、分別在30秒、1分鐘、3分鐘時(shí)將拔出的FBI板插回原槽位,發(fā)現(xiàn)每次插回FBI板后話音立即恢復(fù)。4、觀察BAM上的打印消息,發(fā)現(xiàn)打印的各模塊占用CTN板大HW上DM時(shí)隙的空閑個(gè)數(shù)比較混亂。打印消息如下圖所示:其中:1)由于模塊1、2、3、4各占用CTN板上兩條大HW,每個(gè)DM時(shí)隙個(gè)數(shù)為256(即由兩條大HW的兩個(gè)DM組成,由于與OPT相聯(lián)的大HW上有兩個(gè)保留時(shí)隙,因此此DM上空閑時(shí)隙個(gè)數(shù)為:254。2)由于E3M板只與一條大HW相聯(lián),故每個(gè)DM上空閑的時(shí)隙個(gè)數(shù)為:128。本現(xiàn)象對(duì)應(yīng)2個(gè)問(wèn)題:idle_count打印混亂,BM釋放故障光路的時(shí)隙和對(duì)應(yīng)的CCB、無(wú)線信道等資源。1、idle_count打印混亂是由于函數(shù)restore_one_hw中的一些處理不當(dāng)造成的,以前被當(dāng)作B型機(jī)的歷史遺留問(wèn)題沒(méi)有重視;2、B2模塊有2條光路,如果斷掉其中一條,模塊狀態(tài)不會(huì)改變,原B型機(jī)程序?qū)Υ瞬蛔魅魏翁幚?,但?yīng)該增加這個(gè)功能,以免光路故障導(dǎo)致資源吊死。解決方法:?jiǎn)栴}一:將函數(shù)restore_one_hw中原代碼作如下改動(dòng):mod_dm[mod][i].=idle_dm_head+125;(idle_dm_head==384)?mod_dm[mod][i].idle_count+=TS_PER_DM-1:mod_dm[mod][i].idle_count+=TS_PER_DM-1;改為:if(idle_dm_head!=384){mod_dm[mod][i].=idle_dm_head+127;mod_dm[mod][i].idle_count+=TS_PER_DM;}else{mod_dm[mod][i].=idle_dm_head+126;mod_dm[mod][i].idle_count+=TS_PER_DM-1;}問(wèn)題二分析如下:目前的模塊狀態(tài)是由IPATH調(diào)用DBMS模塊的邊檢查實(shí)現(xiàn)的,只要存在一條可用的光路,即認(rèn)為相鄰模塊為正常,對(duì)于具體的OPT板上的時(shí)隙狀態(tài)的維護(hù)沒(méi)有與呼OPT板狀態(tài)功能的檢測(cè)是由IPATHBM側(cè)沒(méi)有專門(mén)維護(hù)OPT和MC2板的模塊,將轉(zhuǎn)交OS組處理??偨Y(jié):在拔出FBC板后,通話話音被中斷,AM/CM側(cè)已將與被拔出的FBC板相關(guān)的資源全BM側(cè)主機(jī)程序也應(yīng)該與AM/CM而造成的,即AM/CM側(cè)與BM側(cè)開(kāi)發(fā)人員交流不夠。作為測(cè)試人員對(duì)類似兩個(gè)或多的地方也容易測(cè)出問(wèn)題?!景咐?.10.7】在進(jìn)行有關(guān)排隊(duì)指示的系統(tǒng)測(cè)試中,先閉塞掉基站的所有業(yè)務(wù)信道TCH,進(jìn)行呼叫,再直接掛機(jī)或超時(shí)釋放,發(fā)現(xiàn)TC存在中繼資源吊死的問(wèn)題。ccb超時(shí)后收到AIR發(fā)來(lái)的clearcmd入rel_one_bm_res()ccb所登記的CIC還放在pre_occupied_res放入occuped_res,而rel_one_bm_res()只對(duì)存入occuped_res的CIC進(jìn)行判斷,并向AIE發(fā)UNBOOKCICpre_occupied_res的CICUNBOOKTC的中繼資源吊死。應(yīng)在超時(shí)函數(shù)或釋放函數(shù)中對(duì)pre_occupied_res的CIC進(jìn)行處理。在此過(guò)程中,CIC資源還存放在老CCB的pre_occupied_res函數(shù)中均未對(duì)pre_occupied_res中的CICAIEUNBOOKTC中繼資源吊死。在超時(shí)函數(shù)RR_time_out()中timer_name為T(mén)N_WAIT_ASS_READY時(shí),和釋放函數(shù)rel_one_bam_res()中增加對(duì)CCBpre_occupied_res中的CIC的判斷和釋放處理。們的系統(tǒng)不斷地穩(wěn)定下來(lái)。們的交換機(jī)因?yàn)闊o(wú)資源使用而死掉,要知道,“千里長(zhǎng)堤,毀于蟻穴”。11、防止資源的重復(fù)釋放【案例1.11.1】【正文】AIE收到UNBOOKCIC電路狀態(tài)為空閑,出現(xiàn)一個(gè)斷言。這說(shuō)明AIE電路電路被誤釋放了。這個(gè)問(wèn)題出現(xiàn)的原因有以下幾種:1.RR可能發(fā)錯(cuò)了電路號(hào),導(dǎo)致AIE狀態(tài)錯(cuò)誤。2.AIE可能發(fā)起資源核查,失敗后將本控制表項(xiàng)釋放了。3.RR可能發(fā)起了重復(fù)釋放操作,導(dǎo)致AIE的某個(gè)表項(xiàng)連續(xù)收到兩個(gè)UNBOOK消息。分析完了可能的情況,就要一一分析定位。在可能原因一發(fā)生的情況下,RR發(fā)來(lái)的UNBOOK消息所帶的AIR連接號(hào)和模塊號(hào)會(huì)此可能原因一不成立。在可能原因二發(fā)生的情況下,AIE收到資源核查失敗消息的數(shù)目應(yīng)該不是零。但立。RR這需要進(jìn)行進(jìn)一步分析。程有關(guān)。從統(tǒng)計(jì)代碼中查找異常流程,發(fā)現(xiàn)該次統(tǒng)計(jì)中BSC內(nèi)切換流程多次出現(xiàn)的。因此集中研究這個(gè)流程,發(fā)現(xiàn)存在問(wèn)題如下:當(dāng)原小區(qū)向目標(biāo)小區(qū)發(fā)送內(nèi)部切換請(qǐng)求消息時(shí),帶來(lái)了AIR和AIE側(cè)RR沒(méi)有將占用資源中的AIR和AIEAIR和AIE發(fā)AIRAIE沒(méi)有保護(hù)機(jī)制,新CCB就將AIE電路釋放掉了。而后當(dāng)老CCB在通話結(jié)束后發(fā)起釋放時(shí),就產(chǎn)生了重復(fù)釋放。從上面分析可以看出,這個(gè)問(wèn)題是由于RR對(duì)此加以修改,在新CCB釋放前將AIR和AIE信息從預(yù)占資源中清除。RR的釋放是一個(gè)非常復(fù)雜的過(guò)程,如何正確的整理資源,確保資源的合理釋放,確釋放各種資源,即不會(huì)吊死資源,也不會(huì)產(chǎn)生重復(fù)釋放。12、公共資源的互斥性和競(jìng)用性【案例1.12.1】【正文】試驗(yàn)環(huán)境:CPX8216CPCI機(jī)架、vxWorks操作系統(tǒng)、Tornado1.0.1調(diào)試環(huán)境A向接口板B循環(huán)發(fā)送消息,通過(guò)超級(jí)終端觀察消息的收發(fā)情況。測(cè)試結(jié)果:每發(fā)送一定數(shù)量的消息幀后,會(huì)出現(xiàn)發(fā)送地址出錯(cuò)現(xiàn)象。原因分析:接收板回送緩沖區(qū)指針給發(fā)送板,是采用memcpy單字節(jié)拷貝的方式。memcpy過(guò)程被打斷,即出現(xiàn)發(fā)送板讀發(fā)送地址出錯(cuò)現(xiàn)象。采用四字節(jié)拷貝函數(shù)bcopyLongs傳送發(fā)送緩沖區(qū)指針,問(wèn)題解決。共享內(nèi)存的訪問(wèn)設(shè)計(jì),除了考慮互斥外,還有總線競(jìng)用問(wèn)題?!景咐?.12.2】【正文】問(wèn)題描述:在進(jìn)行主BCCH在數(shù)管臺(tái)設(shè)置“TRX倒換是否允許”為“是”,進(jìn)行設(shè)定整表后,關(guān)閉基站其中配有4個(gè)TRX的小區(qū)的主BCCH所在的TRX電源,發(fā)現(xiàn)對(duì)應(yīng)小區(qū)重新初始化并成功,也就是載頻互助成功。這個(gè)時(shí)候從后臺(tái)對(duì)該小區(qū)所在的站點(diǎn)進(jìn)行4級(jí)復(fù)位,同時(shí)重新打開(kāi)之前關(guān)閉的該小區(qū)的原配主BCCH所在TRX的電源,發(fā)現(xiàn)對(duì)應(yīng)小區(qū)初始化失敗。問(wèn)題定位:在問(wèn)題定位開(kāi)始,先是查看了載頻互助相關(guān)代碼在站點(diǎn)初始化流程中的處理。BTSM生過(guò),再判斷原配主BCCH(即數(shù)據(jù)庫(kù)中實(shí)際配置的主BCCH所在的TRX)是否已經(jīng)恢復(fù)(即能正常建立TEI,能正常設(shè)置該TRX對(duì)應(yīng)的RC屬性,總之能正常開(kāi)工)。若載頻互助發(fā)生過(guò),且原配主BCCH所在的TRX(CoTRXGroupForBts[BtsNo].MainTRX)已經(jīng)恢復(fù),即把之前進(jìn)行互助的TRX(CoTRXGroupForBts[BtsNo].AidTRX)的數(shù)據(jù)和原配的主BCCH所在TRX的數(shù)據(jù)交初始化不成功呢?BCCHTRX與實(shí)際數(shù)據(jù)配置主BCCH所在的TRX為同一TRX是實(shí)際數(shù)據(jù)配置主BCCH所在的TRX不能正常開(kāi)工而借用其他TRX作為主BCCH我們根據(jù)此線索查詢了所有BTSM近合進(jìn)版本的相關(guān)模塊的程序,終于找出了問(wèn)題的根源所在。在載頻互助程序中以全局變量ptrBTS_CONFIG_MAP[BtsNo].TRX_no_BCCH_in表示當(dāng)前實(shí)際運(yùn)行的主BCCH所在的TRX號(hào),是隨時(shí)變化的;以CoTRXGroupForBts[BtsNo].MainTRX表示原配的主BCCH所在的TRX號(hào),是固定的。兩者在系統(tǒng)開(kāi)工的系統(tǒng)開(kāi)工的接口函數(shù)FetchOneSiteConfig該函數(shù)的409行有賦值語(yǔ)句CoTRXGroupForBts[BTS_no_temp].MainTRX=ptrBTS_CONFIG_MAP[BTS_no_temp].TRX_no_BCCH_inFetchOneSiteConfig一次,故CoTRXGroupForBts[BTS_no_temp].MainTRX在系統(tǒng)開(kāi)工以后是不變的,但是在DBMI斷站點(diǎn)下有沒(méi)有發(fā)生過(guò)載頻互助,若發(fā)生過(guò)則試圖先把目前進(jìn)行互助的TRX的數(shù)據(jù)與實(shí)際數(shù)據(jù)配置成主BCCH的TRX的數(shù)據(jù)倒換回來(lái),然后進(jìn)行站點(diǎn)初始化。問(wèn)題就出現(xiàn)在這,在DBMI中認(rèn)為DB中原配的主BCCH的TRX是ptrBTS_CONFIG_MAP[BTS_no_temp].TRX_no_BCCH_in,而且每次進(jìn)行站點(diǎn)初始化時(shí)都調(diào)用函數(shù)FetchOneSiteConfig(),這樣將導(dǎo)致CoTRXGroupForBts[BTS_no_temp].MainTRXDBBCCH不BCCH的相關(guān)數(shù)據(jù)倒換是出現(xiàn)錯(cuò)誤,最終導(dǎo)致相應(yīng)小區(qū)初始化不成功。DBMI與BTSM之間全局變量的用途,如果DBMI與BTSM兩個(gè)功能模塊都認(rèn)為CoTRXGroupForBts[BTS_no_temp].MainTRXBCCHTRX號(hào),那么就不會(huì)出現(xiàn)以上問(wèn)題。現(xiàn)在BSC主機(jī)程序的各個(gè)功能模塊都同時(shí)合進(jìn)了二、接口類代碼問(wèn)題1、對(duì)函數(shù)參數(shù)進(jìn)行有效性檢查【案例2.1.1】【案例描述】某交換類產(chǎn)品BAM后臺(tái)管理系統(tǒng)使用了注冊(cè)表存儲(chǔ)后臺(tái)系統(tǒng)數(shù)據(jù)自動(dòng)備份時(shí)間;影響?!咎幚磉^(guò)程】通過(guò)審查源程序及實(shí)際驗(yàn)證,發(fā)現(xiàn)果然存在問(wèn)題。BAM有關(guān)數(shù)據(jù)自動(dòng)備份程序程統(tǒng)可能會(huì)產(chǎn)生重大影響?!窘Y(jié)論】數(shù)據(jù)設(shè)置。【思考與啟示】系統(tǒng)的數(shù)據(jù)輸入有多種渠道,不僅包括人機(jī)命令、系統(tǒng)INI文件,還包括注冊(cè)表性。【案例2.1.2】【案例描述】設(shè)計(jì)規(guī)定07的TSS板是不支持?jǐn)?shù)字用戶內(nèi),外線強(qiáng)測(cè)的,在對(duì)數(shù)字用戶內(nèi),外線測(cè)試正常后,有意強(qiáng)測(cè)一正在通話的數(shù)字用戶,卻發(fā)現(xiàn)返回報(bào)告:用戶外線測(cè)試------------測(cè)試時(shí)間=1999-06-0316:48:06號(hào)首集=0用戶號(hào)碼=BAM測(cè)試狀態(tài)=正常主機(jī)測(cè)試狀態(tài)=正常AVAG=0.08AVBG=0.29AVAB=-0.21DVAG=0.62DVBG=0.62DVAB=0.00RAG=>10MRBG=>10MRAB=>10MRL=>10MCAG=0.001CBG=0.001CAB=0.001結(jié)論=斷線結(jié)論斷線肯定是錯(cuò)誤的,測(cè)試期間查詢TSSTSS報(bào)告是錯(cuò)誤的?!咎幚磉^(guò)程】修改命令A(yù)DDRTSTI對(duì)應(yīng)的存儲(chǔ)過(guò)程,問(wèn)題解決?!窘Y(jié)論】用戶外線測(cè)試主機(jī)沒(méi)有判用戶是否為數(shù)字用戶?!舅伎寂c啟示】否誤執(zhí)行了,導(dǎo)致錯(cuò)誤的結(jié)論?!景咐?.1.3】【正文】些參數(shù)方面的錯(cuò)誤。下面就一些例子進(jìn)行一些分析,希望能引起大家的重視。1、函數(shù)設(shè)計(jì)中,使用函數(shù)內(nèi)局部變量保存下次函數(shù)重新調(diào)用時(shí)需要的保留值。voidSlaverDownLoadProc(WORDwMsgLength,void*pTempMsgAddr){void*pTempTargetAddr;SSLAVERLOADMSG*pSTempSlaverLoadMsg=(SSLAVERLOADMSG*)pTempMsgAddr;if(COMMON_BOARD_LOAD_PROGRAM==pSTempSlaverLoadMsg->m_ucCmd)pTempTargetAddr=(void*)SDRAM_LOAD_PROG_START_ADDR;#ifndefMMX/*MMX板的數(shù)據(jù)不用加載,用備份方式*/elseif(COMMON_BOARD_LOAD_FPGA==pSTempSlaverLoadMsg->m_ucCmd)pTempTargetAddr=(void*)SDRAM_FPGA_START_ADDR;...caseBEGIN_LOAD:if((LOAD_MIDDLE_FRAME==pSTempSlaverLoadMsg->m_ucLoadCmd)&&((dwRecFrameNum%0xFF)==pSTempSlaverLoadMsg->m_ucOrderNo)){/*序號(hào)和幀的命令字都是合法的,保存BUFFER*/memcpy((BYTE*)pTempTargetAddr,(BYTE*)pSTempSlaverLoadMsg+5,wMsgLength-5);/*5=m_ucBoardType+m_ucCmd+m_ucSerialNo+m_ucLoadCmd+m_ucOrderNo*/dwRecFrameNum++;這里每收到一幀都要調(diào)用此函數(shù),而每次進(jìn)入時(shí),函數(shù)將pTempTargetAddr賦值本應(yīng)作為全局變量的參數(shù)pTempTargetAddr錯(cuò)誤地定義為局部變量。2、當(dāng)函數(shù)的輸入?yún)?shù)較多,并且互相之間有聯(lián)系時(shí),是較易出錯(cuò)的地方。一個(gè)字符時(shí),程序死掉。經(jīng)過(guò)調(diào)試跟蹤,發(fā)現(xiàn)是在input函數(shù)中調(diào)用GetString,40度設(shè)置為4141數(shù)GetString的聲明:signedlongGetString(char*szString,/*OUT:字符串指針*/WORDwSize/*IN:指定的字符串長(zhǎng)度*/)致上溢下溢等。這些都是編程者容易出錯(cuò)的地方,亦是我們大家在走讀代碼時(shí),需要特別注意的地方?!景咐?.1.4】【正文】在交換機(jī)的V5V5V5測(cè)試中都會(huì)很順利地通過(guò)的項(xiàng)目,在以前這個(gè)項(xiàng)目也測(cè)試過(guò)許多次,也從來(lái)沒(méi)有遇到過(guò)異常情況。“V5接口號(hào)、“邏輯C通道ID”V5端口”。ANLE側(cè)也能正常發(fā)起該V5,“V5接口號(hào)”均是非常常規(guī)的數(shù)值,應(yīng)該沒(méi)有問(wèn)題;“邏輯C通道ID”數(shù)值比較65535輯C通道ID”值一直配得比較小,或許問(wèn)題就出在此。于是把“邏輯C通道ID”值改小,再作同樣的操作,操作成功。到此很顯然是這然是該參數(shù)定義的類型有誤。原因是:在函數(shù)OAM_Swap_Communication_Link(_UCv5_interface_UClogic_c_idC_US型即解決。判斷,特別應(yīng)該注意一些特殊值和臨界值,比如在字節(jié)和雙字節(jié)處等等?!景咐?.1.5】現(xiàn)象與分析:在回歸“載頻配置表及跳頻數(shù)據(jù)表中有零頻點(diǎn)或重復(fù)頻點(diǎn)時(shí),MA編碼不正確問(wèn)叫不成功。CA表沒(méi)有錯(cuò)誤,已經(jīng)過(guò)濾掉了重復(fù)頻點(diǎn)和零頻點(diǎn)。在考慮指配命令所帶的MAMA掉重復(fù)頻點(diǎn)和零頻點(diǎn)。經(jīng)過(guò)以上初步分析以后,開(kāi)始懷疑給基站下配置時(shí)是否也正確過(guò)濾了無(wú)效頻點(diǎn)。然后查閱代碼,發(fā)現(xiàn)果然BTSM在對(duì)基站初始化設(shè)置載頻屬性及設(shè)置信道屬性時(shí),點(diǎn)時(shí)跳頻呼叫不成功。回顧與反思:這個(gè)問(wèn)題的發(fā)現(xiàn)并沒(méi)有用什么特殊的分析方法,只不過(guò)是一般的“排除法,而一模塊的修改而引起其他模塊的連鎖反映。本來(lái)RR和BTSMRR首先增加了對(duì)非法頻點(diǎn)的過(guò)濾,本來(lái)是件好事,使我們的BTSM反而起到了相反的效果。公司常說(shuō)“下一道工序是上一道工序的上帝,是不是可以引申為“其他相關(guān)模影響,多及時(shí)了解一下其他模塊的最新進(jìn)展。那么此類問(wèn)題將不再會(huì)發(fā)生.【案例2.1.6】【正文】現(xiàn)象與分析:在動(dòng)態(tài)數(shù)據(jù)配置測(cè)試增加小區(qū)時(shí),發(fā)現(xiàn)小區(qū)不能正常初始化。觀察ABIS_BTSM接口跟蹤窗口,沒(méi)有關(guān)于初始化流程的相關(guān)消息。經(jīng)過(guò)分析發(fā)現(xiàn)是調(diào)用函數(shù)。BTSM_make_send_site_config(_UCsite_no,_UCObjectClass,_USBTS_no,_UCTRX_no,_UCOperMode){………//判斷合法性if((site_no>=MAX_SITE_NUM)||(BTS_no>=MAX_BTS_NUM)||(TRX_no>=MAX_TRX_A_BTS)){ASSERT(FALSE);return(FALSE);}………1}TRX_NO以0xFF時(shí)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 公司股權(quán)授權(quán)合同范本
- 光纖面板采購(gòu)合同范本
- 商場(chǎng)門(mén)店售賣(mài)合同范本
- 中華美德頌的演講稿
- 中專生學(xué)期個(gè)人總結(jié)
- 個(gè)人賣(mài)房委托書(shū)
- 分公司注銷合同范本
- 下半年會(huì)計(jì)工作總結(jié)
- 不起訴合同范本
- 代評(píng)職稱合同范本
- 深圳市一模+Z20名校聯(lián)盟+浙江名校協(xié)作體高三語(yǔ)文2月聯(lián)考作文題目解析及相關(guān)范文
- 油氣田開(kāi)發(fā)專業(yè)危害因素辨識(shí)與風(fēng)險(xiǎn)防控
- DB37-T4824-2025 鄉(xiāng)鎮(zhèn)(街道)應(yīng)急物資配備指南
- 教育部人文社科 申請(qǐng)書(shū)
- 無(wú)菌手術(shù)臺(tái)鋪置的細(xì)節(jié)管理
- 《重大基礎(chǔ)設(shè)施項(xiàng)目涉及風(fēng)景名勝區(qū)選址論證報(bào)告編制技術(shù)規(guī)范》編制說(shuō)明
- 議論文8(試題+審題+范文+點(diǎn)評(píng)+素材)-2025年高考語(yǔ)文寫(xiě)作復(fù)習(xí)
- 2025-2030年(全新版)中國(guó)軟冰淇淋市場(chǎng)發(fā)展趨勢(shì)與投資戰(zhàn)略研究報(bào)告
- 2025新人教版英語(yǔ)七年級(jí)下單詞默寫(xiě)表(小學(xué)部分)
- 2024年大慶醫(yī)學(xué)高等??茖W(xué)校高職單招語(yǔ)文歷年參考題庫(kù)含答案解析
- 2025江蘇蘇州高新區(qū)獅山商務(wù)創(chuàng)新區(qū)下屬國(guó)企業(yè)招聘9人高頻重點(diǎn)提升(共500題)附帶答案詳解
評(píng)論
0/150
提交評(píng)論