簡介:
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 調用堆棧的支持。
如果有任何改進建議,不妨來信告知,以便我將它們加到下下一個版本中。
本文配套源碼