當前(qián)位置:首頁 > 技(jì)術(shù)支持 > 技術文(wén)章
摘要(yào):本文闡述了在蝌蚪视频在线观看(ōu)視邁(OZEAM)全數字可視對講係統(tǒng)程序調試過程中通過map(映射文件)和cod(程序集(jí)、機(jī)器碼、源代碼)文件查找異常地址的方法(fǎ)和應用技巧
關(guān)鍵詞:程序異常 全數字可視對講係統 蝌蚪视频在线观看視邁 OZEAM 異常地址 map cod
我們在研發蝌蚪视频在线观看視(shì)邁(OZEAM)全數字可視對講係統程序(xù)時,經常會遇到程序異常的(de)情況。在程序異常時,通常通過debug調(diào)試的方法找原因。在非調試的模式下或者(zhě)實際應用中(zhōng),程序(xù)出現(xiàn)崩潰,當程序比較複雜,通(tōng)過查看代碼不容易查出問題。
在(zài)evc和vs2005的(de)工具中,可以通過生成map(映射文件)和cod(程序集、機器碼、源(yuán)代碼)文件查找異常地址。map可定位在(zài)發生崩潰的函數,code文件可定位在具體函數中的某一行。
在evc中配置設置如下
(1)生成Cod文件:在(zài)Project->Setting->C/C++->Listing file type中,選擇Assembli,Machine Code,and Source。如圖1.1.
圖(tú)1.1
(2)生成Map文件:在Project->Setting->Link中,在Generate mapfile選項中打(dǎ)勾。如圖1.2
圖1.2
在vs2005中配置設置如下
(1)生成Cod文件:在屬性->配(pèi)置屬性->C/C++->輸出文(wén)件中,選擇程序集、機器碼(mǎ)和原代碼(/FAcs)。如圖1.3
圖1.3
(2)生成Map文件:在屬性->配置屬性->鏈接器->調試->生成映射文件選擇(zé)是(/NAP).如(rú)圖1.4
圖1.4
設置該2項後,編譯工程,會生(shēng)成.cod和.map文件。這些文件就是用來查找異常地址。
下麵(miàn)舉個例子:
void CHelloDlg::Fun(char *pbuf)
{
*pbuf = 1;
}
// CHelloDlg 消息(xī)處理程序
BOOL CHelloDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 設置此對話框的圖標。當應用程序主窗口不是對話框時,框架將自(zì)動
// 執行此操作
SetIcon(m_hIcon, TRUE); // 設置大圖標
SetIcon(m_hIcon, FALSE); // 設置小圖標(biāo)
// TODO: 在此添加額外的初始化代碼
char *p = 0;
Fun(p);
return TRUE; // 除非將焦點設置到控件,否則返回TRUE
}
很容易看出來,在(zài)函數Fun中pbuf是(shì)參數(shù)p沒有申請(qǐng)空間(jiān),所以(yǐ)*pbuf = 1會異(yì)常。
所以在運行時出現如下異常:
PC=0001119c(Hello.exe+0x0000119c) RA=00011194(Hello.exe +0x00001194) SP=0004f620, BVA=00000000
這裏麵最關鍵的信息是(shì)PC和RA給出的地址信(xìn)息。PC就是上麵(miàn)提到的崩潰地址,根(gēn)據這個地址可以定位到導致崩潰的源代碼行(háng);RA是(shì)PC的返回地址(Return Address),根據這個地(dì)址可以找到導致崩潰的上一級函(hán)數。除了(le)PC和RA,其(qí)他信息也可以提供一(yī)些參考作用:BVA是ARM中的Fault Address Register(FAR),是引起Data Abort的(de)虛擬地址,比如說你的程序試圖訪問一個(gè)非法地址(zhǐ)裏的內容(róng),那麽Data Abort時BVA就是(shì)這個非法地址;FSR是Fault Status Register,指明導致異常的原因。
1、查找異常的函數:
打開Hello.map文件(jiàn),內容如下(xià)(截取部分)
Address Publics by Value Rva+Base Lib:Object
0001:0000015c ?DoDataExchange@CHelloDlg@@MAAXPAVCDataExchange@@@Z 0001115c f HelloDlg.obj
0001:0000015c ?Serialize@CObject@@UAAXAAVCArchive@@@Z 0001115c f Hello.obj
0001:0000015c ?OnBnClickedButton1@CHelloDlg@@QAAXXZ 0001115c f HelloDlg.obj
0001:0000015c ?DoDataExchange@CWnd@@MAAXPAVCDataExchange@@@Z 0001115c f HelloDlg.obj
0001:00000160 ?OnInitDialog@CHelloDlg@@MAAHXZ 00011160 f HelloDlg.obj
0001:000001a8 ?GetMessageMap@CHelloDlg@@MBAPBUAFX_MSGMAP@@XZ 000111a8 f HelloDlg.obj
0001:000001b4 ?GetMessageMap@CWinApp@@MBAPBUAFX_MSGMAP@@XZ 000111b4 f uafxcw:appcore.obj
0001:000001b4 ?GetThisMessageMap@CWinApp@@KAPBUAFX_MSGMAP@@XZ 000111b4 f uafxcw:appcore.obj
0001:000001c0 ?_LoadSysPolicies@CWinApp@@IAAHXZ 000111c0 f uafxcw:appcore.obj
0001:000002e4 ?InitApplication@CWinApp@@UAAHXZ 000112e4 f uafxcw:appcore.obj
0001:00000370 ??1CWinApp@@UAA@XZ 00011370 f uafxcw:appcore.obj
0001:000004bc ?ExitInstance@CWinApp@@UAAHXZ 000114bc f uafxcw:appcore.obj
通過異常地址0001119c,找(zhǎo)到最相近的2個地(dì)址
OnInitDialog@CHelloDlg@@MAAHXZ 00011160 f HelloDlg.obj
GetMessageMap@CHelloDlg@@MBAPBUAFX_MSGMAP@@XZ 000111a8 f HelloDlg.obj
以上2個地址(zhǐ)表示函數的起始地址,所以直接看HelloDlg,異常的地址在HelloDlg .obj的CHelloDlg的OnInitDialog。相(xiàng)應的代碼在HelloDlg.cod
2、查找(zhǎo)異常(cháng)的行號
異常地址為0001119c,減去(qù)起始地址00011160,得(dé)0x3c。
異常(cháng)地(dì)址的上一層函數地址為00011194,減去起始地址(zhǐ)00011160,得0x34。
打開(kāi)HelloDlg.cod,部分內容(róng)如下
; 48 :
; 49 : // TODO: 在此添加額外的初始化代(dài)碼
; 50 : char *p = 0;
00034 e3a02000 mov r2, #0
; 51 : FunOSAD(p);
00038 e3a03001 mov r3, #1
0003c e5c23000 strb r3, [r2]
; 52 :
; 53 : return TRUE; // 除非將焦點設置到控件,否則返回 TRUE
(說明:48是行號(hào),00034是十六進製地址)
根據0x3c,可找到0003c e5c23000 strb r3, [r2],往上看,可以(yǐ)知道在FunOSAD中異常了。第51行。即(jí)*pbuf = 1;這一行。
上一層地址0x34,可找到(dào)上一級函數(shù)00034 e3a02000 mov r2, #0,往上看可知道上一級地址(zhǐ)為char *p = 0;,第(dì)50行。
以上方法成功應(yīng)用於蝌蚪视频在线观看視邁(OZEAM)全數字可視對講係統、智能家居係統程序的(de)研發過程,使產品更加穩(wěn)定。
全數字可視(shì)對講係統
類數(shù)字可視對講係統
電(diàn)梯控製係統
雙向可(kě)視(shì)對講求助係統
智能家居係統
聲波雲門禁係統
4000-020-230