16錯(cuò)誤處理_第1頁(yè)
16錯(cuò)誤處理_第2頁(yè)
16錯(cuò)誤處理_第3頁(yè)
16錯(cuò)誤處理_第4頁(yè)
16錯(cuò)誤處理_第5頁(yè)
已閱讀5頁(yè),還剩22頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

錯(cuò)誤處理 目標(biāo) 了解錯(cuò)誤檢查和錯(cuò)誤處理的方法,從而提高編碼的質(zhì)量 目錄 概述 錯(cuò)誤檢查 錯(cuò)誤處理 GOTO GOTO GOTO 概述 錯(cuò)誤的分類 不應(yīng)該發(fā)生的錯(cuò)誤 “應(yīng)該發(fā)生”的錯(cuò)誤 錯(cuò)誤處理的幾個(gè)方面 錯(cuò)誤檢查 發(fā)生異常錯(cuò)誤時(shí)的處理 返回錯(cuò)誤 錯(cuò)誤處理的原則 輸入垃圾,不能輸出垃圾 錯(cuò)誤檢查 斷言 檢查輸入?yún)?shù) 檢查內(nèi)部調(diào)用函數(shù)的返回值 錯(cuò)誤檢查與性能的平衡 GOTO GOTO GOTO GOTO BACK 錯(cuò)誤檢查 斷言( ASSERT) 用于檢查 “不應(yīng)該發(fā)生的錯(cuò)誤” 。 僅在 Debug版本起作用。 如果程序在 assert處終止了,并不是說(shuō)含有該 assert的函數(shù)有錯(cuò)誤,而是調(diào)用者出了差錯(cuò), assert可以幫助我們找到發(fā)生錯(cuò)誤的原因。 對(duì)于內(nèi)部使用的函數(shù),通常可以用斷言,而對(duì)于提供給外部使用的函數(shù),最好使用錯(cuò)誤處理。 錯(cuò)誤檢查 斷言( ASSERT) 一個(gè)例子 void *memcpy(void *pvTo, const void *pvFrom, size_t size) /*使用斷言 */ assert(pvTo != NULL) & (pvFrom != NULL); byte *pbTo = (byte *) pvTo;/防止改變 pvTo的地址 byte *pbFrom = (byte *) pvFrom;/防止改變pvFrom的地址 */ while(size - 0 ) *pbTo + = *pbFrom + ; return pvTo; 錯(cuò)誤檢查 斷言( ASSERT) 使用 assert時(shí)需要注意: 在編寫函數(shù)時(shí),要進(jìn)行反復(fù)的考查,并且自問(wèn):“ 我打算做哪些假定? ” 一旦確定了的假定,就要使用斷言對(duì)假定進(jìn)行檢查 assert不應(yīng)該產(chǎn)主其他的副作用 ,因?yàn)?assert在release版是不執(zhí)行的 Assert(a = b);/a=b在 release版不執(zhí)行,錯(cuò)誤 BACK 錯(cuò)誤檢查 檢查輸入?yún)?shù) 檢查輸入的內(nèi)核對(duì)象 Handle是否有效,如線程handle、 event handle、文件 handle等 if( INVALID_HANDLE = inputHandle) 檢查指針是否為 NULL if( NULL = inputPtr) 檢查參數(shù)的取值范圍是否符合對(duì)它的限制,對(duì)數(shù)組下標(biāo)和偏移量尤其要檢查,因?yàn)橐粋€(gè)不合法的數(shù)組小標(biāo)和偏移量會(huì)導(dǎo)致非法的內(nèi)存訪問(wèn) If( 0=maxSize) If( 0 31 ) 錯(cuò)誤檢查 檢查輸入?yún)?shù) int noteL03_FAC_MakeDetail(MarkID_t *pstMarkID, void *pResult) do if( (NULL = pResult)|(NULL = pstMarkID) ) break; while(false); int noteL99_GetFileNameAndCateInfo(int index, , INNOTE_CateInfo_t *pstCateInfo) do if( index = INNOTE_DB_FILE_MAX ) break; *pstCateInfo = stNoteManageInfo.stCateInfoindex; while(false); BACK 錯(cuò)誤檢查 檢查函數(shù)返回值 內(nèi)核對(duì)象操作 fileHdl = noteL99_FileOpen(fName, O_BINARY|O_RDONLY, S_OREAD); if( fileHdl 0 ) break; 內(nèi)存操作 buffHdl = noteL99_AssignMemory( buffSize ); if( buffHdl 0 ) break; pBuff = noteL99_LockMemory( buffHdl ); if( NULL = pBuff ) break; 一般函數(shù)的返回值 對(duì)所有函數(shù)的返回值進(jìn)行判斷,除非該函數(shù)沒(méi)有返回值 BACK 錯(cuò)誤檢查與性能的平衡 過(guò)多的錯(cuò)誤檢查會(huì)影響性能 為了減少調(diào)用者的負(fù)擔(dān),如果函數(shù)任何情況下都不會(huì)出錯(cuò),就不要有返回值 要避免重復(fù)的,無(wú)效的錯(cuò)誤檢查 對(duì)于“不應(yīng)該發(fā)生”的錯(cuò)誤,使用斷言在開(kāi)發(fā)階段發(fā)現(xiàn)錯(cuò)誤,發(fā)布以后就不進(jìn)行錯(cuò)誤檢查了 BACK 錯(cuò)誤處理 常用錯(cuò)誤處理的方式 返回錯(cuò)誤信息的幾種方式 錯(cuò)誤處理的實(shí)踐 GOTO GOTO GOTO 常用錯(cuò)誤處理的方式 把錯(cuò)誤校正,并輸出正確的結(jié)果 函數(shù)的容錯(cuò)性很好,但是會(huì)隱藏調(diào)用者的錯(cuò)誤 大部分情況下,因?yàn)殄e(cuò)誤是不能校正的,所以不能這樣處理 什么都不輸出,返回成功信息 函數(shù)的容錯(cuò)性較好,但是會(huì)給調(diào)用者帶來(lái)麻煩 不建議使用 什么也不輸出,“返回”錯(cuò)誤信息 建議使用 結(jié)束程序的運(yùn)行 除非發(fā)生了極其嚴(yán)重的錯(cuò)誤,否則不要這樣做 返回錯(cuò)誤信息的方式 通過(guò)函數(shù)返回值返回錯(cuò)誤代碼 更新某個(gè)公共的狀態(tài) 通過(guò) event、 message等發(fā)出錯(cuò)誤的通知 輸出打印信息 Error Log 上面幾種的混合 注意:函數(shù)采用什么處理方式要在系統(tǒng)范圍內(nèi)或模塊范圍內(nèi)統(tǒng)一規(guī)定,開(kāi)發(fā)者在設(shè)計(jì)和編寫函數(shù)的時(shí)候一定要弄清楚系統(tǒng)和模塊的錯(cuò)誤處理方式,并按照要求進(jìn)行錯(cuò)誤處理 返回錯(cuò)誤信息 返回值 返回值的方式 返回值 定義不同的返回值以標(biāo)識(shí)錯(cuò)誤原因 返回值 + GetLastError 返回值只說(shuō)明發(fā)生了錯(cuò)誤 具體的錯(cuò)誤原因通過(guò) GetLastError()獲得 這是 Windows系統(tǒng)處理錯(cuò)誤的方法 錯(cuò)誤代碼的定義 足夠的 必要的 注意:盡量使用系統(tǒng)和模塊統(tǒng)一定義的錯(cuò)誤代碼。除非萬(wàn)不得已,不要自己?jiǎn)为?dú)定義。 返回錯(cuò)誤信息 返回值 錯(cuò)誤代碼的定義實(shí)例 COM S_OK E_FAIL E_NOTIMPL E_INVALIDARG System Errors ERROR_SUCCESS ERROR_FILE_NOT_FOUND ERROR_TOO_MANY_OPEN_FILES ERROR_ACCESS_DENIED 返回錯(cuò)誤信息 打印信息 輸出打印信息實(shí)例 #if defined(DEVELOP_PHASE_DEBUG) #define DEBUGprintf(Argument_) printf_(%10s:%4d,_FILE_,_LINE_); REGULARprintf(Argument_); #else #define DEBUGprintf(Argument_) #endif 只能在 Debug版使用 注意:為了共同調(diào)試的方便,打印信息的格式最好在系統(tǒng)一級(jí)有統(tǒng)一的定義。開(kāi)發(fā)者在函數(shù)中輸出的打印信息必須符合系統(tǒng)的定義 返回錯(cuò)誤信息 Error log Error Log 在 Release版, Error Log是唯一獲得出錯(cuò)信息的途徑 Error Log的信息 根據(jù) Error Log信息必須可以迅速確定出問(wèn)題的位置 從 Error Log中必須盡可能多的包含有意義的信息 返回錯(cuò)誤信息 Error log Error Log void Inspect_writeErrorRecord( uint ErrorKind, uint ModuleID, uint Parameter1, uint Parameter2, uint Parameter3, uint Parameter4); BACK 錯(cuò)誤處理的實(shí)踐 現(xiàn)場(chǎng)恢復(fù) 函數(shù)因發(fā)生錯(cuò)誤而 return時(shí),一定要 “恢復(fù)現(xiàn)場(chǎng)”,即在return前讓系統(tǒng)盡可能恢復(fù)到進(jìn)入函數(shù)時(shí)的樣子 如果申請(qǐng)了資源, return前要回收 釋放申請(qǐng)的內(nèi)存,關(guān)閉在函數(shù)內(nèi)打開(kāi)或創(chuàng)建的內(nèi)核對(duì)象等 如果修改了輸出參數(shù),要把該參數(shù)恢復(fù)原來(lái)的值或設(shè)成其他合理的值(輸入?yún)?shù)是不允許修改的) 如果修改了全局變量,或?qū)ξ募M(jìn)行了寫操作,要將全局變量和文件恢復(fù)成進(jìn)入函數(shù)時(shí)的樣子 注意:如果不能完全恢復(fù)現(xiàn)場(chǎng),至少要將資源正確回收 錯(cuò)誤處理的實(shí)踐 現(xiàn)場(chǎng)恢復(fù) int sample() fileHdl = noteL99_FileOpen(); if( fileHdl 0 ) return FAILURE; buffHdl = noteL99_AssignMemory( ); if( buffHdl 0 ) return FAILURE; pBuff = noteL99_LockMemory( buffHdl ); if( NULL = pBuff ) noteL99_ReleaseMemory( buffHdl ); return FAILURE; return SUCCESS; 錯(cuò)誤處理的實(shí)踐 函數(shù)結(jié)構(gòu) 前面例子的問(wèn)題 發(fā)現(xiàn)錯(cuò)誤就 return 每次 return都要回收資源,很麻煩 容易出錯(cuò) 容易遺漏 錯(cuò)誤處理的實(shí)踐 函數(shù)結(jié)構(gòu) 修正方式一: goto 可以集中回收資源 不容易控制,一般項(xiàng)目都不允許用 goto 錯(cuò)誤處理的實(shí)踐 函數(shù)結(jié)構(gòu) 修正方式二: do-while 可以集中回收資源 安全 錯(cuò)誤處理的實(shí)踐 異常 void AFunctionMayMeetSomeError() / 錯(cuò)誤發(fā)生了 throw exception(meet

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論