__try
{
int j = 0;
int i = 1 / j;
BYTE* pch;
pch = (BYTE*)00001234; //给予一个非法地址
*pch = 6; //对非法地址赋值,会造成Access Violation 异常
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
CString stackInfo;
if (LogUtil::GetTraceStack(&stackInfo) != NULL) {//获取堆栈信息
LOG(ERROR) << "程序发生了错误:" << stackInfo;//将堆栈信息存到文件
}
printf("stackInfo:%s \n",stackInfo);
}
- 修改配置:
这时候直接编译,可能会提示:error C2712: 无法在要求对象展开的函数中使用__try,我们需要修改配置 ,如图:

- LogUtil.h头文件
#pragma once
#include "stdafx.h"
class LogUtil
{
public:
static CString * GetTraceStack(CString *message);
};
#include "stdafx.h"
#include "LogUtil.h"
#include <windows.h>
#include <dbghelp.h>
#include <stdio.h>
#pragma comment(lib, "version.lib")
#pragma comment( lib, "dbghelp.lib" )
#include <exception>
#include <iostream>
#define STACK_INFO_LEN 1024
static const int MAX_STACK_FRAMES = 12;
CString * LogUtil::GetTraceStack(CString *message)
{
void *pStack[MAX_STACK_FRAMES];
static char szStackInfo[STACK_INFO_LEN * MAX_STACK_FRAMES];
static char szFrameInfo[STACK_INFO_LEN];
HANDLE process = GetCurrentProcess();
SymInitialize(process, NULL, TRUE);
typedef WORD(_stdcall *PFUNRtlCaptureStackBackTrace)(
DWORD FramesToSkip,
DWORD FramesToCapture,
PVOID* BackTrace,
PDWORD BackTraceHash
);
HMODULE hNt = LoadLibrary(_T("NtDll.dll"));
PFUNRtlCaptureStackBackTrace
pCaptureStackBackTrace = (PFUNRtlCaptureStackBackTrace)
GetProcAddress(hNt, ("RtlCaptureStackBackTrace"));
if (!pCaptureStackBackTrace)
{
return NULL;
}
WORD frames = pCaptureStackBackTrace(0, MAX_STACK_FRAMES, pStack, NULL);
TCHAR szBuffer[sizeof(SYMBOL_INFOW) + MAX_SYM_NAME * sizeof(TCHAR)];
DWORD64 dwAddress = 0;
DWORD64 dwDisplacement = 0;
PSYMBOL_INFOW pSymbol = NULL;
DWORD dwDisplacement2 = 0;
IMAGEHLP_LINEW64 ilLine;
for (WORD i = 0; i < frames; ++i) {
DWORD64 address = (DWORD64)(pStack[i]);
DWORD64 displacementSym = 0;
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
DWORD displacementLine = 0;
IMAGEHLP_LINE64 line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
if (SymFromAddr(process, address, &displacementSym, pSymbol) && SymGetLineFromAddr64(process, address, &displacementLine, &line))
{
snprintf(szFrameInfo, sizeof(szFrameInfo), "\t%s() at %s:%d(0x%x)\n", pSymbol->Name, line.FileName, line.LineNumber, pSymbol->Address);
strcat(szStackInfo, szFrameInfo);
}
else
{
}
}
message->Format(_T("%s"), szStackInfo);
FreeLibrary(hNt);
return message;
}