青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
數(shù)據(jù)加載中……

調(diào)試Release發(fā)布版程序的Crash錯(cuò)誤

http://blog.sina.com.cn/s/blog_48f93b530100fsln.html

 

Windows平臺(tái)下用C++開發(fā)應(yīng)用程序,最不想見到的情況恐怕就是程序崩潰,而要想解決引起問題的bug,最困難的應(yīng)該就是調(diào)試release版本了。因?yàn)?span lang="EN-US">release版本來就少了很多調(diào)試信息,更何況一般都是發(fā)布出去由用戶使用,crash的現(xiàn)場很難保留和重現(xiàn)。本文將給出幾個(gè)解決方案,完成對(duì)release版應(yīng)用程序crash錯(cuò)誤的調(diào)試。(本文只討論Windows平臺(tái)MSVC環(huán)境下的調(diào)試,對(duì)于其他平臺(tái)和開發(fā)環(huán)境沒有關(guān)注,請(qǐng)大家自己借鑒和嘗試。)

 

    方案一:崩潰地址 + MAP文件

    這種方案只能對(duì)VC7以前的版本開發(fā)的程序使用。 

    1、崩潰地址

     所謂崩潰地址就是引起程序崩潰的內(nèi)存地址,在WinXP下應(yīng)用程序crash的對(duì)話框如下圖:

clip_image001

clip_image002

clip_image003

    上面第2張圖中畫紅線的值為crash的代碼偏移地址,第3張圖為即crash絕對(duì)地址;一般引起crash的原因多為內(nèi)存操作錯(cuò)誤,我們用這兩個(gè)地址和MAP文件就能定位出錯(cuò)的代碼行。

    2MAP文件

    MAP文件是記錄應(yīng)用程序信息的文件(文本文件),里面大概包含了程序的全局符號(hào)、源碼模塊名、源碼文件和行號(hào)等信息,而這些信息能夠幫助我們定位出錯(cuò)的代碼行。

    怎樣生成MAP文件呢?以VC6為例,在 Project Settings -> C/C++ -> Debug info中,選擇 Line Numbers Only ;在 Project Settings -> Link 中,選擇 Generate mapfile項(xiàng),并在Project Options 里面輸入 /MAPINFO:LINES /MAPINFO:EXPORTS,重新編譯程序就會(huì)生成.map文件。

    以上設(shè)置對(duì)應(yīng)的編譯鏈接選項(xiàng)分別分:

    /Zi — 表示生成pdb調(diào)試信息;

    /MAP[:filename] — 表示生成map文件名;

    /MAPINFO:EXPORTS — 表示生成的map文件中加入exported functions(生成DLL文件時(shí));

    /MAPINFO:LINES — 表示生成的map文件中加入代碼行信息。

    由于/MAPINFO:LINES選項(xiàng)在VC8以后的版本中不再支持,因此通過MAP文件中的信息和crash地址定位出錯(cuò)代碼行就比較困難了,所以這種方案只能在VC7及以前的版本中使用。

    一個(gè)MAP文件片段示例如下: 

    clip_image004  

    clip_image005

    圖中Rva+Base列的地址為該行函數(shù)對(duì)應(yīng)的函數(shù)絕對(duì)地址,Address列中冒號(hào)后面的地址為函數(shù)相對(duì)偏移地址。   

    3、定位crash代碼

    有了上面的介紹,定位crash代碼就很簡單了。用下面的公式來進(jìn)行定位:

    崩潰行偏移 = 崩潰地址 - 崩潰函數(shù)絕對(duì)地址 + 函數(shù)相對(duì)偏移

    我們首先根據(jù)崩潰地址(絕對(duì)地址),按照找到第2張圖中Rva+Base列的地址找到發(fā)生崩潰的函數(shù)(即崩潰地址大于該函數(shù)行的Rva+Base地址且小于下個(gè)函數(shù)的地址),然后找到該行對(duì)應(yīng)的函數(shù)相對(duì)偏移地址,帶入公式中,就得到了崩潰行偏移,該值表示崩潰行的代碼相對(duì)于代碼所在函數(shù)的偏移量。用該值去與第3張圖中對(duì)應(yīng)函數(shù)冒號(hào)后面的偏移量去比較,最接近的值前面的那個(gè)十進(jìn)制數(shù)即為代碼所在函數(shù)中的行號(hào)。

    ok,到此我們已經(jīng)成功找到了崩潰的代碼行,只不過這種方法還是比較費(fèi)力,并且限制比較多,我們看看下面的方案。

上篇給出的方案一還要補(bǔ)充幾句。通過“crash地址 + MAP文件來定位出錯(cuò)代碼位置雖然需要經(jīng)過比較復(fù)雜的地址計(jì)算,但卻是最簡單實(shí)現(xiàn)的方式。如果僅僅想通過崩潰地址定位出錯(cuò)的函數(shù),就更加方便了。我在網(wǎng)上找到一個(gè)解析MAP文件的小工具,可以非常清晰的列出每個(gè)函數(shù)的地址,并且可以將分析表格導(dǎo)出為Excel文件。工具下載地址:http://e.ys168.com/?tinyfun,工具目錄下VCMapper.exe

    另外上篇主要參考兩篇文章:

    http://www.vckbase.com/document/viewdoc/?id=908

    http://www.vckbase.com/document/viewdoc/?id=1473

 

    方案二:崩潰地址 + MAP文件 + COD文件

    由于VC8以后的版本都不再支持MAP文件中產(chǎn)生代碼行信息,因此我們尋找另一種定位方式:COD文件。

    1COD文件

    COD文件是一個(gè)包含了匯編碼、二進(jìn)制機(jī)器碼和源代碼對(duì)應(yīng)信息的文件,每一個(gè)cpp都對(duì)應(yīng)一個(gè)COD文件。通過這個(gè)文件,我們可以非常方便地進(jìn)行定位。

    VC6中生成COD文件的設(shè)置方式為:Project Settings -> C/C++,在 Category 中選 Listing Files,在 Listing file type 組合框中選 AssemblyMachine codeand source。在VC8中生成COD文件的設(shè)置方式為:Project Properties -> C/C++ -> Output Files -> Assembler Output 項(xiàng),選擇 AssemblyMachine codeand Source(/Facs)

   

    2、定位崩潰行

    下面通過舉例進(jìn)行說明。現(xiàn)在我有一個(gè)基于對(duì)話框的MFC應(yīng)用程序CrashTest,在CCrashTestDlg::OnInitDialog函數(shù)中寫入導(dǎo)致crash的代碼語句(第99行),源文件如下:

    clip_image006

    根據(jù)崩潰地址(0x004012A3)以及MAP文件(定位片段圖片如下),定位crash函數(shù)為OnInitDialog;并且我們可以很容易地計(jì)算出崩潰地址相對(duì)于崩潰函數(shù)的偏移量為 0x004012A3 - 0x004011E0 = 0xC3

    clip_image007

    再來看看CrashTestDlg.cod文件,我們根據(jù)文件中源碼信息找到OnInitDialog函數(shù)信息片段:

    clip_image008

    可以看到圖片中第一行為OnInitDialog函數(shù)匯編代碼的起始行;找到“int * p = NULL;”這一句源碼,其前面的98表示這行代碼在源文件中的行號(hào),下面的000c1表示相對(duì)于函數(shù)開始位置的偏移量,后面的33 c0”為機(jī)器碼,“xor eaxeax”為匯編碼。那么我們根據(jù)前面算出來的偏移量0xC3,找到對(duì)應(yīng)出錯(cuò)的語句為99行:“*p = 5;”

    總結(jié)一下定位步驟:

    1) 根據(jù)公式 崩潰語句在函數(shù)中偏移地址 = 崩潰地址 - 崩潰函數(shù)地址 計(jì)算出偏移量X

    2) 根據(jù)公式 崩潰語句在COD文件中地址 = 崩潰函數(shù)在COD文件中地址 + X 計(jì)算出地址Y。其中崩潰函數(shù)在COD文件中地址為COD文件中函數(shù)起始括號(hào)“{”后面表明的地址,一般情況下為0x0000

    3) 根據(jù)YCOD文件中找到對(duì)應(yīng)代碼行。

   

    ok,方案二介紹完了。這種方法最大的好處是沒有VC開發(fā)環(huán)境版本限制,而且COD文件里面包含的信息更加豐富,不但可以幫助我們定位crash,還能幫我們分析很多東西。當(dāng)然,這也導(dǎo)致編譯生成了很多信息文件。

根據(jù)前面兩篇博文,我們要定位崩潰行代碼,必須要自己根據(jù)相關(guān)信息文件進(jìn)行計(jì)算。如果需要處理的量比較大,恐怕會(huì)很費(fèi)力氣。有沒有更簡單快速的辦法呢?

    最直接的想法就是寫一個(gè)小工具,根據(jù)規(guī)則和信息進(jìn)行自動(dòng)定位,不過開發(fā)起來也是要費(fèi)一番功夫的。令人開心的是,我們可以找到類似的工具,而且是開源免費(fèi)的!程序員的世界也許很多時(shí)候都是這么單純而樂于分享!

   

    方案三:崩潰地址 + PDB文件 + CrashFinder

    CrashFinder是一個(gè)開源工具,作者是John Robbin,大家可以去他的blog上去找關(guān)于CrashFinder的信息。我們這里以CrashFinder2.5版本為例介紹,相關(guān)文章鏈接為:http://www.wintellect.com/CS/blogs/jrobbins/archive/2006/04/19/crashfinder-returns.aspx

    1PDB文件

    PDBProgram Database)文件中包含了exe程序所有的調(diào)試相關(guān)信息,具體可以查閱MSDN。當(dāng)編譯選項(xiàng)設(shè)置為/Zi,鏈接選項(xiàng)設(shè)置為/DEBUG/OPT:REF時(shí),就會(huì)生成工程的.pdb文件。具體到VC2005中,就是 Project Propertise -> C/C++ -> General -> Debug Information Format 項(xiàng)設(shè)置為 Program Database/Zi),Linker -> Debugging -> Generate Debug Info 項(xiàng)設(shè)置為 Yes/Debug),Linker -> Optimization -> References 項(xiàng)設(shè)置為 Eliminate Unreferenced Data/OPT:REF)。

    只要設(shè)置以上選項(xiàng),release版本也能生成PDB文件。當(dāng)然,對(duì)應(yīng)的應(yīng)用程序也會(huì)稍大。

    2CrashFinder

    CrashFinder能夠運(yùn)行需要兩個(gè)條件:一是系統(tǒng)必須要有dbghelp.dll文件;二是PDB文件必須與exe文件在一個(gè)路徑下。對(duì)于dbghelp.dll,一般在系統(tǒng)system32路徑下都有,如果沒有下載一個(gè)放到這個(gè)目錄下就可以了。

    先看一下CrashFinder的界面。

   

clip_image009

    用起來也非常簡單。首先選擇File->New或點(diǎn)擊工具欄新建按鈕,選擇要調(diào)試的exe文件打開,會(huì)發(fā)現(xiàn)exe及所依賴的dll文件信息都已經(jīng)加載進(jìn)來。在下半部分的編輯框中輸入崩潰地址(16進(jìn)制),點(diǎn)右邊的“Find”按鈕,就會(huì)在下面顯示崩潰的源文件路徑、名稱以及崩潰所在行號(hào)了,如下圖所示。

clip_image010

    CrashFinder進(jìn)行crash定位真的非常方便。但是我在使用過程中發(fā)現(xiàn)了一個(gè)bug,每次啟動(dòng)程序后,直接新建的話加載進(jìn)來的exe模塊都顯示叉,提示找不到debug symbols。但是用打開按鈕隨便打開一個(gè)文件失敗后,再新建就能成功。猜測可能是直接新建,定位PDB文件時(shí)的路徑不對(duì)引起的。有源碼,但是懶的看了呵呵,大家感興趣可以試一下。

    好了,方案三就介紹到這里,后面還有更加強(qiáng)大的方案 : )

前面幾個(gè)方案都是直接定位crash的代碼位置,但是在比較大型的程序中,只知道這個(gè)信息還是遠(yuǎn)遠(yuǎn)不夠的,我們希望知道更多關(guān)于調(diào)用函數(shù)順序及變量值等信息,也就是crash時(shí)調(diào)用堆棧信息。

 

    方案四:SetUnhandledExceptionFilter + StackWalker

    這個(gè)方案需要自己動(dòng)手往工程里添加代碼了。要實(shí)現(xiàn)上面的想法,需要做兩件事情:1、需要在crash時(shí)有機(jī)會(huì)對(duì)程序堆棧進(jìn)行處理;2、對(duì)堆棧信息進(jìn)行收集。

    1SetUnhandleExceptionFilter函數(shù)

    Windows平臺(tái)下的C++程序異常通常可分為兩種:結(jié)構(gòu)化異常(Structured Exception,可以理解為與操作系統(tǒng)相關(guān)的異常)和C++異常。對(duì)于結(jié)構(gòu)化異常處理(SEH),可以找到很多資料,在此不細(xì)說。對(duì)于crash錯(cuò)誤,一般由未被正常捕獲的異常引起,Windows操作系統(tǒng)提供了一個(gè)API函數(shù)可以在程序crash之前有機(jī)會(huì)處理這些異常,就是SetUnhandleExceptionFilter函數(shù)。(C++也有一個(gè)類似函數(shù)set_terminate可以處理未被捕獲的C++異常。)

    SetUnhandleExceptionFilter函數(shù)聲明如下:

    LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(
      __in          LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
    );

    其中 LPTOP_LEVEL_EXCEPTION_FILTER 定義如下:

    typedef LONG (WINAPI *PTOP_LEVEL_EXCEPTION_FILTER)(
        __in struct _EXCEPTION_POINTERS *ExceptionInfo
    );
    typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;

    簡單來說,SetUnhandleExceptionFilter允許我們?cè)O(shè)置一個(gè)自己的函數(shù)作為全局SEH過濾函數(shù),當(dāng)程序crash前會(huì)調(diào)用我們的函數(shù)進(jìn)行處理。我們可以利用的是 _EXCEPTION_POINTERS 結(jié)構(gòu)類型的變量ExceptionInfo,它包含了對(duì)異常的描述以及發(fā)生異常的線程狀態(tài),過濾函數(shù)可以通過返回不同的值來讓系統(tǒng)繼續(xù)運(yùn)行或退出應(yīng)用程序。

    關(guān)于 SetUnhandleExceptionFilter 函數(shù)的具體用法和示例請(qǐng)參考MSDN

 

    2StackWalker
   
現(xiàn)在我們已經(jīng)有機(jī)會(huì)可以在crash之前對(duì)程序狀態(tài)信息進(jìn)行處理了,只需要生成并保存堆棧信息就大功告成了。Windowsdbghelp.dll庫提供了一個(gè)函數(shù)可以得到當(dāng)前堆棧信息:StackWalk64(在Win2K以前版本中為StackWalk)。該函數(shù)聲明如下:

    BOOL WINAPI StackWalk64(
      __in          DWORD MachineType,
      __in          HANDLE hProcess,
      __in          HANDLE hThread,
      __in_out      LPSTACKFRAME64 StackFrame,
      __in_out      PVOID ContextRecord,
      __in          PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
      __in          PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
      __in          PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
      __in          PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
    );
   
該函數(shù)的具體用法可以參考MSDN。在這里推薦一個(gè)牛人寫好的StackWalker,可以直接拿來用,開源的。StackWalker提供了一個(gè)基類,給出了幾個(gè)簡單的接口,可以方便地生成堆棧信息,并且支持一系列VC版本,非常好用。我們可以自己寫一個(gè)子類,并重載虛函數(shù)OnOutput,就可以將堆棧信息輸出為特定格式了。StackWalker的地址為:http://www.codeproject.com/KB/threads/StackWalker.aspx

    不過對(duì)于Release版本來說,StackWalk64函數(shù)獲得的堆棧信息有可能不完整。如果異常是由MFC的模塊拋出,那么獲得的堆棧可能缺少前面調(diào)用模塊信息。另外,StackWalk64需要最新的dbghelp.dll文件支持才能工作;要正確輸出crash的函數(shù)名和行號(hào),需要要pdb文件支持。以上不足有可能影響輸出信息的完整性和效果,而對(duì)于發(fā)布在外的程序,要帶上pdb文件幾乎不可能,因此這個(gè)方案還是有缺憾的,比較適用于本地的release版本調(diào)試。

    下一篇我們將介紹一個(gè)更加完善的解決方案

當(dāng)我們把自己的release版本程序發(fā)布出去以后,一般都是在用戶的機(jī)器上運(yùn)行。這種情況下,對(duì)于第四種方案,因?yàn)樾枰?span lang="EN-US">pdb文件才能夠正確生成堆棧調(diào)用的函數(shù)行號(hào)及代碼行號(hào),因此方案四只適用于本地release版的調(diào)試,否則只能生成不完整的堆棧信息。對(duì)于前三種方案,其實(shí)只需要用戶告知崩潰地址,然后在本地查找crash地址就可以了,但是定位crash的過程非常不方便,如果crash的情況比較多,前三種方案都不合適。而且,前三種方案均不能生成堆棧調(diào)用信息,對(duì)于debug的作用有限。

    下面我們就來看一個(gè)更加完善的解決方案。

 

    方案五:SetUnhandledExceptionFilter + Minidump

    SetUnhandleExceptionFilter函數(shù)我們已經(jīng)介紹過了,本方案的思路還是要利用我們自己的異常處理函數(shù),來生成minidump文件。

    1Minidump概念

    minidump(小存儲(chǔ)器轉(zhuǎn)儲(chǔ))可以理解為一個(gè)dump文件,里面記錄了能夠幫助調(diào)試crash的最小有用信息。實(shí)際上,如果你在 系統(tǒng)屬性 -> 高級(jí) -> 啟動(dòng)和故障恢復(fù) -> 設(shè)置 -> 寫入調(diào)試信息 中選擇小內(nèi)存轉(zhuǎn)儲(chǔ)(64 KB)”的話,當(dāng)系統(tǒng)意外停止時(shí)都會(huì)在C:\Windows\Minidump\路徑下生成一個(gè).dmp后綴的文件,這個(gè)文件就是minidump文件,只不過這個(gè)是內(nèi)核態(tài)的minidump

   我們要生成的是用戶態(tài)的minidump,文件中包含了程序運(yùn)行的模塊信息、線程信息、堆棧調(diào)用信息等。而且為了符合其mini的特性,dump文件是壓縮過的。

    2、生成minidump文件

    生成minidump文件的API函數(shù)是MiniDumpWriteDump,該函數(shù)需要dbghelp.lib支持,其原型如下:

    BOOL WINAPI MiniDumpWriteDump(
      __in          HANDLE hProcess,
      __in          DWORD ProcessId,
      __in          HANDLE hFile,
      __in          MINIDUMP_TYPE DumpType,
      __in          PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
      __in          PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
      __in          PMINIDUMP_CALLBACK_INFORMATION CallbackParam
    );

    在我們的異常處理函數(shù)中加入以下代碼:

    HANDLE hFile = ::CreateFile( _T("E:\\dumpfile.dmp"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
     if( hFile != INVALID_HANDLE_VALUE)
     {
         MINIDUMP_EXCEPTION_INFORMATION einfo;
         einfo.ThreadId = ::GetCurrentThreadId();
         einfo.ExceptionPointers = pExInfo;
         einfo.ClientPointers = FALSE;

        ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpNormal, &einfo, NULL, NULL);
        ::CloseHandle(hFile);
     }

    其中,pExInfo變量為異常處理函數(shù)PEXCEPTION_POINTERS類型的參數(shù)。具體請(qǐng)參考MSDN

    3、調(diào)試minidump

    調(diào)試dump文件首先需要pdb文件,因此我們build程序時(shí)需要設(shè)置 Debug Infomation Format “Program Database/Zi。其次,我們還要確保所用的dump文件與源代碼、exepdb文件版本是一致的,這要求我們必須維護(hù)好程序版本信息。

    調(diào)試minidump最方便的環(huán)境就是VS了,我們只要將.dmp.exe.pdb文件放在一個(gè)路徑下,保證源代碼文件的路徑與編譯時(shí)的路徑一致就可以了,剩下的就是VS幫我們完成。雙擊.dmp文件或者在文件打開工程中選擇“dump files”,加載dump文件,然后按F5運(yùn)行就能直接恢復(fù)crash時(shí)的現(xiàn)場了,你可以定位crash的代碼,可以查看調(diào)用堆棧,可以查看線程和模塊信息...一切都跟你設(shè)置斷點(diǎn)調(diào)試一樣,太強(qiáng)大了!看個(gè)截圖吧。

clip_image012

    需要注意的是,對(duì)于release版的程序來說,很多代碼是經(jīng)過編譯器優(yōu)化過的,因此定位的時(shí)候可能會(huì)有所偏差,大家可以考慮設(shè)置選項(xiàng)去掉代碼優(yōu)化。

    其他可以調(diào)試minidump的工具還有WinDbg等,大家可以查閱相關(guān)資料。

    本文主要參考了這篇文章:http://vicchina.51.net/research/other/seh/minidumps/intro.htm

    下一篇,我們將給出一個(gè)調(diào)試release發(fā)布程序的完美解決方案,適合用戶量較大的應(yīng)用發(fā)布程序的調(diào)試。

上一篇我們已經(jīng)給出了方案,能夠非常方便的通過dump文件對(duì)crash錯(cuò)誤進(jìn)行調(diào)試和定位;從整個(gè)流程上看還差最后一步,即怎樣拿到crash時(shí)產(chǎn)生的dump文件。如果可以讓用戶把文件發(fā)送過來自然不錯(cuò),但對(duì)于類似免費(fèi)共享軟件等在互聯(lián)網(wǎng)上發(fā)布的程序呢?我們的用戶是不確定的,而且用戶量有可能非常大,即使我們能想辦法聯(lián)系到用戶,總不能挨個(gè)去收集crash信息吧。

    我們需要一種方案,能夠提供crash信息匯報(bào)功能。

    我們可以架設(shè)一臺(tái)服務(wù)器專門進(jìn)行信息收集,只要客戶端在crash時(shí)正確匯報(bào)即可,但是相應(yīng)的維護(hù)成本和開發(fā)難度也不可忽視。有沒有更簡單的方法呢?還記得我的博文為程序添加自動(dòng)發(fā)送Email功能嗎?這就是簡單有效的方法!

 

    方案六:minidump + email

    我們只需要在異常處理時(shí),先生成minidump信息文件,再用email方式將文件發(fā)送到指定郵箱就行了。剩下的就是我們每天查看郵箱,提取dump文件進(jìn)行調(diào)試了。

    1Email功能

    首先我們來看一下email發(fā)送都需要哪些相關(guān)信息。

    a、發(fā)送端郵箱帳戶;

    b、接收端郵箱帳戶;

    cemail標(biāo)題,一般應(yīng)有軟件名稱及版本信息;

    demail正文,一般應(yīng)有簡單的crash信息提示,以區(qū)別不同原因造成的crash

    eemail附件,當(dāng)然就是我們的dump文件了,還可以加上軟件生成的log文件等。

    當(dāng)然,對(duì)于標(biāo)題應(yīng)該盡量多加一些信息區(qū)別引起crash的原因,比如將crash的地址信息加到標(biāo)題中;因?yàn)楫?dāng)每天有成百上千的crash匯報(bào)上來,重復(fù)的crash占大多數(shù),把時(shí)間都花在區(qū)分它們身上有點(diǎn)太浪費(fèi)。由此看來,前面方案中提到的StackWalker還是有些用處的,我們可以用它來生成一些crash的文字描述信息,寫到標(biāo)題或正文中去。

    dump文件的大小是否適合作為郵件的附件呢?實(shí)際上minidump產(chǎn)生的文件一般在幾K到幾十K之間,作為email的附件沒有任何問題。

    關(guān)于發(fā)送email相關(guān)技術(shù)細(xì)節(jié),已經(jīng)在為程序添加自動(dòng)發(fā)送Email功能文中介紹了,大家可以參考。其實(shí),對(duì)接受郵箱中郵件的處理還是很費(fèi)時(shí)費(fèi)力的,大家可以考慮寫一些腳本將處理流程自動(dòng)化,提高效率。

    2google breakpad

    google breakpad是一個(gè)開源的跨平臺(tái)crash report系統(tǒng),光從開源和跨平臺(tái)這兩個(gè)特點(diǎn)上來看,它就足以稱的上是一個(gè)完善而有效的工具了。其實(shí),breakpad在整個(gè)crash report層次上給出了一個(gè)系統(tǒng)級(jí)的解決方案,也就是說它幾乎能適應(yīng)各種軟件、各種平臺(tái)的應(yīng)用要求。

    breakpad的整體思路跟上面介紹的方案是相似的,只不過最后提交dump文件的方式更加完善。大家有興趣可以去它的官方網(wǎng)址查閱相關(guān)資料:http://code.google.com/p/google-breakpad/

 

    ok,關(guān)于調(diào)試release發(fā)布程序的crash錯(cuò)誤系列文章就寫完了。這幾篇文章給出的方案由簡單到復(fù)雜,由簡陋到完善,對(duì)crash調(diào)試有了一個(gè)比較全面的總結(jié)。當(dāng)然,其中涉及到的概念和技術(shù)還很多,需要我們?nèi)ゲ粩鄬W(xué)習(xí)和領(lǐng)悟,也希望大家能夠互相交流。

 

posted on 2011-05-10 11:58 肥仔 閱讀(7743) 評(píng)論(1)  編輯 收藏 引用 所屬分類: 調(diào)試

評(píng)論

# re: 調(diào)試Release發(fā)布版程序的Crash錯(cuò)誤  回復(fù)  更多評(píng)論   

還沒試過,但應(yīng)該是篇很有用的文章。
2011-05-11 15:51 | K.V
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品久久久久久久久婷婷| 亚洲男女毛片无遮挡| 欧美国产精品专区| 欧美成人精品一区二区| 欧美成人精品一区| 欧美体内谢she精2性欧美| 欧美日韩一区视频| 国产欧美综合一区二区三区| 国内精品视频一区| 在线观看91精品国产入口| 最新国产乱人伦偷精品免费网站| 亚洲人成毛片在线播放| 亚洲视频1区| 噜噜噜躁狠狠躁狠狠精品视频| 久久激情综合网| 蘑菇福利视频一区播放| 国产精品盗摄久久久| 国产日韩欧美视频| 亚洲国产一二三| 亚洲影音先锋| 欧美大尺度在线观看| 日韩视频永久免费| 久久精品国产69国产精品亚洲| 久久综合狠狠| 国产精品第三页| 亚洲国产精品综合| 欧美在线二区| 亚洲人体偷拍| 亚洲欧美国产制服动漫| 免费久久精品视频| 国产网站欧美日韩免费精品在线观看| 伊人久久婷婷色综合98网| 亚洲一区免费网站| 亚洲国产成人精品女人久久久| 亚洲免费一区二区| 欧美日韩久久| 在线免费观看视频一区| 午夜精品久久久久久久99热浪潮| 欧美成人资源网| 香蕉国产精品偷在线观看不卡| 欧美黄色大片网站| 国产亚洲福利一区| 亚洲在线一区二区| 亚洲伦理一区| 欧美国产在线电影| 91久久精品美女高潮| 久久夜色精品国产| 亚洲欧美成人一区二区在线电影| 欧美精品免费在线| 亚洲大胆在线| 免费观看日韩av| 久久久久久久999| 国产一区自拍视频| 久久久999| 午夜精品久久久久久久白皮肤| 欧美精品在线观看播放| 亚洲老板91色精品久久| 欧美成人精品福利| 米奇777在线欧美播放| 影音先锋久久久| 免费成人高清| 麻豆成人在线| 亚洲日韩第九十九页| 亚洲国产va精品久久久不卡综合| 老鸭窝毛片一区二区三区| 樱桃成人精品视频在线播放| 欧美大片在线观看一区| 美脚丝袜一区二区三区在线观看| 亚洲福利在线视频| 欧美.www| 欧美激情综合色| 亚洲天堂av在线免费| 午夜伦理片一区| 在线一区二区日韩| 国产麻豆精品视频| 久久久久久久一区二区三区| 久久精品首页| 亚洲乱码精品一二三四区日韩在线| 亚洲国产欧美一区二区三区同亚洲 | 欧美一区二区视频在线| 国产在线精品一区二区夜色| 噜噜噜在线观看免费视频日韩 | 先锋影音国产一区| 国产亚洲午夜| 亚洲国产高清自拍| 国产精品久久久久久久久| 香蕉久久夜色精品国产| 久久九九全国免费精品观看| 亚洲欧洲一区二区三区在线观看| 亚洲精品美女免费| 国产日韩精品久久| 亚洲国产精品尤物yw在线观看| 欧美日韩1区| 久久精品夜夜夜夜久久| 男女激情久久| 久久9热精品视频| 欧美14一18处毛片| 欧美一区二区三区四区高清 | 亚洲午夜国产一区99re久久| 国产亚洲精品bv在线观看| 亚洲国产视频一区二区| 国产精品欧美一区二区三区奶水 | 亚洲国产成人高清精品| 国产精品免费aⅴ片在线观看| 欧美v日韩v国产v| 欧美日韩专区| 欧美1区3d| 国产精品一卡二卡| 亚洲精品国产无天堂网2021| 国产一区二区剧情av在线| 亚洲激情综合| 红杏aⅴ成人免费视频| 亚洲调教视频在线观看| 亚洲日本一区二区三区| 久久本道综合色狠狠五月| 亚洲私人影院| 欧美区视频在线观看| 美国十次成人| 国产视频欧美视频| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 久久天天躁狠狠躁夜夜av| 欧美三日本三级三级在线播放| 蜜桃久久av一区| 国产欧美在线观看一区| 亚洲视频 欧洲视频| 一本不卡影院| 欧美成人黄色小视频| 免费日韩av| 国精产品99永久一区一区| 一区二区三区精品国产| 日韩一区二区久久| 欧美国产激情| 亚洲电影免费在线观看| 精品av久久707| 久久精品99| 麻豆精品91| 精品二区久久| 久久青草久久| 欧美成人一区在线| 亚洲人人精品| 欧美激情一区三区| 亚洲日本在线观看| 一区二区三区 在线观看视| 欧美极品色图| 亚洲精一区二区三区| 一区二区三区四区五区精品视频 | 亚洲狠狠丁香婷婷综合久久久| 欧美一级二区| 久久综合久久久久88| 亚洲丶国产丶欧美一区二区三区| 久久婷婷综合激情| 欧美激情视频在线播放| 亚洲精品午夜精品| 欧美午夜寂寞影院| 亚洲欧美电影在线观看| 久久久无码精品亚洲日韩按摩| 国内一区二区在线视频观看| 久久久www成人免费精品| 欧美大片在线影院| 日韩一级成人av| 国产精品麻豆成人av电影艾秋| 午夜精品福利一区二区三区av| 久久精品视频免费播放| 亚洲高清视频一区二区| 欧美日韩一区二区在线观看视频| 亚洲性感美女99在线| 久久亚洲色图| 一本久久a久久精品亚洲| 国产伦精品一区二区三| 乱人伦精品视频在线观看| 99国产精品私拍| 久久一综合视频| 中日韩在线视频| 国语自产精品视频在线看8查询8| 免费成年人欧美视频| 亚洲夜晚福利在线观看| 欧美高清在线视频| 欧美一区二区视频97| 亚洲国产一区在线观看| 国产精品亚洲激情| 欧美韩日亚洲| 久久精品一区二区| 亚洲小说春色综合另类电影| 亚洲国产精品福利| 久久蜜桃精品| 亚洲欧美日本另类| 亚洲欧洲日本mm| 美女999久久久精品视频| 一区二区三区欧美视频| 欧美激情精品久久久久久变态 | 欧美高清在线观看| 久久福利影视| 在线综合亚洲| 亚洲欧洲精品天堂一级| 尤物网精品视频| 国内精品久久国产| 国产三级精品三级| 国产精品私房写真福利视频| 欧美伦理视频网站| 美女国产一区|