版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 中藥師崗位職責(zé)制度
- 專利標(biāo)引制度
- 機(jī)加工行車安全培訓(xùn)課件
- 直腸癌放療患者的護(hù)理創(chuàng)新方法
- 2025-2030中國PTFE微粉市場運(yùn)行監(jiān)測與未來行情走勢預(yù)測研究報(bào)告
- 2026中國空氣表面消毒行業(yè)運(yùn)行態(tài)勢與投資趨勢預(yù)測報(bào)告
- 2025-2030綜合零售產(chǎn)業(yè)行業(yè)現(xiàn)狀全面調(diào)研及市場發(fā)展趨勢與資源配置報(bào)告
- 2025-2030中國垃圾處置設(shè)施市場消費(fèi)趨勢與多元化銷售渠道研究報(bào)告
- 東莞市中堂鎮(zhèn)公開招聘編外聘用人員20人備考題庫及參考答案詳解1套
- 2026年重慶醫(yī)科大學(xué)編外聘用人員招聘備考題庫及完整答案詳解一套
- 2025年互聯(lián)網(wǎng)安全與隱私保護(hù)操作手冊
- 潔凈墻板專項(xiàng)施工方案
- 5g基站施工指導(dǎo)方案
- 浙江省金華市2024-2025學(xué)年七年級上學(xué)期期末地理試卷(含答案)
- 北京通州產(chǎn)業(yè)服務(wù)有限公司招聘參考題庫及答案1套
- 2026年七臺河職業(yè)學(xué)院單招職業(yè)技能筆試模擬試題帶答案解析
- 2025至2030中國短弧氙燈行業(yè)調(diào)研及市場前景預(yù)測評估報(bào)告
- 2026廣東河源市東源縣司法局招聘司法協(xié)理員9人筆試備考題庫及答案解析
- 炎德·英才·名校聯(lián)考聯(lián)合體2026屆高三年級1月聯(lián)考英語試卷(含答及解析)+聽力音頻+聽力材料
- 2025年易制毒化學(xué)品自查報(bào)告
- 科創(chuàng)飛地合作協(xié)議書
評論
0/150
提交評論