#include <windows.h>
#include <dbghelp.h>
#include <iostream>
#include<iomanip>
#include<vector>
#pragma comment(lib, "dbghelp.lib")
bool
PrintCallStackBackTrace()
{
DWORD
options = SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES;
SymSetOptions(options);
CONTEXT context = { 0 };
RtlCaptureContext(&context);
STACKFRAME64 stack = { 0 };
stack.AddrPC.Offset = context.Eip;
stack.AddrPC.Mode = AddrModeFlat;
stack.AddrStack.Offset = context.Esp;
stack.AddrStack.Mode = AddrModeFlat;
stack.AddrFrame.Offset = context.Ebp;
stack.AddrFrame.Mode = AddrModeFlat;
std::vector<
DWORD_PTR
> backtrace;
std::string path =
R
"(SRV*D:\symbols*https://msdl.microsoft.com/download/symbols)"
;
BOOL
result = SymInitialize(GetCurrentProcess(), path.c_str(), TRUE);
if
(!result) {
DWORD
error = GetLastError();
std::cout <<
"SymInitialize returned error : "
<< error << std::endl;
}
while
(StackWalk64(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(),
GetCurrentThread(), &stack, &context, NULL,
SymFunctionTableAccess64, SymGetModuleBase64, NULL))
{
backtrace.push_back(stack.AddrPC.Offset);
}
for
(
DWORD
index = 0; index < backtrace.size(); index++)
{
DWORD_PTR
frame = backtrace[index];
const
int
kMaxNameLength = 256;
ULONG64
buffer[(
sizeof
(SYMBOL_INFO) + kMaxNameLength *
sizeof
(
wchar_t
) +
sizeof
(
ULONG64
) - 1) /
sizeof
(
ULONG64
)];
memset
(buffer, 0,
sizeof
(buffer));
DWORD64
sym_displacement = 0;
PSYMBOL_INFO symbol =
reinterpret_cast
<PSYMBOL_INFO>(&buffer[0]);
symbol->SizeOfStruct =
sizeof
(SYMBOL_INFO);
symbol->MaxNameLen = kMaxNameLength - 1;
BOOL
has_symbol =
SymFromAddr(GetCurrentProcess(), frame, &sym_displacement, symbol);
DWORD
line_displacement = 0;
IMAGEHLP_LINE64 line = {};
line.SizeOfStruct =
sizeof
(IMAGEHLP_LINE64);
BOOL
has_line = SymGetLineFromAddr64(GetCurrentProcess(), frame,
&line_displacement, &line);
std::cout <<
"0x"
<< std::left << std::hex << std::setw(12) << frame;
if
(has_symbol) {
std::cout <<std::setw(5)<< symbol->Name <<
"\t"
;
}
std::cout << std::endl;
}
result = SymCleanup(GetCurrentProcess());
return
true
;
}
void
f()
{
PrintCallStackBackTrace();
}
int
main()
{
f();
system
(
"pause"
);
return
0;
}