通过结构化异常定位崩溃程序
程序崩溃时,生成文本文件,记录崩溃得堆栈信息
直接上代码
已经编译通过,拷贝直接可用
.h
#include <Windows.h>
#include <stdarg.h>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#pragma once
#ifdef _WIN32
class CExceptionHandler
{
public:
static LONG WINAPI CleanExceptionFun(struct _EXCEPTION_POINTERS* pei);
private:
static void GetCurModulePath(TCHAR* ptcPath, int iLen, LPVOID addr);
//static void EI2Str(TCHAR* ptcInfo,int iInfoLen,ULONG_PTR* Info,int iCount);
static void EI2Str(char* ptcInfo, int iInfoLen, ULONG_PTR* Info, int iCount);
static void TcharToChar(const TCHAR * tchar, char * _char);
static void CharToTchar(const char * _char, TCHAR * tchar);
};
#else
#endif
.cpp
#include "stdafx.h"
#include "exceptionhandler.h"
#ifdef _WIN32
#include <DbgHelp.h>
#pragma comment(lib, "Dbghelp.lib")
#pragma warning(disable:4313)
void CExceptionHandler::GetCurModulePath(TCHAR* ptcPath, int iLen, LPVOID addr)
{
MEMORY_BASIC_INFORMATION mbi = { 0 };
if (FALSE == ::VirtualQuery(addr, &mbi, sizeof(mbi)))
return;
UINT_PTR h_module = (UINT_PTR)mbi.AllocationBase;
::GetModuleFileName((HMODULE)h_module, ptcPath, iLen);
return;
}
void CExceptionHandler::EI2Str(char* ptcInfo, int iInfoLen, ULONG_PTR* Info, int iCount)
{
int i = 0;
char* p1 = ptcInfo;
for (i = 0; i < iCount; i++)
{
sprintf(p1, "%08X ", Info[i]);
p1 += 9;
}
}
void CExceptionHandler::TcharToChar(const TCHAR * tchar, char * _char)
{
int iLength;
iLength = WideCharToMultiByte(CP_ACP, 0, tchar, -1, NULL, 0, NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, tchar, -1, _char, iLength, NULL, NULL);
}
void CExceptionHandler::CharToTchar(const char * _char, TCHAR * tchar)
{
int iLength;
iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, NULL, 0);
MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, tchar, iLength);
}
LONG WINAPI CExceptionHandler::CleanExceptionFun(struct _EXCEPTION_POINTERS* pei)
{
STACKFRAME sf;
CONTEXT context;
TCHAR tcPath[2048] = { 0 };
TCHAR tcInfo[10240] = { 0 };
TCHAR tcExcep[20480] = { 0 };
GetCurModulePath(tcPath, 2048, pei->ExceptionRecord->ExceptionAddress);
char szExcep[20480] = {};
char szInfo[10240] = {};
char szPath[2048] = {};
//TcharToChar(tcInfo, szInfo);
TcharToChar(tcPath, szPath);
EI2Str(szInfo, 10240, pei->ExceptionRecord->ExceptionInformation, pei->ExceptionRecord->NumberParameters);
sprintf(szExcep, "threadid: %u code: 0x%08X flag:0x%08X param:%d %s \nmoudle:%s \nstack:\n",
GetCurrentThread(),
pei->ExceptionRecord->ExceptionAddress,
pei->ExceptionRecord->ExceptionFlags,
pei->ExceptionRecord->ExceptionAddress,
pei->ExceptionRecord->NumberParameters, szInfo, szPath);
memset(tcInfo, 0, sizeof(tcInfo));
memset(&sf, 0, sizeof(STACKFRAME));
memcpy(&context, pei->ContextRecord, sizeof(CONTEXT));
sf.AddrPC.Offset = context.Eip;
sf.AddrPC.Mode = AddrModeFlat;
sf.AddrStack.Offset = context.Esp;
sf.AddrStack.Mode = AddrModeFlat;
sf.AddrFrame.Offset = context.Ebp;
sf.AddrFrame.Mode = AddrModeFlat;
DWORD machineType = IMAGE_FILE_MACHINE_I386;
HANDLE hProcess = GetCurrentProcess();
HANDLE hThread = GetCurrentThread();
SymInitialize(hProcess, NULL, TRUE);
for (; ; )
{
if (!StackWalk(machineType, hProcess, hThread, &sf, &context, 0, SymFunctionTableAccess, SymGetModuleBase, 0))
{
break;
}
if (sf.AddrFrame.Offset == 0)
{
break;
}
BYTE symbolBuffer[sizeof(SYMBOL_INFO) + 1024];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
pSymbol->SizeOfStruct = sizeof(symbolBuffer);
pSymbol->MaxNameLen = 1024;
sprintf(szPath, "Offset:0x%08X ", sf.AddrPC.Offset);
strcat(szExcep, szPath);
memset(tcPath, 0, sizeof(tcPath));
DWORD64 symDisplacement = 0;
if (SymFromAddr(hProcess, sf.AddrPC.Offset, 0, pSymbol))
{
sprintf(szPath, "%s ", pSymbol->Name);
}
else
{
sprintf(szPath, "%s ", "Unknown symbol");
}
strcat(szExcep, szPath);
IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
DWORD dwLineDisplacement;
memset(tcPath, 0, sizeof(tcPath));
if (SymGetLineFromAddr(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
{
sprintf(szPath, "[%s @ %u] ", lineInfo.FileName, lineInfo.LineNumber);
}
else
{
}
strcat(szExcep, szPath);
strcat(szExcep, "\n");
//break;
}
strcat(szExcep, "\n");
SymCleanup(hProcess);
FILE* fp = fopen("C:\\Users\\pc\\Desktop\\1.txt", "w");
if (NULL != fp)
{
fseek(fp, 0, SEEK_END);
fprintf(fp, "%s", szExcep);
fclose(fp);
fp = NULL;
}
TerminateProcess(GetCurrentProcess(), 0);
return EXCEPTION_EXECUTE_HANDLER;;
}
#else
#endif
以上代码可以正常执行
stdafx.h文件中无特殊头文件
main.cpp需要加上30、31这两行代码
#include "ExceptionHandler.h"
执行结果如下
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)