SEH转化为C++异常<二>

//==============================================================================
//
// 项目名 :
// 文件名 :XDBExceptionReport.h
// 作  者 :
// 用  途 :异常报告实现类。
// 
//==============================================================================
// 版本记录	
//==============================================================================
//
// V0.1	 2005-5-19 9:30:47
// V0.9	 2005-6-20 8:54:02 RC1
//
//==============================================================================
#ifndef __XDBEXCEPTIONREPORT__H__INCLUDED__
#define __XDBEXCEPTIONREPORT__H__INCLUDED__
//==============================================================================

//=============================================================
// 如果需要使用DBGHELP的Unicode版(要求DBGHELP 6.3以上),让下行生效
//=============================================================
// #define DBGHELP_TRANSLATE_TCHAR

//=============================================================
// 如果需要打印输出全局变量的信息,让下行生效
//=============================================================
// #define DBGHELP_PRINTOUT_GLOBAL

//=============================================================
// 必须的头文件
//=============================================================
#include <OAIdl.h>					// VARIANT类型
#include <DbgHelp.h>				// DBGHELP库

/// <summary> 
/// 基本数据类型。
/// </summary> 
/// <remarks>
/// 来源于DIA2.0 SDK的CVConst.h文件。
/// </remarks>
enum BasicType
{
    btNoType	= 0,	/// 没有指定类型
    btVoid		= 1,	/// void类型
    btChar		= 2,	/// ANSI字符
    btWChar		= 3,	/// UNICODE字符
    btInt		= 6,	/// 有符号整数
    btUInt		= 7,	/// 无符号整数
    btFloat		= 8,	/// 浮点数
    btBCD		= 9,	/// BCD类型
    btBool		= 10,	/// 布尔值
    btLong		= 13,	/// 有符号长整数
    btULong		= 14,	/// 无符号长整数
    btCurrency	= 25,	/// 货币类型
    btDate		= 26,	/// 日期类型
    btVariant	= 27,	/// 可变数据类型
    btComplex	= 28,	/// 复数
    btBit		= 29,	/// 二进制
    btBSTR		= 30,	/// 字符串
    btHresult	= 31	/// HRESULT
};

/// <summary> 
/// 基本符号类型。
/// </summary> 
/// <remarks>
/// 来源于DIA2.0 SDK的CVConst.h文件。
/// </remarks>
enum SymTagType
{
	SymTagNull,						// 00:没有类型
	SymTagExe,						// 01:EXE文件
	SymTagCompiland,				// 02:对于本地程序,对应于0BJ文件;对于MSIL,情况会有不同
	SymTagCompilandDetails,			// 03:符号包含扩展的Compiland模块属性
	SymTagCompilandEnv,				// 04:符号是Compiland的环境字符串
	SymTagFunction,					// 05:函数
	SymTagBlock,					// 06:嵌套块
	SymTagData,						// 07:数据
	SymTagAnnotation,				// 08:代码注释
	SymTagLabel,					// 09:标号
	SymTagPublicSymbol,				// 10:公共(导出)符号
	SymTagUDT,						// 11:自定义类型
	SymTagEnum,						// 12:枚举
	SymTagFunctionType,				// 13:函数签名
	SymTagPointerType,				// 14:指针
	SymTagArrayType,				// 15:数组
	SymTagBaseType,					// 16:基本类型
	SymTagTypedef,					// 17:类型重定义(类型别名)
	SymTagBaseClass,				// 18:自定义类型的基类
	SymTagFriend,					// 19:自定义类型的友元
	SymTagFunctionArgType,			// 20:函数参数
	SymTagFuncDebugStart,			// 21:函数序幕代码的结束位置
	SymTagFuncDebugEnd,				// 22:函数结尾代码的开始位置
	SymTagUsingNamespace,			// 23:命名空间的名字	
	SymTagVTableShape,				// 24:虚表描述
	SymTagVTable,					// 25:虚表指针
	SymTagCustom,					// 26:未解释的定制类型
	SymTagThunk,					// 27:THUNK
	SymTagCustomType,				// 28:定制编译器类型
	SymTagManagedType,				// 29:元数据
	SymTagDimension,				// 30:FORTRAN多维数组
	SymTagMax						// 31:符号类型的种类数目
};


/// <summary> 
/// 异常报告实现类。
/// </summary> 
class XDBExceptionReport
{
public:

	/// <summary> 
	/// 构造函数。
	/// </summary> 
	XDBExceptionReport( );

	/// <summary> 
	/// 析构函数。
	/// </summary> 
    ~XDBExceptionReport( );
    
	/// <summary> 
	///		设置异常报告输出文件的路径。
	/// </summary> 
	/// <param name="pszReportFileName">
	///		文件路径。
	/// </param>
	static void SetReportFileName( LPWSTR pszReportFileName );

	/// <summary> 
	///		获得异常报告输出文件的路径。
	/// </summary> 
	/// <returns>
	///     返回文件路径。
	/// </returns>
	static WCHAR* GetReportFileName( );

	/// <summary> 
	///		未处理异常入口函数。	
	/// </summary> 
	/// <param name="pExceptionInfo">
	///		异常信息。
	/// </param>
	/// <returns>
	///		返回值为EXCEPTION_CONTINUE_SEARCH或EXCEPTION_EXECUTE_HANDLER。
	/// </returns>
	static LONG WINAPI XDBUnhandledExceptionFilter(
				PEXCEPTION_POINTERS pExceptionInfo );
	

	/// <summary> 
	///		异常过滤函数。
	/// </summary> 
	/// <param name="pszReportFileName">
	///		异常报告输出的文件路径。
	/// </param>
	/// <param name="pExceptionInfo">
	///		异常信息。
	/// </param>
	/// <param name="bWriteVariables">
	///		是否输出参数信息。
	/// </param>
	/// <returns>
	///		返回值为EXCEPTION_EXECUTE_HANDLER。
	/// </returns>
	static LONG WINAPI XDBHandledExceptionFilter(
				LPCWSTR				pszReportFileName,
				PEXCEPTION_POINTERS pExceptionInfo,
				bool				bWriteVariables = false );

private:

	/// <summary> 
	///		生成异常报告。
	/// </summary> 
	/// <param name="pReportFile">
	///		异常报告输出的文件句柄。
	/// </param>
	/// <param name="pExceptionInfo">
	///		异常信息。
	/// </param>
	/// <param name="bWriteVariables">
	///		是否输出参数信息。
	/// </param>
	static void GenerateExceptionReport( 
		HANDLE				pReportFile,
		PEXCEPTION_POINTERS pExceptionInfo,
		bool				bWriteVariables);

    /// <summary> 
	///		当文件尺寸过大时,收缩异常报告输出文件。
	/// </summary> 
	/// <param name="pReportFile">
	///		异常报告输出文件句柄。
	/// </param>
	/// <param name="pszReportFileName">
	///		异常报告输出文件路径。
	/// </param>
	/// <returns>
	///		指明操作是否成功。
	/// </returns>
	static BOOL ShrinkReportFile( 
			HANDLE&	pReportFile,
			LPCWSTR	pszReportFileName );


	/// <summary> 
	///		获得文件版本信息。
	/// </summary> 
	/// <param name="lpszFileName">
	///		文件名。
	/// </param>
	/// <param name="lpszVersionName">
	///		要获取的版本信息。
	/// </param>
	/// <param name="lpszVersion">
	///		用于返回版本信息,必须具有足够的空间。
	/// </param>
	/// <returns>
	///		是否成功。
	/// </returns>
	static BOOL GetFileVersion( 
		LPCWSTR lpszFileName, 
		LPCWSTR lpszVersionName, 
		LPWSTR	lpszVersion );

	/// <summary> 
	///		获得运行程序的版本信息。
	/// </summary> 
	/// <param name="szBuffer">
	///		用于保存信息的缓冲区(必须足够大)。
	/// </param>
	/// <returns>
	///		返回程序信息。
	/// </returns>
	static WCHAR* GetApplicationInfo(  WCHAR* szBuffer,size_t szLength );


 	/// <summary> 
	///		获得异常代码的字符串描述。
	/// </summary> 
	/// <param name="dwCode">
	///		异常代码。
	/// </param>
	/// <returns>
	///		异常代码的字符串描述。
	/// </returns>
	static WCHAR* GetExceptionString( DWORD dwCode );


	/// <summary> 
	///		获得引起异常的地址信息。
	/// </summary> 
	/// <param name="addr">
	///		地址信息。
	/// </param>
	/// <param name="szModule">
	///		用于保存模块名的缓冲。
	/// </param>
	/// <param name="len">
	///		缓冲区大小。
	/// </param>
	/// <param name="section">
	///		地址所位于的节。
	/// </param>
	/// <param name="offset">
	///		地址偏移。
	/// </param>
	/// <returns>
	///		成功返回TRUE,否则返回FALSE。
	/// </returns>
	static BOOL GetLogicalAddress(
			PVOID addr, PWSTR szModule, DWORD len,
            DWORD_PTR& section, DWORD_PTR& offset );

	/// <summary> 
	///		输出调用堆栈信息。
	/// </summary> 
	/// <param name="pReportFile">
	///		异常报告输出的文件句柄。
	/// </param>
	/// <param name="pContext">
	///		上下文环境句柄。
	/// </param>
	/// <param name="bWriteVariables">
	///		是否输出参数信息。
	/// </param>
	static void WriteStackDetails( 
		HANDLE	 pReportFile,
		PCONTEXT pContext, 
		bool	bWriteVariables );

	/// <summary> 
	///		枚举符号信息的回调函数。
	/// </summary> 
	/// <param name="pSymInfo">
	///		符号信息。
	/// </param>
	/// <param name="SymbolSize">
	///		符号尺寸。
	/// </param>
	/// <param name="UserContext">
	///		用户参数。
	/// </param>
	/// <returns>
	///		返回TRUE时,继续枚举;否则,终止枚举过程。
	/// </returns>
	static BOOL CALLBACK EnumerateSymbolsCallback(
		PSYMBOL_INFO  pSymInfo,
		ULONG         SymbolSize,
		PVOID         UserContext );

	/// <summary> 
	///		格式化符号值。
	/// </summary> 
	/// <param name="pSym">
	///		符号信息。
	/// </param>
	/// <param name="sf">
	///		堆栈帧。
	/// </param>
	/// <param name="pReportFile">
	///		异常报告输出的文件句柄。
	/// </param>
	/// <returns>
	///		成功或失败。
	/// </returns>
	static bool FormatSymbolValue( 
		PSYMBOL_INFO	pSym,
		LPSTACKFRAME64	sf,
		HANDLE			pReportFile );
		

	/// <summary> 
	///		输出类型信息。
	/// </summary> 
	/// <param name="pReportFile">
	///		异常报告输出的文件句柄。
	/// </param>
	/// <param name="modBase">
	///		模块基址。
	/// </param>
	/// <param name="dwTypeIndex">
	///		类型索引。
	/// </param>
	/// <param name="nestingLevel">
	///		嵌套层次。
	/// </param>
	/// <param name="offset">
	///		偏移。
	/// </param>
	/// <returns>
	///		成功或失败标志。
	/// </returns>
	static bool DumpTypeIndex( 
		HANDLE		pReportFile,
		DWORD64		modBase,
		DWORD		dwTypeIndex,
		unsigned	nestingLevel,
		DWORD_PTR	offset);

	/// <summary> 
	///		 输出类型的属性信息。
	/// </summary> 
	/// <param name="pReportFile">
	///		 异常报告输出的文件句柄。
	/// </param>
	/// <param name="modBase">
	///		 模块基址。
	/// </param>
	/// <param name="dwTypeIndex">
	///		  类型索引。
	/// </param>
	/// <param name="dwOffset">
	///		  变量地址。
	/// </param>
	static void DumpTypeInfo(
		HANDLE		pReportFile,
		DWORD64		modBase,
		DWORD		dwTypeIndex ,
		DWORD_PTR	dwOffset );

	/// <summary> 
	///		输出符号信息。	
	/// </summary> 
	/// <param name="pReportFile">
	///		异常报告输出的文件句柄。
	/// </param>
	/// <param name="pSymInfo">
	///		符号信息结构。
	/// </param>
	static void DumpSymbolInfo(
		HANDLE			pReportFile,
		PSYMBOL_INFO	pSymInfo );

	/// <summary> 
	///		获得基本类型的字符串描述。
	/// </summary> 
	/// <param name="dwBasicType">
	///		基本类型。
	/// </param>
	/// <returns>
	///		基本类型的字符串表示。
	/// </returns>
	static WCHAR* GetBasicTypeString( 
		DWORD			dwBasicType );

	/// <summary> 
	///		获得符号类型的字符串描述。
	/// </summary> 
	/// <param name="dwSymbolTag">
	///		符号类型。
	/// </param>
	/// <returns>
	///		符号类型的字符串描述。
	/// </returns>
	static WCHAR* GetSymbolTagString(
		DWORD			dwSymbolTag );

	/// <summary> 
	///		格式化参数值。
	/// </summary> 
	/// <param name="pReportFile">
	///		异常报告输出的文件句柄。
	/// </param>
	/// <param name="basicType">
	///		参数类型。
	/// </param>
	/// <param name="length">
	///		值长度。
	/// </param>
	/// <param name="pAddress">
	///		值地址。
	/// </param>
	static void FormatOutputValue( 
			HANDLE		pReportFile,
			DWORD		basicType, 
			DWORD64		length, 
			PVOID		pAddress );

	/// <summary> 
	///		格式化指针参数值。
	/// </summary> 
	/// <param name="pReportFile">
	///		异常报告输出的文件句柄。
	/// </param>
	/// <param name="basicType">
	///		参数类型。
	/// </param>
	/// <param name="length">
	///		值长度。
	/// </param>
	/// <param name="pAddress">
	///		值地址。
	/// </param>
	static void FormatPointerValue( 
		HANDLE		pReportFile,
		DWORD		basicType, 
		DWORD64		length, 
		PVOID		pAddress );

	/// <summary> 
	///		输出可变类型的数据。
	/// </summary> 
	/// <param name="pReportFile">
	///		异常报告输出的文件句柄。
	/// </param>
	/// <param name="pVal">
	///		待输出数值。
	/// </param>
	static void FormatVariantValue(
			HANDLE			pReportFile,
			const VARIANT*	pVal );
    
	

	/// <summary> 
	///		输出信息到文件。
	/// </summary> 
	/// <param name="pReportFile">
	///		文件句柄。
	/// </param>
	/// <param name="format">
	///		格式化字符串。
	/// </param>
	/// <returns>
	///		写入的字符个数。
	/// </returns>
    static int __cdecl PrintOut( 
		HANDLE		  pReportFile,
		const WCHAR * format, ...);

  	//==============================================================================
	// 静态成员变量
	//==============================================================================

	///  异常报告输出文件路径
    static WCHAR m_szReportFileName[MAX_PATH];

	/// 异常过滤函数指针
    static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter;

	/// 异常报告输出文件句柄
    static HANDLE m_hReportFile;

	/// 进程句柄
    static HANDLE m_hProcess;

	// 并发控制(DBGHELP库不能被多个线程同时访问)
	static CRITICAL_SECTION m_csDbgHelp;
};

//==============================================================================
#endif // __XDBEXCEPTIONREPORT__H__INCLUDED__
//==============================================================================

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值