⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debug.cpp

📁 Debug.x:封装SEH 作用:在程序发生未处理的异常时
💻 CPP
字号:
// Debug.cpp: implementation of the CDebug class.
// Finished @ 2004-09-17. Last modified @ 2004-09-24
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Debug.h"
#include "Output.h"
#include <imagehlp.h>

#pragma comment (lib, "imagehlp")
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

LPTOP_LEVEL_EXCEPTION_FILTER CDebug::m_pPre = NULL;
char CDebug::m_pszFile[MAX_PATH];
LONG WINAPI CDebug::DebugInfo (EXCEPTION_POINTERS *pException)
{
	// 得到异常的信息
	PEXCEPTION_RECORD pExcp = pException->ExceptionRecord;
	while (NULL != pExcp) {
		DealExcep (pExcp);
		pExcp = pExcp->ExceptionRecord;
	}
	ImgStackWalk (pException->ContextRecord);
	if (m_pPre) {
		return m_pPre (pException);
	}
	return EXCEPTION_CONTINUE_SEARCH;
}

void CDebug::Free ()
{
	SetErrorMode (0);
	SetUnhandledExceptionFilter (m_pPre);
}

void CDebug::Start ()
{
	if (NULL == m_pPre) {
		SetErrorMode (SEM_NOGPFAULTERRORBOX);
		m_pPre = SetUnhandledExceptionFilter (DebugInfo);
	}
}

void CDebug::ToFile (char *pszFile)
{
	lstrcpyn (m_pszFile, pszFile, sizeof (m_pszFile));
}

void CDebug::DealExcep (PEXCEPTION_RECORD pExcp)
{
	char szbuf[3 * MAX_PATH], sztmp[MAX_PATH];
	memset (sztmp, 0x00, sizeof (sztmp));
	memset (szbuf, 0x00, sizeof (szbuf));
	switch (pExcp->ExceptionCode)
	{
	case STATUS_ACCESS_VIOLATION:
		sprintf (sztmp, "非法内存操作\t异常代码 = %8x", pExcp->ExceptionCode);
		break;
	case STATUS_STACK_OVERFLOW:
		sprintf (sztmp, "堆栈溢出\t异常代码 = %8x", pExcp->ExceptionCode);
		break;
	case STATUS_INTEGER_DIVIDE_BY_ZERO:
		sprintf (sztmp, "除数为0\t异常代码 = %8x", pExcp->ExceptionCode);
		break;
	default:
		sprintf (sztmp, "其它异常\t异常代码 = %8x", pExcp->ExceptionCode);
		break;
	}
	lstrcpy (szbuf, sztmp);
	sprintf (sztmp, "\texception address = %8x \tModule:", pExcp->ExceptionAddress);
	lstrcat (szbuf, sztmp);
	// 得到异常所在的module
	MEMORY_BASIC_INFORMATION mem;
	VirtualQuery (pExcp->ExceptionAddress, &mem, sizeof (MEMORY_BASIC_INFORMATION));
	GetModuleFileName ((HMODULE)mem.AllocationBase, sztmp, sizeof (sztmp));
	lstrcat (szbuf, sztmp);
	// 定位异常的偏移位置(相对地址)
	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)(mem.AllocationBase);
	PIMAGE_NT_HEADERS pNts = (PIMAGE_NT_HEADERS)((PBYTE)pDos + pDos->e_lfanew);
	PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION (pNts);
	// get relative virtual address
	DWORD dRva = (DWORD)pExcp->ExceptionAddress - (DWORD)mem.AllocationBase;
	// trips every section.
	for (WORD wCnt = 0; wCnt < pNts->FileHeader.NumberOfSections; ++wCnt) {
		DWORD dStart = pSection->VirtualAddress;
		DWORD dEnd = dStart + max (pSection->SizeOfRawData, pSection->Misc.VirtualSize);
		if (dRva >= dStart && dRva <= dEnd) {
			sprintf (sztmp, "\tSection name: %s - offset(rva) : %x", pSection->Name, dRva - dStart);
			lstrcat (szbuf, sztmp);
			break;
		}
		++pSection;
	}
	if (lstrlen (m_pszFile)) {
		COutput out (m_pszFile);
		out.WriteString (szbuf);
		out.NewLine ();
		out.NewLine ();
	} else {
		MessageBox (NULL, szbuf, "异常!", MB_OK);
	}
}

void CDebug::ImgStackWalk (PCONTEXT pCon)
{
	char szBuf[MAX_PATH * 2], sztmp[MAX_PATH];
	memset (szBuf, 0x00, sizeof (szBuf));
	// 先搞到模块名字
	MEMORY_BASIC_INFORMATION mem;
	VirtualQuery ((PVOID)pCon->Eip, &mem, sizeof (MEMORY_BASIC_INFORMATION));
	GetModuleFileName ((HMODULE)mem.AllocationBase, sztmp, sizeof (sztmp));
	lstrcpy (szBuf, sztmp);
	if (SymInitialize (GetCurrentProcess (), NULL, TRUE)) {
		STACKFRAME sf;
		memset (&sf, 0x00, sizeof (STACKFRAME));
		// Initialize the STACKFRAME structure for the first call.  This is only
		// necessary for Intel CPUs, and isn't mentioned in the documentation.
		sf.AddrPC.Offset       = pCon->Eip;
		sf.AddrPC.Mode         = AddrModeFlat;
		sf.AddrStack.Offset    = pCon->Esp;
		sf.AddrStack.Mode      = AddrModeFlat;
		sf.AddrFrame.Offset    = pCon->Ebp;
		sf.AddrFrame.Mode      = AddrModeFlat;
		while (true) {
			if (!StackWalk (IMAGE_FILE_MACHINE_I386,
				GetCurrentProcess (),
				GetCurrentThread (),
				&sf,
				pCon,
				NULL,
				SymFunctionTableAccess,
				SymGetModuleBase,
				NULL))
			{
				break;
			}
			if ( 0 == sf.AddrFrame.Offset ) {// Basic sanity check to make sure
				break;                      // the frame is OK.  Bail if not.
			}
			// make image buffer
			BYTE imgBuf[sizeof (IMAGEHLP_SYMBOL) + 512];
			PIMAGEHLP_SYMBOL pSymbol = reinterpret_cast <PIMAGEHLP_SYMBOL> (imgBuf);
			pSymbol->SizeOfStruct = sizeof (IMAGEHLP_SYMBOL);
			pSymbol->MaxNameLength = 512;
			DWORD dLen = 0;
			if (SymGetSymFromAddr (GetCurrentProcess (), sf.AddrPC.Offset,
				&dLen, pSymbol))
			{
				sprintf (sztmp, "\nname : %s - location: %x", pSymbol->Name, dLen);
				lstrcat (szBuf, sztmp);
			}
		}
		SymCleanup (GetCurrentProcess ());
	}
	if (lstrlen (m_pszFile) > 0) {
		COutput out (m_pszFile);
		out.WriteString (":::::::::: Trips of Stack ::::::::::\n");
		out.WriteString (szBuf);
		out.NewLine ();
		out.NewLine ();
	} else {
		MessageBox (NULL, szBuf, "Stacks Trip", MB_OK);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -