程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 介紹一個專門處理C++異常的類

介紹一個專門處理C++異常的類

編輯:關於VC++

簡介:

CExceptionLogger,是一個可以免費使用的C++類,用它可以截獲未處理異常,如:非法存取、棧溢出、被零除等,並可以將異常詳細信息記錄到日志文件。這個類源自於MSDN Magazine 2002年3月的一篇專欄文章“Under the Hood: Improved Error Reporting with DBGHELP 5.1”,該文章的作者是 Matt Pietrek。

特性:

在默認情況下,CExceptionLogger產生一個日志文件,名字為:nameofexe.exception,這裡的nameofexe是exe文件的名字。如果以ASCII模式生成CExceptionLogger,則日志文件為一ASCII文件;如果以UNICODE模式生成CExceptionLogger,那麼日志文件為一UNICODE文件。日志文件記錄的信息包括:

記錄異常發生的日期和時間。

異常代碼。

如果發生非法存取,則記錄該異常的詳細信息。

記錄的異常詳細信息包括:線性地址、段、偏移量和模塊路徑。

進程的全路徑名。

當前Win32工作目錄。

進程的命令行。

進程ID。

發生異常的線程ID。

列舉進程中所有的線程(假設ToolHelp32是可獲得的),內容包括:

線程ID

優先級和Delta優先級

參考

創建時間

Kernel 和 User Time

列舉進程中的模塊(同樣假設ToolHelp32是可獲得的),內容包括:

名字和全路徑

全程及每個進程的引用計數

模塊句柄

大小

模塊完全展開後的所有符號

所有x86寄存器。

異常發生的調用堆棧,包括:段、偏移量、模塊、函數和行信息。

日志文件記錄的內容還包括每一個堆棧幀(stack frame)以及所有模塊、所有變量、所有參數;所有基本數據類型,如:voids, chars, shorts, words, ints, DWORDS, floats, doubles 和 longs。此外日志還記錄用戶定義的數據類型(UDT)包括結構、聯合以及類的信息,再現其成員數據。每種類型都包括名字、地址、類型和值。如果變量是一數組,該數組中的值被完全記錄。

版權聲明:

你可以在任何以二進制形式發布的產品(包括商業的、共享的、自由的或其它的)中包含此源代碼

在不修改每個模塊(*.h、*.cpp)最上方版權細則的前提下,你可以用任何方式修改源代碼

如果你想要與自己的應用程序一起分發源代碼,只允許分發作者最新發布的版本,以便保證源代碼的出處是唯一的

使用方法:

編譯這個類需要安裝2002年11月以後發布的平台SDK。使用時既可以將 ExceptHandler.cpp/h 文件直接添加到C++工程中,也可以用DLL輸出異常處理函數類,並用LoadLibrary函數在需要時動態加載DLL。

ExceptHandler的二進制版本在XCPTHLR.DLL中提供。此DLL可以從本文最上方鏈接處下載。

為了在客戶機器上運行該代碼,必須分發DBGHELP 5.1 動態鏈接庫,這個庫可以從2002年11月以後的平台SDK中獲得。選擇“Install Debugging Tools for Windows”選項安裝該DLL。此外,還要注意DBGHELP 動態鏈接庫在最新的 Windows 版本中是受到保護 Windows 系統文件,所以請將 DBGHELP 動態鏈接庫放在與應用程序相同的目錄中。

為了在release模式中給代碼提供符號,必須按照下列步驟修改工程設置:

1.Project Settings -> Link -> Debug (Category) , 啟用“Debug Info” 並選中“Microsoft Format”。

2.相同的地方,選中“Separate Types”。

3.在相同頁的“Project Options”編輯框中,添加“/OPT:REF”,這樣可以保證從最終的二進制中排除掉未引用的函數。

4.Project Settings -> C++ -> General (Category) Debug Info 組合框 -> 選擇“Program Database”

5.如果要對無意義的堆棧進行調用,那麼需將“Optimizations”設置為“Disable (Debug)”。

還要記住與代碼一起分發最終生成的pdb文件(或用其它方法使之可以得到)。以便CExceptionLogger能在最終的日志中給出源和行信息。

請注意由於所有的符號,即便是很小的應用的符號,各自的異常日志可能超過100K。我的觀點是磁盤空間不值錢,而開發人員為查找BUG所花的時間則很寶貴。

參考資料:Bugslayer, MSJ, August 1998 by John Robbins,
http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0898/bugslayer0898.htm
Under the Hood, MSDN, March 2002 by Matt Pietrek,
http://msdn.microsoft.com/msdnmag/issues/02/03/Hood/Hood0203.asp

改進計劃:

可配置日志文件名。

提供對Win64平台的支持。

提供對非x86 調用堆棧的支持。

如果有任何改進建議,不妨來信告知,以便我將它們加到下下一個版本中。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved