📄 debug.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 + -