日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 芯聞號(hào) > 充電吧
[導(dǎo)讀]I.?內(nèi)存分配問題1. 變量未初始化。為debug中會(huì)自動(dòng)給變量初始化found=FALSE,而在release版中則不會(huì)。所以盡可能的給變量、類或結(jié)構(gòu)初始化。2. 數(shù)據(jù)溢出的問題如:char buf

I.?內(nèi)存分配問題

1. 變量未初始化。
為debug中會(huì)自動(dòng)給變量初始化found=FALSE,而在release版中
則不會(huì)。所以盡可能的給變量、類或結(jié)構(gòu)初始化。
2. 數(shù)據(jù)溢出的問題
如:char buffer[10];
int counter;
lstrcpy(buffer, "abcdefghik");
在debug版中buffer的NULL覆蓋了counter的高位,但是除非counter>16M,什么問題也沒
有。但是在release版中,counter可能被放在寄存器中,這樣NULL就覆蓋了buffer下面
的空間,可能就是函數(shù)的返回地址,這將導(dǎo)致ACCESS ERROR。
3. DEBUG版和RELEASE版的內(nèi)存分配方式是不同的 。如果你在DEBUG版中申請(qǐng)
ele 為 6*sizeof(DWORD)=24bytes,實(shí)際上分配給你的是32bytes(debug版以32bytes
為單位分配), 而在release版,分配給你的就是24bytes(release版以8bytes為單位
),所以在debug版中如果你寫ele[6],可能不會(huì)有什么問題,而在release版中,就有A
CCESS VIOLATE。
II. ASSERT和VERIFY
1. ASSERT在Release版本中是不會(huì)被編譯的。?
假如你在這些語句中加了程序中必須要有的代

比如
ASSERT(pNewObj = new CMyClass);
pNewObj->MyFunction();
這種時(shí)候Release版本中的pNewObj不會(huì)分配到空間
所以執(zhí)行到下一個(gè)語句的時(shí)候程序會(huì)報(bào)該程序執(zhí)行了非法操作的錯(cuò)誤。這時(shí)可以用VERIFY?
III. 參數(shù)問題:
自定義消息的處理函數(shù),必須定義如下:
afx_msg LRESULT OnMyMessage(WPARAM, LPARAM);
返回值必須是HRESULT型,否則Debug會(huì)過,而Release出錯(cuò)?
IV.?內(nèi)存分配
保證數(shù)據(jù)創(chuàng)建和清除的統(tǒng)一性:如果一個(gè)DLL提供一個(gè)能夠創(chuàng)建數(shù)據(jù)的函數(shù),那么這個(gè)D
LL同時(shí)應(yīng)該提供一個(gè)函數(shù)銷毀這些數(shù)據(jù)。數(shù)據(jù)的創(chuàng)建和清除應(yīng)該在同一個(gè)層次上。
V.?DLL的災(zāi)難
人們將不同版本DLL混合造成的不一致性形象的稱為 “動(dòng)態(tài)連接庫的地獄“(DLL?Hell)?
如果你的程序使用你自己的DLL時(shí)請(qǐng)注意:
1. 不能將debug和release版的DLL混合在一起使用。debug都是debug版,releas
e版都是release版。
解決辦法是將debug和release的程序分別放在主程序的debug和release目錄下
2. 千萬不要以為靜態(tài)連接庫會(huì)解決問題,那只會(huì)使情況更糟糕
VI. RELEASE板中的調(diào)試 :
1. 將ASSERT() 改為 VERIFY() 。找出定義在"#ifdef _DEBUG"中的代碼,如果
在RELEASE版本中需要這些代碼請(qǐng)將他們移到定義外。查找TRACE(...)中代碼,因?yàn)檫@些
代碼在RELEASE中也不被編譯。 請(qǐng)認(rèn)真檢查那些在RELEASE中需要的代碼是否并沒有被便
宜。
2. 變量的初始化所帶來的不同,在不同的系統(tǒng),或是在DEBUG/RELEASE版本間
都存在這樣的差異,所以請(qǐng)對(duì)變量進(jìn)行初始化。
3. 是否在編譯時(shí)已經(jīng)有了警告?請(qǐng)將警告級(jí)別設(shè)置為3或4,然后保證在編譯時(shí)沒
有警告出現(xiàn).
VII. 將Project Settings" 中 "C++/C " 項(xiàng)目下優(yōu)化選項(xiàng)改為Disbale(Debug)。編
譯器的優(yōu)化可能導(dǎo)致許多意想不到的錯(cuò)誤,請(qǐng)參考http://www.pgh.net/~newcomer/deb
ug_release.htm
1. 此外對(duì)RELEASE版本的軟件也可以進(jìn)行調(diào)試,請(qǐng)做如下改動(dòng):
在"Project Settings" 中 "C++/C " 項(xiàng)目下設(shè)置 "category" 為 "General" 并且將"D
ebug Info"設(shè)置為 "Program Database"。
在"Link"項(xiàng)目下選中"Generate Debug Info"檢查框。
"Rebuild All"
如此做法會(huì)產(chǎn)生的一些限制:
無法獲得在MFC?DLL中的變量的值。

必須對(duì)該軟件所使用的所有DLL工程都進(jìn)行改動(dòng)。

=========================================================


例子: 作為Windows程序員,平時(shí)最擔(dān)心見到的事情可能就是程序發(fā)生了崩潰(異常),這時(shí)Windows會(huì)提示該程序執(zhí)行了非法操作,即將關(guān)閉。請(qǐng)與您的供應(yīng)商聯(lián)系。呵呵,這句微軟的“名言”,恐怕是程序員最怕見也最常見的東西了。


在一個(gè)大型軟件的測(cè)試過程中,初期出現(xiàn)程序崩潰似乎成了不可避免的事。其實(shí)測(cè)試中出現(xiàn)程序崩潰并不可怕,反而是測(cè)試的成功。作為開發(fā)的我們更需要關(guān)心的是程序中的哪個(gè)函數(shù)或哪一行導(dǎo)致了系統(tǒng)崩潰,這樣才能有針對(duì)性的進(jìn)行改正。

本文描述了自己總結(jié)的幾種定位崩潰的辦法。? ??案例分析

以下是幾種常見的崩潰現(xiàn)象及對(duì)應(yīng)的處理辦法:

1.????????對(duì)于Release版本必現(xiàn)的崩潰且在Debug版本上也崩潰的程序。

解決思路:去掉所有斷點(diǎn),直接在Debug版本上運(yùn)行程序,在程序崩潰時(shí),VC會(huì)自動(dòng)跳轉(zhuǎn)定位到崩潰代碼行,?這種方法最簡(jiǎn)單也最常用。

2.????????對(duì)于在Debug版本上不崩潰但Release版本崩潰的程序,很有可能是Debug和Release版本的差異。例如Debug版本所有成員在構(gòu)造時(shí)會(huì)被清0,而Release版本所有成員在構(gòu)造時(shí)是內(nèi)存里面的原始值,而且Debug有運(yùn)行時(shí)庫做保護(hù),這些都會(huì)導(dǎo)致某些程序在Debug正常而Release崩潰。

解決思路:1)在程序中加打印,通過程序崩潰之前的打印定位出錯(cuò)位置;?2)逐段注釋代碼,直到程序不崩潰為止。這種方法耗時(shí)較長(zhǎng),對(duì)程序員要求較高,而且對(duì)于那種不是必現(xiàn)的bug或者很難搭建執(zhí)行環(huán)境的情況就較難處理了。

3.????????對(duì)于在客戶現(xiàn)場(chǎng)崩潰的情況,顯然不適合直接帶一臺(tái)電腦去調(diào)試。

解決思路:應(yīng)該有文件記錄下崩潰信息,客服人員可以將崩潰信息文件發(fā)送給程序員,以便程序員查詢崩潰原因,然后利用編譯時(shí)生成MAP文件(工程信息文件,存放在版本編譯機(jī)中)的信息來定位問題函數(shù)或問題代碼行。下面就這種方法展開討論一

對(duì)于上節(jié)第三種情況,也是最難解決的情況,解決過程如下:

1.??????崩潰回調(diào)注冊(cè),攔截Windows程序崩潰;

2.??????在回調(diào)處理中,輸出崩潰原因,崩潰內(nèi)存地址,崩潰堆棧;

3.??????工程輸出map文件;

4.??????通過崩潰內(nèi)存地址以及map文件找出崩潰的函數(shù)。

5.??????使用COD文件精確定位崩潰行

?

? ??崩潰回調(diào)注冊(cè)

實(shí)際上,只靠Windows的錯(cuò)誤消息對(duì)話框提供的信息量是很有限的。用SetUnhandledExceptionFilter注冊(cè)自定義錯(cuò)誤處理回調(diào)函數(shù),可以替換Win32默認(rèn)的異常處理過濾器(top-level exception filter),而且能打印出崩潰堆棧,這對(duì)定位崩潰原因非常有用。

SetUnhandledExceptionFilter的函數(shù)原型:

LPTOP_LEVEL_EXCEPTION_FILTER?SetUnhandledExceptionFilter(

LPTOP_LEVEL_EXCEPTION_FILTER?lpTopLevelExceptionFilter?);?

功??能:注冊(cè)和注銷異常處理回調(diào);

用??法:第一次調(diào)用注冊(cè)異常處理回調(diào),第二次調(diào)用注銷;

返回值:返回當(dāng)前的exception filter。需要保存這個(gè)函數(shù)指針,在注銷異常處理回調(diào)的時(shí)候,以此為參數(shù)再次調(diào)用SetUnhandledExceptionFilter。打印異常處理也需要此值。

參數(shù):?異常處理的回調(diào)函數(shù);

?

3出崩潰信息

崩潰信息在異?;卣{(diào)函數(shù)中打印,輸出到程序執(zhí)行目錄下的文件:

異常處理回調(diào)的函數(shù)原形:

LONG?WINAPI?CallBackDebugInfo?(?EXCEPTION_POINTERS?*pException);?

功??能:異常處理回調(diào)處理,打印崩潰信息;

用??法:注冊(cè)自定義錯(cuò)誤處理回調(diào):SetUnhandledExceptionFilter (CallBackDebugInfo);

返回值:EXCEPTION_CONTINUE_EXECUTION –??錯(cuò)誤已經(jīng)被修復(fù),從異常發(fā)生處繼續(xù)執(zhí)行

EXCEPTION_CONTINUE_SEARCH????–??繼續(xù)查找異常過濾器

EXCEPTION_EXECUTE_HANDLER???–??正常返回

參數(shù):?崩潰信息結(jié)構(gòu),包含崩潰原因、崩潰模塊、崩潰地址、崩潰堆棧等;

常見崩潰原因有:

EXCEPTION_ACCESS_VIOLATION = C0000005h???讀寫內(nèi)存錯(cuò)誤

EXCEPTION_INT_DIVIDE_BY_ZERO = C0000094h??除0錯(cuò)誤

EXCEPTION_STACK_OVERFLOW = C00000FDh??堆棧溢出或者越界

EXCEPTION_GUARD_PAGE = 80000001h?由Virtual Alloc建立起來的屬性頁沖突

EXCEPTION_NONCONTINUABLE_EXCEPTION = C0000025h不可持續(xù)異常,程序無法恢復(fù)執(zhí)行,異常處理例程不應(yīng)處理這個(gè)異常

EXCEPTION_INVALID_DISPOSITION = C0000026h在異常處理過程中系統(tǒng)使用的代碼

EXCEPTION_BREAKPOINT = 80000003h??調(diào)試時(shí)中斷(INT 3)

EXCEPTION_SINGLE_STEP = 80000004h??單步調(diào)試狀態(tài)(INT 1)

?

3.3?????輸出map文件

map文件記錄程序的全局符號(hào)、源文件和代碼行號(hào)信息,是整個(gè)程序工程信息的靜態(tài)文本。通過文本閱讀工具如Ultra Edit或記事本就可以打開Map文件。

在?VC?中,打開“Project Settings”選項(xiàng)頁,選擇?C/C++?選項(xiàng)卡,并在最下面的?Project Options?里面輸入:/Zd?,然后選擇?Link?選項(xiàng)卡,選中“Generate mapfile”復(fù)選框。并在最下面的?Project Options里面輸入:/mapinfo:lines,表示生成?map?文件時(shí),加入行信息。

?


最后編譯就可以生成?MAP?文件,可以在工程的Debug或Release目錄下找到剛剛生成的MAP文件,文件名為“工程名.map”。

?

3.4?????使用map文件找出崩潰函數(shù)

  ??? 通過上面的步驟,已經(jīng)得到了?MAP?文件,那么我們?cè)撊绾卫盟??下面一步步演示使用MAP文件定位程序崩潰行的過程。

??????1.我們先在代碼中加入非法內(nèi)存操作(最常見的異常)的代碼:

BOOL CMainFrameDlg::OnInitDialog()

{

?????????::SetProp(m_hWnd,?AfxGetApp()->m_pszExeName, (HANDLE)1);

?????????s32 *p?=?NULL;

?????????*p=?123;

?

2.執(zhí)行程序,程序在開始就異常,在異常打印文件中打印了如下信息:

========================?崩潰信息?==========================

崩潰時(shí)間:?2009/06/02 16:58:22

崩潰原因:?非法內(nèi)存操作

異常代碼?= c0000005

異常地址?= 0x0045a76f

異常模塊: E:ccrootliuxiaojing_EnterpriseEnterprise_VOB70-nms1pcmt2prj_win32Releasepcmt2.exe

Section name: .text - offset(rva) : 0x0005976f

---------------------- Trips of Stack ----------------------

E:ccrootliuxiaojing_EnterpriseEnterprise_VOB70-nms1pcmt2prj_win32Releasepcmt2.exe

name : pcmtver - location: 2bef

3.?確定崩潰地址是:0x0005976f,在Map文件中定位函數(shù):

0001:00059420 ?OnCreate@CMainFrameDlg@@IAEHPAUtagCREATESTRUCTA@@@Z?0045a420 f??MainFrameDlg.obj

?0001:00059460????????SetTooltips@CMainFrameDlg@@AAEXXZ?0045a460 f???MainFrameDlg.obj

?0001:00059700????????OnTranslate@CMainFrameDlg@@IAEJIJ@Z?0045a700 f???MainFrameDlg.obj

?0001:00059730????????OnInitDialog@CMainFrameDlg@@MAEHXZ?0045a730 f???MainFrameDlg.obj

?0001:00059a10???OnSysCommand@CMainFrameDlg@@IAEXIJ@Z 0045aa10 f???MainFrameDlg.obj

?0001:00059c20????????OnPaint@CMainFrameDlg@@IAEXXZ?0045ac20 f???MainFrameDlg.obj

根據(jù)00059730<?0005976f?<?00059a10?,確定是在CMainFrameDlg?的OnInitDialog函數(shù)中的某一行產(chǎn)生了異常。

3.5?????使用map代碼行定位崩潰行區(qū)間

?

Line numbers for .ReleaseMainFrameDlg.obj(E:ccrootliuxiaojing_EnterpriseEnterprise_VOB70-nms1pcmt2sourceMainFrameDlg.cpp) segment .text

???498 0001:00059647???499 0001:00059667???501 0001:0005966e???502 0001:000596af

???503 0001:000596ed???506 0001:00059700???507 0001:00059703???508 0001:00059708

???510 0001:0005970f???511 0001:00059720???512 0001:00059723???515 0001:00059730

???516 0001:0005974e???521 0001:0005976d???524 0001:0005977e???526 0001:0005978b

我們?cè)趍ap文件的代碼行信息里查找不超過計(jì)算結(jié)果0x0005976f,但可以找最接近的數(shù)。發(fā)現(xiàn)是MainFrameDlg.cpp?文件中的:521 0001:0005976d,而程序?qū)嶋H崩潰行在519(注釋行和空行也要計(jì)算在內(nèi)),非常接近實(shí)際崩潰行了,考慮到程序?qū)嶋H執(zhí)行的是匯編指令,我們可以在(516 ~524)行區(qū)間內(nèi)尋找到實(shí)際崩潰行。

  

3.6?????無法定位崩潰的情況

但是這種輸出文件的方法也不能定位所有崩潰問題,俗話說得好:沒有萬能的救世主。

例如我們有時(shí)會(huì)碰到下層編解碼器崩潰,崩潰打印如下表:

========================?崩潰信息?==========================

崩潰時(shí)間:?2009/05/07 09:48:17

崩潰原因:?非法內(nèi)存操作

異常代碼?= c0000005

異常地址?= 0x02163b32

異常模塊: C:WINDOWSsystem32kdg7221.acm

Section name: .text - offset(rva) : 0x00002b32

---------------------- Trips of Stack ----------------------

C:WINDOWSsystem32kdg7221.acm

???這時(shí)可以看出是我們的音頻解碼器kdg7221.acm崩潰了,此時(shí)就要考慮我們的音頻編解碼參數(shù)是否設(shè)置錯(cuò)了,如果沒有設(shè)錯(cuò),bug可以轉(zhuǎn)到媒體處理層或者軟件一部處理。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀
關(guān)閉