直接上代码吧:
#include <DbgHelp.h>
#pragma comment(lib,"Dbghelp.lib")
void ShowTraceStack( )
{
enum
{
MAX_STACK_FRAMES = 16
};
void* arrBackTrace[MAX_STACK_FRAMES] = { 0 };
CString strStackInfo = _T("calling stack-trace:\n");
HANDLE hProcess = GetCurrentProcess();
SymInitialize(hProcess, NULL, TRUE);
typedef USHORT (*PFUNRtlCaptureStackBackTrace)(
ULONG FramesToSkip,
ULONG FramesToCapture,
PVOID* BackTrace,
PULONG BackTraceHash
);
HMODULE hNt = LoadLibrary(_T("NtDll.dll"));
PFUNRtlCaptureStackBackTrace
pCaptureStackBackTrace =(PFUNRtlCaptureStackBackTrace)
GetProcAddress(hNt, ("RtlCaptureStackBackTrace") );
if (!pCaptureStackBackTrace)
{
xxGlobal::LogEvent(LOG_LEVEL_INFO, _T("RtlCaptureStackBackTrace load failed") );
return;
}
WORD wFrames = pCaptureStackBackTrace(0, MAX_STACK_FRAMES, arrBackTrace, NULL);
xxGlobal::LogEvent(LOG_LEVEL_INFO, strStackInfo);
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 wIndex = 0; wIndex < wFrames; ++wIndex)
{
dwAddress = (DWORD64)(arrBackTrace[wIndex]);
dwDisplacement = 0;
pSymbol = (PSYMBOL_INFOW)szBuffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
pSymbol->MaxNameLen = MAX_SYM_NAME;
dwDisplacement2 = 0;
ilLine.SizeOfStruct = sizeof(IMAGEHLP_LINEW64);
if (TRUE == SymFromAddrW(hProcess, dwAddress, &dwDisplacement, pSymbol) &&
TRUE == SymGetLineFromAddrW64(hProcess, dwAddress, &dwDisplacement2, &ilLine))
{
strStackInfo.Format( _T("\t%s() at %s:%d(0x%x)\n"),
pSymbol->Name,
ilLine.FileName, ilLine.LineNumber, pSymbol->Address );
}
else
{
strStackInfo.Format( _T("\tquery error: %d\n"), GetLastError());
}
xxGlobal::LogEvent(LOG_LEVEL_INFO, strStackInfo);
}
FreeLibrary(hNt);
}