華為軟件編程規(guī)范培訓(xùn)案例和練習(xí) (一)_第1頁
華為軟件編程規(guī)范培訓(xùn)案例和練習(xí) (一)_第2頁
華為軟件編程規(guī)范培訓(xùn)案例和練習(xí) (一)_第3頁
華為軟件編程規(guī)范培訓(xùn)案例和練習(xí) (一)_第4頁
華為軟件編程規(guī)范培訓(xùn)案例和練習(xí) (一)_第5頁
已閱讀5頁,還剩63頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

華為軟件編程規(guī)范培訓(xùn)案例和練習(xí)

軟件編程規(guī)范培訓(xùn)

實(shí)例與練習(xí)

第一版

深圳市華為技術(shù)有限公司

說明

本文分為兩部分,第一部分為中研

《關(guān)于規(guī)范開發(fā)人員設(shè)計(jì)編碼行為、

提高軟件質(zhì)量的通知》文件,其中包

含來自測試人員總結(jié)的大量的包含

邏輯類、接口類、保護(hù)類與可測試類

四個(gè)方面的生動(dòng)實(shí)例,是典型的軟件

編程規(guī)范培訓(xùn)實(shí)例,亦可供我司員工

自學(xué);第二部分是一個(gè)練習(xí),作為軟

件編程規(guī)范教學(xué)使用。

案例與練習(xí)

第一部分

深圳市華為技術(shù)有限公司

研發(fā)管理辦公室文件

關(guān)于規(guī)范開發(fā)人員設(shè)計(jì)編碼行為、提高軟件質(zhì)量的通知

為更有效地貫徹執(zhí)行《軟件編碼規(guī)范總則》,強(qiáng)化開發(fā)人員規(guī)范意識,

進(jìn)一步規(guī)范開發(fā)人員的設(shè)計(jì)、編碼習(xí)慣(至少“犯過的錯(cuò)誤,不能再犯”),為

流程下游部門(如測試部)提供高質(zhì)量的輸出,使卜.游部門避免低效、重復(fù)勞動(dòng),

特此通知,請各開發(fā)部門遵照執(zhí)行。

下列問題由測試部的問題單、案例分類匯總而成,將常見設(shè)計(jì)、編嗎問

題分為四類:邏輯類、接口類、保護(hù)類與可測試性,問題級別為:邏輯類〉接

口類>保護(hù)類>可測試性。

本通知中羅列問題如再次出現(xiàn),將進(jìn)行通報(bào)批判并記入干部部關(guān)鍵事件

庫。

?問題分類

邏輯類問題(A類)一指設(shè)計(jì)、編碼中出現(xiàn)的計(jì)算正確性與一致性、程序

邏輯操縱等方面出現(xiàn)的問題,在系統(tǒng)中起關(guān)鍵作用,將導(dǎo)致軟件死機(jī)、功能正常

實(shí)現(xiàn)等嚴(yán)重問題;

接口類問題(B類)一指設(shè)計(jì)、編碼中出現(xiàn)的函數(shù)與環(huán)境、其他函數(shù)、全

局/局部變量或者數(shù)據(jù)變量之間的數(shù)據(jù)/操縱傳輸不匹配的問題,在系統(tǒng)中起重要

作用,將導(dǎo)致模塊間配合失效等嚴(yán)重問題;

保護(hù)類問題(C類)一指設(shè)沖、編碼中出現(xiàn)的對軟件系統(tǒng)的保護(hù)方便程度

造成影響的問題,在系統(tǒng)中不起關(guān)鍵作用,但對系統(tǒng)后期保護(hù)造成不便或者導(dǎo)致

保護(hù)費(fèi)用上升;

可測試性問題(D類)一指設(shè)計(jì)、編碼中因考慮不周而導(dǎo)致后期系統(tǒng)可測

試性差的問題。

?處罰辦法

問題發(fā)生率:

P=D/S

D=DA+O.5DB+0.25DC

其中:

P一問題發(fā)生率

D一1個(gè)季度內(nèi)錯(cuò)誤總數(shù)

4―1個(gè)季度內(nèi)A類錯(cuò)誤總數(shù)

抹一1個(gè)季度內(nèi)B類錯(cuò)誤總數(shù)

D—1個(gè)季度內(nèi)C類錯(cuò)誤總數(shù)

S—1個(gè)季度內(nèi)收到問題報(bào)告單總數(shù)

1)當(dāng)時(shí),假如P,3%,將進(jìn)行警告處理,并予以公告:

2)當(dāng)D25時(shí),假如P25%,將進(jìn)行罰款處理,并予以公告。

目錄

第5頁

一、邏輯類代碼問題

1、變量/指針在使用前就務(wù)必初始化第5頁

【案例第5頁

2、防止指針/數(shù)組操作越界第5頁

【案例121】第5頁

【案例122】第6頁

【案例123】第7頁

【案例124】第8頁

3、避免指針的非法引用第9頁

【案例第9頁

4、變量類型定義錯(cuò)誤第10頁

【案例141】第1°頁

5、正確使用邏輯與&&、屏蔽&操作符第*頁

【案例151】第*頁

6、注意數(shù)據(jù)類型的匹配第18頁

【案例161】第18頁

【案例162】第18頁

7、用于操縱條件轉(zhuǎn)移的表達(dá)式及取值范圍是第2°頁

否書寫正確

【案例1.7.1]第2°頁

【案例1.7.2】第21頁

【案例173】第22頁

8、條件分支處理是否有遺漏第24頁

【案例1.8.1】第24頁

9、引用己釋放的資源第26頁

【案例191】第26頁

10、分配資源是否已正確釋放第28頁

【案例1.10.1】第28頁

【案例1.10.2】第29頁

【案例1.10.3】第30頁

【案例1.10.4】樂以火

【案例1.10.5】第33頁

【案例1.10.6】第35頁

【案例1.10.7】第38頁

11、防止資源的重復(fù)釋放第39頁

【案例L1L1】第39頁

12、公共資源的互斥性與競用性第4°頁

【案例1.12.1】第皿頁

【案例1.12.2】第4°頁

第43頁

二、接口類代碼問題

1、對函數(shù)參數(shù)進(jìn)行有效性檢查第43頁

【案例第43頁

【案例2.1.2】第43頁

【案例2.1.3】第44頁

【案例2.1.4】第46頁

【案例2.1.5】第47頁

【案例2.1.6】第48頁

2、注意多出口函數(shù)的處理第49頁

【案例221】第49頁

第51頁

三、保護(hù)類代碼問題

1、統(tǒng)一枚舉類型的使用第51頁

【案例第51頁

2、注釋量至少占代碼總量的20%第51頁

【案例3.2.1】對XXX產(chǎn)品BAM某版本部分代第51頁

碼注釋量的統(tǒng)計(jì)

第52頁

四、產(chǎn)品兼容性問題

第52頁

1、系統(tǒng)配置、命令方式

第頁

【案例52

第頁

【案例4.1.2153

2、設(shè)備對接第54頁

【案例421】第54頁

3、其他第55頁

【案例4.3.1]第55頁

第58頁

五、版本操縱問題

1、新老代碼中同一全局變量不一致第58頁

【案例第58頁

第59頁

六、可測試性代碼問題

1、調(diào)試信息/打印信息的正確性第59頁

【案例第59頁

一、邏輯類代碼問題

1、變量/指針在使用前就務(wù)必初始化

【案例LL1】

C語言中最大的特色就是指針。指針的使用具有很強(qiáng)的技巧性與靈活性,

但同時(shí)也帶來了很大的危險(xiǎn)性。在XXX的代碼中有如卜一端對指針的靈活使用:

_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_ConRg_Table函數(shù)中有可能失敗返回而不給

該指針賦值。因此,以后使用的可能是一個(gè)非法指針。

指針的使用是非常靈活的,同時(shí)也存在危險(xiǎn)性,務(wù)必小心使用。指針使用的

危險(xiǎn)性舉世共知。在新的編程思想中,指針基本上被禁止使用(JAVA中就是

這樣),至少也是被限制使用。而在我們交換機(jī)的程序中大量使用指針,同

時(shí)有增無減。

2、防止指針/數(shù)組操作越界

【案例121】

1在香港項(xiàng)目測試中,發(fā)現(xiàn)ISDN話機(jī)撥新業(yè)務(wù)號碼時(shí),若一位一位的撥

至18位,不可能有問題。但若先撥完號碼再成組發(fā)送,會(huì)導(dǎo)致MPU死機(jī)。

處理過程:

查錯(cuò)過程很簡單,按呼叫處理的過程檢查代碼,發(fā)現(xiàn)某一處的推斷有誤,

本應(yīng)為小于18的推斷,寫成了小于等于18。

結(jié)論:

代碼編寫有誤。

思考與啟示:

1、極限測試務(wù)必注意,測試前應(yīng)對某項(xiàng)設(shè)計(jì)的極限做好充分測試規(guī)劃。

2、測試極限時(shí)還要注意多種業(yè)務(wù)接入點(diǎn),本例為ISDN。關(guān)于交換機(jī)

來說,任何一種業(yè)務(wù)都要分別在模擬話機(jī)、ISDN話機(jī)、V5話機(jī)、多種形式的話

務(wù)臺上做測試。關(guān)于中繼的業(yè)務(wù),則要充分考慮各類信令:TUP、ISUP、PRA.

N01、V5等等。

【案例122】

對某交換類進(jìn)行計(jì)費(fèi)測試,字冠011對應(yīng)1號路由、1號子路由,有4個(gè)中繼群

11,12,13,14(都屬于1#模塊),前后兩個(gè)群分別構(gòu)成自環(huán)。其中11,13群向?yàn)橛芍?/p>

繼,12,14群向?yàn)槿胫欣^,對這四個(gè)群分別進(jìn)行計(jì)費(fèi)設(shè)置,對出入中繼都計(jì)費(fèi)。電

話60640001撥打01160010001兩次,使四個(gè)群都有機(jī)會(huì)被計(jì)費(fèi),取話單后瀏覽話

單發(fā)現(xiàn)對11群計(jì)費(fèi)計(jì)次表話單出中繼群號不正確,其它群的計(jì)次表中出中繼群號

正常。

處理過程:

與開發(fā)人員在測試組環(huán)境多次重發(fā)以上步驟,發(fā)現(xiàn)11群的計(jì)次表話單有的時(shí)

候正常,有的時(shí)候其出中繼群號就為一個(gè)隨機(jī)值,發(fā)生特殊的頻率比較高。為什

么其它群的話單正常,唯獨(dú)11群不正常呢?11群是四個(gè)群中最小的群,其中繼計(jì)

次表位于緩沖區(qū)的首位,打完電話后查詢內(nèi)存發(fā)現(xiàn)出中繼群號在內(nèi)存中是正確

的,取完話單后再查就不正確了。

結(jié)論:

話單池的一個(gè)備份指針PooLhead」與中繼計(jì)次表的頭指針重合,影響到第一

個(gè)中繼計(jì)次表的計(jì)費(fèi)。

思考與啟示:

隨機(jī)值的背后往往隱臧著指針問題,兩塊內(nèi)存緩沖區(qū)的交界處比較容易出現(xiàn)

問題,在編程時(shí)是應(yīng)該注意的地方。

【案例123】

【正文】

在接入網(wǎng)產(chǎn)品A測試中,在內(nèi)存數(shù)據(jù)庫正常的情況下的各類數(shù)據(jù)庫方

面的操作都是正常的。為了進(jìn)行數(shù)據(jù)庫特殊測試,因此將數(shù)據(jù)庫內(nèi)容人為地破壞

了。發(fā)現(xiàn)在對數(shù)據(jù)庫進(jìn)行比較操作時(shí),出現(xiàn)程序跑死了現(xiàn)象。

通過跟蹤調(diào)試發(fā)現(xiàn)問題出現(xiàn)在如下一段代碼中:

1for(i=0;i<pSysHcad->dbCcount;i十十)

2{

3pDBFat=(_NM_DBFAT_STRUC*)(NVDB_BASE+

DBFAT_OFFSET+i*DBFAT_LEN);

4if(fat_check(pDBFat)!=0)

5(

6pSysHead->system_flag=0;

7hcad_sum();

8continue;

9}

10if(strlen(dbf->dbf_name)!=0&&stmcmp(dbf->dbf_name,

pDBFat->dbf_name,strlen(dbf->dbf_name))==0)

H(

12dbLptrl=(_UC*)pDBFat->dbLhead;

13filesize=pDBFat->dbf_fsize;

14break;

15)

16)

在測試時(shí)發(fā)現(xiàn)程序死在循環(huán)之中,得到的錯(cuò)誤記錄是“BusError”(總線

出錯(cuò)),由此能夠說明出現(xiàn)了內(nèi)存操作特殊。

通過跟蹤變量值發(fā)現(xiàn)循環(huán)變量i的閥值pSysHead->dbf_count的數(shù)值為

OxFFFFFFFF,該值是從被破壞的內(nèi)存數(shù)據(jù)庫中獲取的,正常情況下該值小于127。

ihjpDBFat是數(shù)據(jù)庫的起始地址,假如pSysHead->dbf_count值特殊過大,將導(dǎo)致

pDBFat值超過最大內(nèi)存地址值,隨后進(jìn)行的內(nèi)存操作將導(dǎo)致內(nèi)存操作越界錯(cuò)誤,

因而在測試過程中數(shù)據(jù)庫破壞后就出現(xiàn)了主機(jī)死機(jī)的現(xiàn)象。

上面的問題解決起來很容易,只需在第一行代碼中增加一個(gè)推斷條件即可,

如下:

for(i=0;i<pSysHead->dbf_coun&&i<MAX_I)B_NUM;i++)

//MAX_DB_NUM=127

這樣就保證了循環(huán)變量i的值在正常范圍內(nèi),從而避免了對指針pDBFai進(jìn)行

內(nèi)存越界的操作。

從上面的測試過程中,我們能夠看到:如此嚴(yán)重的問題,僅僅是一個(gè)簡單的

錯(cuò)誤引起的。實(shí)際上,系統(tǒng)的不穩(wěn)固往往是由這些看似很簡單的小錯(cuò)誤導(dǎo)致的。

這個(gè)問題給我們教訓(xùn)的是:在直接對內(nèi)存地址進(jìn)行操作時(shí),一定要保證其值的合

法性,否則容易引起內(nèi)存操作越界,給系統(tǒng)的穩(wěn)固性帶來潛在的威脅。

【案例124】

近日在CDB并行測試中發(fā)現(xiàn)一個(gè)問題:我們需要的小區(qū)負(fù)荷話統(tǒng)結(jié)果總是為

零,開始還以為小區(qū)負(fù)荷太小,因此加大短消息下發(fā)數(shù)量,但還為零,因此在程

序中加入測試代碼,把收到的數(shù)據(jù)在BAM上打印出來,

結(jié)果打印出來的數(shù)據(jù)正常,不可能為零,認(rèn)真查看有關(guā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_msg.usCellNum;

OOO

)

因此結(jié)構(gòu)指針傳入函數(shù)后,如要進(jìn)行指針移動(dòng)操作,最好先將其轉(zhuǎn)化為

_uc型再說。總之指針操作要小心為上。

3、避免指針的非法引用

【案例131】

【正文】

在一次測試中,并沒有記得做了什么操作,發(fā)現(xiàn)HONET系統(tǒng)的主機(jī)復(fù)位

了,之后,系統(tǒng)又工作正常了。由于沒有打開后臺的跟蹤窗口,當(dāng)時(shí)查了半天沒

有眉目。過了半天,現(xiàn)象又出現(xiàn)了,而且這次是主機(jī)在反復(fù)復(fù)位,系統(tǒng)根本無法

正常工作了。

我憑經(jīng)歷,推斷應(yīng)該是與當(dāng)時(shí)正在測試的DSL板的端口配置有關(guān)。因此將

板上所有端口配置為普通2B+D端口,重新加載在主機(jī)數(shù)據(jù),現(xiàn)象消失。因此初

步定位為主機(jī)在DSL端口處理過程中有重大錯(cuò)誤。

我在新的數(shù)據(jù)上努力恢復(fù)原出問題的現(xiàn)象,卻一直沒有重現(xiàn),因此恢復(fù)原

數(shù)據(jù),加載后立即重現(xiàn)。并注意到,當(dāng)DSL端口激活時(shí),主機(jī)復(fù)位。認(rèn)真比較兩

種數(shù)據(jù)的差別,發(fā)現(xiàn)出現(xiàn)主機(jī)復(fù)位問題的數(shù)據(jù)中DSL板配置了MNT/MLT端口,

但是沒有做DSL端口之間的半永久數(shù)據(jù)。

因此在程序中不斷加打印語句,通過后臺的DBWIN調(diào)試程序跟蹤,最后

終于定位為:每當(dāng)執(zhí)行到portdsl.c的DeviceDslMsgProc。函數(shù)中處理U口透傳的

if(SPC_STATEOK=pSpcCB->bySpcState)

語句時(shí),主機(jī)復(fù)位。但是該語句大概并無不妥。

再分析整個(gè)函數(shù),pSpcCB在函數(shù)前部分已經(jīng)被賦值,

pSpcCB=SpcCB+(PortTablc+indcx)->spcNo;

但由于得到index后,沒有任何推斷,導(dǎo)致若MNT/MLT端口沒有做半永久,

端口激活后,執(zhí)行此部分函數(shù),(PortTable+index)->spcNo有可能為NULL_W0RD,

因此,運(yùn)算后,pSpcCB可能為非法值。如今主機(jī)在取進(jìn)行推斷,就不知會(huì)導(dǎo)致

什么后果了。

事實(shí)上,改起來很簡單,只要在這兩句前增加一個(gè)推斷就行了。因此,修

改代碼為:

if((PortTable+index)->spcNo!=NULLJVORD)

(

pSpcCB=SpcCB+(PortTable+index)->spcNo;

if(SPCSTATEOK==pSpcCB->bySpcState)

{ooo}

)

修改后,問題不再重現(xiàn)。

通過分析能夠發(fā)現(xiàn),編譯環(huán)境是有很大的容許空間的,若主機(jī)沒有做充分

的保護(hù),很可能會(huì)有極嚴(yán)重的隨即故障出現(xiàn)。因此編程時(shí)一定要考慮各類可能情

況;而測試中遇到此類死機(jī)問題,則要耐心的定位到具體是執(zhí)行哪句代碼時(shí)出現(xiàn)

的,再進(jìn)行分析。由于問題很隱蔽,直接分析海一樣的代碼是很難發(fā)現(xiàn)的。

4、變量類型定義錯(cuò)誤

【案例141】

【正文】

在FRI板上建幾條FRPVC,其DLCI類型分別為:10Bit/2bytcs、

10bit/3bytes>16bit/3bytes、17bit/4bytes>23bit/4byteso相應(yīng)的DLCI值為:16、

234、991>126975>1234567,然后儲存,重起MUX,觀察PVC的恢復(fù)情況,結(jié)

果DLCI值為16、234與991的PVC正確恢復(fù),而DLCI=126975的PVC恢復(fù)的數(shù)據(jù)

錯(cuò)誤為61439,而DLCI=1234567的PVC完全沒有恢復(fù)。

關(guān)于17/4類型,DLCI=126975的PVC在恢復(fù)時(shí)變成61439,根據(jù)這條線

索,查找原因,發(fā)現(xiàn)126975-61439=65535,轉(zhuǎn)化二進(jìn)制就是10000000000000000,

也就是說在數(shù)據(jù)恢復(fù)或者儲存時(shí)把原數(shù)據(jù)的第一個(gè)1給忽略了。如今第一個(gè)辦法

是:在程序處理中,把無符號長整型變量當(dāng)作短整型變量處理了,為了證實(shí)這個(gè)

推斷,針對17bit/4bytes類型又重新設(shè)計(jì)測試用例:(1)先建PVC,DLCI=65535,

然后儲存,重起MUX,觀察PVC的恢復(fù)情況,發(fā)現(xiàn)PVC能夠正確恢復(fù);

(2)再建PVC,DLCI=65536,然后儲存,重起MUX,觀察PVC的恢復(fù)情況,

如今PVC不能正確恢復(fù)。

至此基本能夠斷定原因就是出在這里。帶著這個(gè)目的查看原代碼,發(fā)現(xiàn)在下列代

碼中有問題:

int_GetFrDlci(DWORD*dwDlci,char*str,DWORDdwDlciType,DWORD

dwPortType,DWORDdwSlotID,DWORDdwPortID)

{DWORDtempDIci;

charszArg[8O];

1charszLine[8OJ;

IDLowPVCEP;

DWORDdwDlciVal[5][2]=

{{16,1007),{16,1007},{1024,64511),

{2048,129023},{131072,4194303}};

)

typcdefstructtagFrPppIntIWF

(

???

WORDwHdlcPort:

WORDwHdlcDlci;

WORDwPeerHdlcDlci;

WORDwPccrOldAtmPort;

???

)SFrPppIntIWFData:

DWORDSaveFrNetIntIWFData(DWORD*pdwWritePoint)

(

BYTEbSlotID,bPeerSlotID;

DWORDdwCCID,dwPeerCCID;

WORDwHdlcPort.wAtmPort,wlci,wPeerlci,wPcerHdlcPort;

WORDwCount;

)

DWORDSaveFrNetExtIWFData(DWORD*pdwWritePoint)

BYTEbSIotID;

DWORDdwCCID,dwPeerCCID;

WORDwHdlcPorl.wAtmPort,wlci;

WORDwCounl;

???

unSevData.FrNetExtIWF[wCount].bSlotID=bSlotID;

unSevData.FrNetExtIWF[wCount].wHdlcPort=wHdlcPort;

iinSevDara.FrNerF.xtIWF[wCount].wHdlcDlci=

gFrPVCEPfbSlotID][gFrPVCC[bSlotID][dwCCIDl.dwLoPVCEPl.dwDLCI;

unSevData.FrNetExtIWF[wCountl.wOldAtmPort=wAtmPort;

unSevData.FrNetExlIWF[wCount].wAlmDlci=

gFrPVCEP[bSlotID][gFrPVCC[bSlotID][dwCCID].dwHiPVCEP].dwDLCI;

unScvData.FrNctExtIWF[wCount].dwMapModc=

gFrPVCC[bSlotID][dwCCID].dwMapMode;

???

)

DWORDRestoreFrNetExtIWFData(WORDwSlotlD,BYTE*pReadPoint)

{

WORDwCount,wTotalNetIWF;

BYTEbSlolID,bHdlcDluiTypu,bAlmDlciType;

WORDwOldAtmPort,vvAtmDlci,wHdlcPort,wHdlcDlci;

DWORDdwMapMode,dwCIR,dwBe;

DWORDdwCCID,dwResult,dwAtmPort;

wTotalNetIWF=g_MuxData.SevDataSize.wFrNetExtIWFNum;

)

DWORDRestoreFrHdlcIntlWFData(WORDwSlotID,BYTE*pReadPoint)

WORDwCount,wTotalHdlcIWF;

DWORDdwCCID,dwPeerCCID,dwAtmPort,dwPeerAtmPort;

DWORDdwResult;

BYTEbSlotID,bPeerSlotID;

WORDwHdlcPorl.wOldAtmPort,wCIR;

WORDwPeerHdlcPort,wPeerOldAtmPorl;

???

1

其中涉及DLCI值的變量都為WORD(即無符號短整型)類型,在程序

的處理時(shí),出現(xiàn)WORD與DWORD(無符號長整型)類型在一句中同時(shí)存在的情

況,至此能夠推斷問題出在這里。由于DLCI值在不一致類型時(shí)的取值范圍不一

致,前三種類型的取值范圍為16?991,第四種取宜范圍為2048?126975,第五種

取值范圍為131072?4194303,因此當(dāng)使用前三種DLCI類型時(shí),使用WORD類型

最大值為65535,已經(jīng)完全夠用了;而關(guān)于第四種類型時(shí);其取值在超過65535

時(shí),獲取DLCI值的函數(shù)_GetFrDlci()使用DWORD類型,而負(fù)責(zé)儲存與恢復(fù)的

兩個(gè)函數(shù)SaveFrNetExtIWFData()與RestoreFrNetExtIWFData(),都把DLCI

的值當(dāng)作WORD類型進(jìn)行處理,因此導(dǎo)致DLCI取值越界,因此程序把原本為長

整型的DLCI強(qiáng)制轉(zhuǎn)換成整型,從而導(dǎo)致DLCI值在恢復(fù)時(shí),比原數(shù)據(jù)小65536。

而在程序運(yùn)行過程中,這些數(shù)據(jù)儲存在DRAM中,程序運(yùn)行直接從DRAM中獲取

數(shù)據(jù)■,程序不可能出錯(cuò);當(dāng)FRI板復(fù)位或者插拔后,需要從FLASH中讀取數(shù)據(jù),

如今恢復(fù)函數(shù)的錯(cuò)誤就表現(xiàn)出來。

另一個(gè)問題是為什么23/4類型的DLCI數(shù)據(jù)不能恢復(fù)?這是由丁關(guān)丁23/4

類型的PVC,其DLCI的取值范圍為:131()72~4194303,而程序強(qiáng)制轉(zhuǎn)換并恢復(fù)

的數(shù)據(jù)最大只能是65535,因此這條PVC不能恢復(fù)。

至此,DLCI數(shù)據(jù)恢復(fù)出錯(cuò)的原因完全找到,解決的方法是將DLCI1勺類

型改為DWORD類型。從這個(gè)案例能夠看出,在程序開發(fā)中一個(gè)很低級的錯(cuò)誤,

將在實(shí)際工作中造成很嚴(yán)重的后果。

【案例1.4.21

【正文】

在FRI板上建幾條FRPVC,其DLCI類型分別為:I()Bit/2bytes、

10bit/3bytes>16bit/3bytes>17bit/4bytes>23bit/4byteso相應(yīng)的DLCI值為:16、

234、991、126975、1234567,然后儲存,重起MUX,觀察PVC的恢復(fù)情況,結(jié)

果DLCI值為16、234與991的PVC正確恢復(fù),而DLCI=126975的PVC恢復(fù)的數(shù)據(jù)

錯(cuò)誤為61439,而DLC】=1234567的PVC完全沒有恢復(fù)。

關(guān)于17/4類型,DLCI=126975的PVC在恢復(fù)時(shí)變成61439,根據(jù)這條線

索,查找原因,發(fā)現(xiàn)126975-61439=65535,轉(zhuǎn)化二進(jìn)制就是10000000000000000,

也就是說在數(shù)據(jù)恢復(fù)或者儲存時(shí)把原數(shù)據(jù)的第一個(gè)1給忽略了。如今第一個(gè)辦法

是:在程序處理中,把無符號長整型變量當(dāng)作短整型變量處理了,為了證實(shí)這個(gè)

推斷,針對I7hit/4hy&類型又重新設(shè)計(jì)測試用例:(I)先建PVC,DICI=6SS3s.

然后儲存,重起MUX,觀察PVC的恢復(fù)情況,發(fā)現(xiàn)PVC能夠正確恢復(fù);

(2)再建PVC,DLCI=65536,然后儲存,重起MUX,觀察PVC的恢復(fù)情況,

如今PVC不能正確恢復(fù)。

至此基本能夠斷定原因就是出在這里。帶著這個(gè)目的查看原代碼,發(fā)現(xiàn)在下列代

碼中有問題:

int_GetFrDlci(DWORD*dwDlci,char*str,DWORDdwDlciType,DWORD

dwPortType,DWORDdwSlotID,DWORDdwPortID)

{DWORDtempDlci;

charszArg[80];

charszLine[80];

IDLowPVCEP;

DWORDUwDluiVal[5JL2J-

{{16,1007},(16,1007),{1024,64511},

{2048,129023),(131072,4194303));

typedefstructtagFrPpplntlWF

WORDwHdlcPort:

WORDwHdlcDlci;

WORDwPeerHdlcDlci;

WORDwPeerOldAtmPort;

}SFrPppIntIWFData:

DWORDSaveFrNetIntIWFData(DWORD*pdwWritePoint)

(

BYTEbSlotID,bPeerSlotID;

DWORDdwCCID,dwPeerCCID;

WORDwHdlcPort.wAtmPort,wlci,wPeerTci,wPeerHdlcPort;

WORDwCount;

)

DWORDSaveFrNetExtIWFData(DWORD*pdwWritePoint)

(

BYTEbSlotID;

DWORDdwCCID,dwPeerCCID;

WORDwHdlcPort.wAtmPort,wlci;

WORDwCount;

unSevData.FrNelExtIWF[wCount].bSlotID=bSlotID;

ufiScvDala.FrNclExlIWFlwCounlJ.wHdlcPuil-wHdluPorl;

unSevData.FrNetExtIWF[wCount].wHdlcDlci=

gFrPVCEP[bSlotID][gFrPVCC[bSlotID][dwCCID].dwLoPVCEP].dwDLCI;

unSevData.FrNetExtIWF[wCount].wOldAtmPort=wAtmPort;

unSevData.FrNetExlIWF[wCount].wAlmDlci=

gFrPVCEP[bSloiID][gFrPVCC[bSlotID][dwCCID].dwHiPVCEPJ.dwDLCI;

unScvData.brNetExtlWF[wCountJ.dwMapModc=

gFrPVCC[bSlotID][dwCCID].dwMapMode;

)

DWORDRestoreFrNetExtIWFData(WORDwSlotID,BYTE*pReadPoint)

{

WORDwCount,wTotalNetIWF;

BYTEbSlolID,bHdlcDlciType,bAtmDlciType;

WORDwOldAtmPort,wAlmDlci,wHdlcPort,wHdlcDlci;

DWORDdwMapModc,dwCIR,dwBc;

DWORDdwCCID,dwResult,dwAtmPort;

wTotalNetIWF=g_MuxData.SevDataSize.wFrNetExtIWFNum;

)

DWORDRestoreFrHdlcIntlWFData(WORDwSlotID,BYTE*pReadPoint)

{

WORDwCount,wTotalHdlcIWF;

DWORDdwCCID,dwPccrCCID,dwAtmPort,dwPccrAtmPort;

DWORDdwResult;

BYTEbSlotID,bPeerSlotID;

WORDwHdlcPort.wOldAtmPort,wCIR;

WORDwPeerHdlcPort,wPeerOldAtmPort;

)

其中涉及DLCI值的變量都為WORD(即無符號短整型)類型,在程序

的處理時(shí),出現(xiàn)WORD與DWORD(無符號長整型)類型在一句中同時(shí)存在的情

況,至此能夠推斷問題出在這里。由于DLCI值在不一致類型時(shí)的取值范圍不一

致,前三種類型的取值范圍為16?991,第四種取值范圍為2048?126975,第五種

取值范圍為131072?4194303,因此當(dāng)使用前三種DLCI類型時(shí),使用WORD類型

最大值為65535,已經(jīng)完全夠用了;而關(guān)于第四種類型時(shí),其取值在超過65535

時(shí),獲取DLCI值的函數(shù)_GetFrDlci()使用DWORD類型,而負(fù)責(zé)儲存與恢復(fù)的

兩個(gè)函數(shù)SaveFrNetExtlWFData()與RestoreFrNetExtIWFData(),都把DLC1

的值當(dāng)作WORD類型進(jìn)行處理,因此導(dǎo)致DLCI取值越界,因此程序把原本為長

整型的DLCI強(qiáng)制轉(zhuǎn)換成整型,從而導(dǎo)致DLCI值在恢復(fù)時(shí),比原數(shù)據(jù)小65536。

而在程序運(yùn)行過程中,這些數(shù)據(jù)儲存在DRAM中,程序運(yùn)行直接從DRAM中獲取

數(shù)據(jù),程序不可能出錯(cuò);當(dāng)FRI板復(fù)位或者插拔后,需要從FLASH中讀取數(shù)據(jù),

如今恢復(fù)函數(shù)的錯(cuò)誤就表現(xiàn)出來。

另一個(gè)問題是為什么23/4類型的DLCI數(shù)據(jù)不能恢復(fù)?這是由于關(guān)于23/4

類型的PVC,其DLCI的取值范圍為:131072~4194303,而程序強(qiáng)制轉(zhuǎn)換并恢復(fù)

的數(shù)據(jù)最大只能是65535,因此這條PVC不能恢復(fù)。

至此,DLCI數(shù)據(jù)恢復(fù)出錯(cuò)的原因完全找到,解決的方法是將DLCI的類

型改為DWORD類型.從這個(gè)案例能夠看出,在程序開發(fā)中一個(gè)很低級的錯(cuò)誤,

將在實(shí)際工作中造成很嚴(yán)重的后果。

5、正確使用邏輯與&&、屏蔽&操作符

【案例151】

【案例描述】:由于(語言中位與比求模效率高,因而系統(tǒng)設(shè)計(jì)時(shí),關(guān)于模128

的地方都改為與127,系統(tǒng)定義的宏為#€1?仔優(yōu)MOD128127與#加6根W_MOD

127(定義的宏的名字易引起誤解),但實(shí)際程序中還是采取求模,從而引起發(fā)送

窗口欲重發(fā)的與實(shí)際重發(fā)的不一致,最終導(dǎo)致鏈路復(fù)位此類嚴(yán)重問題,曾在定位

此問題時(shí)花了很多時(shí)間。

【處理過程】:處理過程如下:

#defineMOD128127〃隊(duì)列長128,當(dāng)隊(duì)頭到128時(shí),上其返回。

#defineW_MOD127〃發(fā)送窗口隊(duì)列,意義同上。

在函數(shù)L2_TO_L1()中,有如下語句:

linkstate_ptr->SendWin.head=(head+1)%W_MOD;

這里當(dāng)head=126時(shí),ScndWin.hcad=0?這將造成發(fā)送窗口指針與隊(duì)列窗口指針

錯(cuò)位,造成鏈路復(fù)位;

另外,在重發(fā)函數(shù)voidINVOKE_RETRANSMISSION(_USlogicjink,_USn_r)中,

有如下語句:

retran_num=(LinkState[logic_link].Vs+MOD128-(_UC)n_r)%

MOD128;

w_head=(LinkState[logic_link].SendWin.head+W_MOD-

retran_num)%W_MOD;

第一個(gè)語句求欲重發(fā)的消息包個(gè)數(shù),第二個(gè)語句求重發(fā)的起始位置,當(dāng)Vs小于

n」?時(shí),將造成實(shí)際重發(fā)數(shù)小于欲重發(fā)數(shù),同時(shí)造成實(shí)際起始重發(fā)位置與欲重發(fā)

起始位置錯(cuò)開,從而引起鏈路復(fù)位。上面三個(gè)語句應(yīng)該做如下改動(dòng):

linkstate_ptr->SendWin.head=(head+1)&W_MOD;

rctran_num=(LinkState[logic」ink].Vs+MOD128+1-(_UC)n_r)&

MOD128;

wjiead=(LinkState[logic_link].SendWin.head+W_MOD+1-

retran_num)&W_MOD;

【結(jié)論】:由于鏈路通信對系統(tǒng)效率要求很高,算法使用效率最高的,但位與

(&)與求模(%)這小小的區(qū)別,造成的竟是鏈路復(fù)位這種嚴(yán)重的錯(cuò)誤。

【思考與啟示】:對這類問題,大家在閱讀代碼或者代碼審查時(shí)一定要注意,認(rèn)

真一點(diǎn)往往能發(fā)現(xiàn)問題,但在測試中來定位這種問題,花費(fèi)的時(shí)間往往更長。

6、注意數(shù)據(jù)類型的匹配

【案例161】

【案例描述】

下面通過測試中的一個(gè)例子來說明這個(gè)問題:命令DSPN7c是用來顯示NO7

電路狀態(tài)的,其參數(shù)設(shè)備類型DID支持TUP與ISUP,參數(shù)信道號BSN支持多值輸

入(最多支持32路查詢),正常情況下該命令沒有問題。但試了非正常情況下,

問題就出來了。

1、首先試BSN參數(shù)越界情況,即參數(shù)BSN超過32路查詢,選了幾個(gè)數(shù)據(jù)段,

問題就出來了。關(guān)于0&&300與0&&256,該命令返回結(jié)果不一致,對前者認(rèn)為

參數(shù)越界,對后者返回執(zhí)行成功。

2、關(guān)于參數(shù)DID,選定一種設(shè)備類型(TUP或者ISUP),讓參數(shù)BSN所包含

的32路電路跨越TUP與ISUP,兩次結(jié)果是不一致的。

【處理過程】

反饋到開發(fā)人員那里,第一個(gè)問題是BAM的問題,第二個(gè)問題是SM的問題。

【結(jié)論】

1、為數(shù)據(jù)超出范圍溢出造成,int值賦值給BYTE,造成數(shù)據(jù)丟失。

2、問題的產(chǎn)生是曰于查詢的第一個(gè)信道是TUP電路,但是卻按ISUP電路查

詢。ISUP的保護(hù)處理函數(shù)推斷第一個(gè)信道不是ISUP信道,認(rèn)為整個(gè)的PCM不是

ISUP類型的PCM,返回全部的電路狀態(tài)為未安裝。消息處理不合理。TUP也會(huì)

產(chǎn)生如此錯(cuò)誤。

【思考與啟示】

我們的MML命令并不是無懈可擊的,許多表面上的小問題,往往隱臧著代

碼的缺陷與錯(cuò)誤。

【案例162】

【正文】

當(dāng)我們使用PC-LINT檢查代碼時(shí),會(huì)發(fā)現(xiàn)大量的數(shù)據(jù)類型不匹配的告警,

大部分情況下,這種代碼上存在的問題并不可能引起程序功能實(shí)現(xiàn)上的錯(cuò)誤,但

有些情況下,也許會(huì)產(chǎn)生嚴(yán)重的問題:

一、不一致數(shù)據(jù)類型變量之間賦值引起的問題,實(shí)際上,該類問題也能

夠分為幾種情況:

1、直接賦值,比如,把一個(gè)WORD型變量賦給一個(gè)INT型變量,假如

WORD型變量大于32767,INT型變量得到的就是一個(gè)負(fù)值了。

【例一】一次測試過程中發(fā)現(xiàn),SDH送的告警在BAM調(diào)試窗口打印出紅色

提示:File(XXX),Line(XXX):Invalidalarmid,from:7,Alarmld:65463

通過檢查數(shù)據(jù)發(fā)現(xiàn),并沒有ID為65463的告警,分析上報(bào)的數(shù)據(jù)幀,發(fā)現(xiàn)

上報(bào)的告警ID為B7,原先代碼中有一處強(qiáng)制類型轉(zhuǎn)換:

sdhAlmStru.Alarmld=(WORD)RecvBuffer[iTmpLen+5];

char型強(qiáng)制轉(zhuǎn)換成WORD型。B7就變成了FFB7,十進(jìn)制就是65463。由

于char是有符號型,B7的第8位為1,因此轉(zhuǎn)換后為FFB7,而不是代碼作者希望

的00B7,假如第8位是0,或者該變量是BYTE型,轉(zhuǎn)換就不可能有問題了。

2、函數(shù)形參與實(shí)參不一致,實(shí)際上與第一種情況本質(zhì)上是一樣的,只是

表現(xiàn)的形式不太一樣,這種情況也是代碼中經(jīng)常出現(xiàn)的問題,下面例子是測試中

曾經(jīng)發(fā)現(xiàn)的一個(gè)小問題:

【例二】在fileOl中的INTDebugMsgProc(charbyMsgO,charbyMsgl)函

數(shù),兩個(gè)形參都是char型,而實(shí)際傳入的參數(shù)都是BYTE型,結(jié)果函數(shù)中的如下語

句:

PrintfE(PlD_RED,z/%dtickstimeout!,z,byMsgl);

在byMsgl大于127時(shí),輸出錯(cuò)誤的結(jié)果。

二、不一致數(shù)據(jù)類型之間的比較操作

在循環(huán)終止條件的推斷中,不一致類型變量的比較操作是容易造成死循環(huán)

錯(cuò)誤的地方,同時(shí)也是開發(fā)人員容易忽視的地方,值得測試人員多加留意。下面

兩個(gè)例子是該類錯(cuò)誤的兩種典型情況:

【例三】file02文件中某函數(shù)中如下代碼,可能造成死循環(huán):

inti;

WORD*pCheck=(WORD*)p;

WORDwCheckSum=*pCheck;

pCheck++;

for(i=l;i<dwLcn/2;i++)

(

wCheckSumA=(*pCheck);

pCheck++;

}

//binlenhadalreadywordalignmenl

return(wCheckSum);

該段代碼是在DOS環(huán)境下用BC編譯的,由于循環(huán)變量i是int型(2個(gè)字節(jié)),

而dwLen是DWORD型(4個(gè)字節(jié)),假如dwLen大于65536,那么該函數(shù)就是死

循環(huán)了。

上面的例子是不一致類型變量之間直接比較操作,還有一種情況是函數(shù)

的返回值與另一不一致類型的變量比較,見下面例子:

【例四】fileO3.c文件中某函數(shù)中如下代碼,

while(ftell(fp)<Part[3J)

I

ftell返回10ng型,而Part是DWORD型,有符號變量與無符號變量的比較,可能

造成死循環(huán)。

類似的例子還有很多,類型不匹配的問題還有許多種情況,都是代碼中

的隱患,有的時(shí)候會(huì)造成嚴(yán)重的后果,需要引起足夠的重視。關(guān)于該類問題,我

們能夠利用PC-LINT工具對代碼進(jìn)行細(xì)致的檢查。

7、用于操縱條件轉(zhuǎn)移的表達(dá)式及取值范圍是否書寫正確

【案例

【案例描述】:

在測試主機(jī)MPU板倒換功能時(shí),假如MPU備份充分,倒換前后對處于激活狀

態(tài)的電路應(yīng)無影響,即不影響通話。但近期測試發(fā)現(xiàn),假如兩局通過DT板進(jìn)行

一號對接,MPU備份倒換卻發(fā)生斷話。具表達(dá)象為:假如DT板的第1個(gè)PCM系

統(tǒng)電路為故障,則MPU倒換時(shí)復(fù)位該DT板,假如DT板的第2個(gè)PCM系統(tǒng)電路為

故障,則MPU倒換時(shí)復(fù)位下一塊DT。

【處理過程】:

據(jù)查,MPU倒換時(shí)會(huì)自動(dòng)復(fù)位處于“故障”態(tài)的電路,但由于計(jì)算錯(cuò)誤(多

加了32),錯(cuò)復(fù)位了下一個(gè)PCM系統(tǒng)32路電路。

【結(jié)論】:

如此嚴(yán)重問題為什么到今天才發(fā)現(xiàn)?由于我們在實(shí)驗(yàn)室中通常使用同一單

板的2個(gè)PCM系統(tǒng)自環(huán)進(jìn)行測試,則不可能在某單板上有故障與空閑電路共存,

自環(huán)屏蔽了錯(cuò)誤。

【思考與啟示】:

自環(huán)是在測試環(huán)境下常用的一種提高效率的手段,但一旦條件同意,我們的

測試工作應(yīng)盡量模擬網(wǎng)上的實(shí)際環(huán)境進(jìn)行。

【案例172】

平常對計(jì)費(fèi)功能進(jìn)行測試的時(shí)候,瀏覽全面話單都是比較注意話單本身為正

確性,并沒有注意該命令對系統(tǒng)的影響。因此當(dāng)瀏覽少量話單的時(shí)候,并沒有發(fā)

現(xiàn)該命令的特殊。但是當(dāng)時(shí)間的跨度較大時(shí),全面話單數(shù)量較多,問題就出現(xiàn)了。

執(zhí)行如下命令:

LSTAMA:TP=NRM,SD=1999&7&1,SA=YES;

當(dāng)瀏覽了大約10萬張全面話單后,終端與BAM的連接關(guān)閉。重建連接后,發(fā)

現(xiàn)話單臺的命令不能執(zhí)行。觀察BAM的性能,發(fā)現(xiàn)話單臺仍占有CPU50%以上的

利用率,說明原先的任務(wù)仍在執(zhí)行。需要關(guān)一下話單臺才能恢復(fù)正常。

重復(fù)上述步驟,當(dāng)終端與BAM的連接尚未關(guān)閉時(shí)主動(dòng)斷開此次連接,結(jié)果同

上。

反饋到開發(fā)人員那里,發(fā)現(xiàn)該現(xiàn)象與設(shè)計(jì)的初衷是相違背的。本來話單臺操

縱最多輸出200張?jiān)拞危@是為了防止過多話單的輸出顯示會(huì)增加BAM的開銷,

從而降低RAM的性能.查看一下源代碼,問題就發(fā)現(xiàn)了八

話單臺操縱最多輸出200張?jiān)拞?/p>

程序如下

while(timeCur<=limeEnd)

(

timeCur+=tsOneDay;//加一天

while(fileBill.Read(&rpt,sizeof(CBillReport))=

sizeof(CBillReport))

〃只輸出滿足條件的前200張?jiān)拞?/p>

if(++wBillCouul==200)

(

break;

)

}〃一個(gè)文件查詢結(jié)束

}〃所有文件查詢結(jié)束

在話單輸出200張之后,程序只退出一層循環(huán),仍然會(huì)從下一天話單繼續(xù)輸

出,導(dǎo)致向MML發(fā)幀過多,造成MML與話單臺都被堵死。

修改ProcessQueryBiH。函數(shù)

〃只輸出滿足條件的前2)0張?jiān)拞?/p>

if(++wBilICount==200)

(

timeCur=timeEnd+tsOneDay;//退出第二層循環(huán),

while(timeCur<=timeEnd)

break;

}

作上述修改后問題就不再出現(xiàn)了。

一些MML命令從完成的功能來講可能是沒什么問題的,但其執(zhí)行對系統(tǒng)性

能的影響我們在測試時(shí)時(shí)往往給忽視了。在我們目前的BAM方案中,存在看多

個(gè)終端協(xié)同工作,假如某個(gè)終端發(fā)出的命令在BAM中長時(shí)間獨(dú)占著大部分系統(tǒng)

資源,造成的后果是嚴(yán)重的。這是在設(shè)計(jì)時(shí)要避免的,在測試中要注意的問題。

【案例1.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;

作者的本意是假如是32路用戶板(藍(lán)色字體推斷),就看端口號是否是第15

與16路,假如是,就是反極性端口,返回TRUE,否則就不是,應(yīng)該返回FALSE。

但代碼表達(dá)的意思是:假如是32路用戶板同時(shí)端口號是15或者16就返回真值,否

則還要執(zhí)行下邊語句。

當(dāng)端口在32路用戶板上,但端口號不是15或者16時(shí),不一致的32路端口的起

始地址g_wASL32StartPSN,會(huì)導(dǎo)致不一致的非15、16端口被誤認(rèn)為是反極性端

口。舉個(gè)例子,當(dāng)g_wASL32StartPSN的值為30()()時(shí),端口號為300()(第一塊板

上的第0個(gè)端口)就被認(rèn)為是反極性端口,這與作者的意圖完全相悖。

能夠?qū)⒋a修改如下:

if((bsn>=g_wASL32StartPSN)

(

if(((bsn-g_wASL32SlartPSN)%32)==15||((bsn-

g_wASL32StartPSN)%32==16)))

returnTRUE;

)

else

if((bsn%16)==7||(bsn%16)==8)

returnTRUE;

returnFALSE;

通過這個(gè)例子,我覺得在代碼審查時(shí)應(yīng)該留意在推斷條件較多的情況下,每

個(gè)輸入是否都能正確輸出,在單元測試、集成測試、系統(tǒng)測試時(shí)要針對邊界值設(shè)

計(jì)相應(yīng)的測試用例。

推斷條件較多時(shí)開發(fā)人員也應(yīng)該適當(dāng)分開寫,既使代碼更易讀,又不容易出

錯(cuò)。

8、條件分支處理是否有遺漏

【案例1.8.11

【現(xiàn)象】

在接入網(wǎng)主機(jī)程序的代碼審查中,發(fā)現(xiàn)dbquery.c的DBQ」nit_ANType

函數(shù)中如下代碼段缺少應(yīng)有的條件分支,在數(shù)據(jù)特殊的情況下,會(huì)產(chǎn)生較嚴(yán)重的

問題。

【處理過程】

該錯(cuò)誤比較隱蔽,現(xiàn)在說明如下:

Max2BlQStatTime最大統(tǒng)計(jì)時(shí)間

Max2BIQStatPortNum最大統(tǒng)計(jì)端口數(shù)

MAX_2B1Q_STAT_PSN最大統(tǒng)計(jì)內(nèi)存分配數(shù)量

其中:Max2BlQStatTime(最大統(tǒng)計(jì)時(shí)間)與Max2BIQStatPortNum

(最大統(tǒng)計(jì)端口數(shù))的乘積不能大于MAX_2B1Q_STAT_PSN

程序如下:

〃查詢數(shù)據(jù)庫,獲得Max2BlQStalTime的值

directQueryCond.tupleNo=10;

error_codc=DB_Qucry(R1D_OTHERS_PARA_INFO,1,

(LPDBCondition)&directQucrjzCond,

(BYTEFAR*)&tempstruct());

〃查詢數(shù)據(jù)庫成功

if(error_code==DB_SUCCESS)

{

//tempstructO.data是數(shù)據(jù)庫中為Max2BlQStatTime配置的值

if(tempstructO.data>MAX_2B1Q_STAT_PSN)

Max2BlQStatTime=MAX_2B1Q_STAT_PSN;

elseif(tempstructO.data!-0)

Max2B1QStatTime=tempstructO.data;

)

〃查詢數(shù)據(jù)庫,獲得Max2B1QSlalPortNum的值

directQueryCond.tupleNo=11;

error_code=DB_Query(RID_OTHERS_PARA_INFO,1,

(LPDBCoiidiliuii)<

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論