Skip to content

Instantly share code, notes, and snippets.

@MzHmO
Created November 8, 2023 15:49
Show Gist options
  • Save MzHmO/bc3eb2dd4b3ea41d536d61f7636145dc to your computer and use it in GitHub Desktop.
Save MzHmO/bc3eb2dd4b3ea41d536d61f7636145dc to your computer and use it in GitHub Desktop.
#include <iostream>
#include <Windows.h>
#include <DbgHelp.h>
#pragma comment(lib, "Dbghelp.lib")

BOOL CALLBACK PrintStackFrame(PSYMBOL_INFO symbolInfo, ULONG symbolSize, PVOID context)
{
    std::cout << symbolInfo->Address << ": " << symbolInfo->Name << std::endl;
    return TRUE;
}
void print_stack_trace()
{
    SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
    HANDLE processHandle = GetCurrentProcess();
    SymInitialize(processHandle, NULL, TRUE);
    CONTEXT context;
    RtlCaptureContext(&context);
    STACKFRAME64 stackFrame;
    ZeroMemory(&stackFrame, sizeof(STACKFRAME64));
#ifdef _M_IX86 //x86
    DWORD machineType = IMAGE_FILE_MACHINE_I386;
    stackFrame.AddrPC.Offset = context.Eip;
    stackFrame.AddrPC.Mode = AddrModeFlat;
    stackFrame.AddrFrame.Offset = context.Ebp;
    stackFrame.AddrFrame.Mode = AddrModeFlat;
    stackFrame.AddrStack.Offset = context.Esp;
    stackFrame.AddrStack.Mode = AddrModeFlat;
#elif _M_X64 // Для архитектуры x64
    DWORD machineType = IMAGE_FILE_MACHINE_AMD64;
    stackFrame.AddrPC.Offset = context.Rip;
    stackFrame.AddrPC.Mode = AddrModeFlat;
    stackFrame.AddrFrame.Offset = context.Rsp;
    stackFrame.AddrFrame.Mode = AddrModeFlat;
    stackFrame.AddrStack.Offset = context.Rsp;
    stackFrame.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64 // Itanium
    DWORD machineType = IMAGE_FILE_MACHINE_IA64;
    stackFrame.AddrPC.Offset = context.StIIP;
    stackFrame.AddrPC.Mode = AddrModeFlat;
    stackFrame.AddrFrame.Offset = context.IntSp;
    stackFrame.AddrFrame.Mode = AddrModeFlat;
    stackFrame.AddrBStore.Offset = context.RsBSP;
    stackFrame.AddrBStore.Mode = AddrModeFlat;
    stackFrame.AddrStack.Offset = context.IntSp;
    stackFrame.AddrStack.Mode = AddrModeFlat;
#else
#error "unsupported"
#endif
    while (StackWalk64(machineType, processHandle, GetCurrentThread(), &stackFrame, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
    {
        DWORD64 symbolBuffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + sizeof(DWORD64) - 1) / sizeof(DWORD64)];
        PSYMBOL_INFO symbolInfo = (PSYMBOL_INFO)symbolBuffer;
        symbolInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
        symbolInfo->MaxNameLen = MAX_SYM_NAME;
        if (SymFromAddr(processHandle, stackFrame.AddrPC.Offset, NULL, symbolInfo))
        {
            PrintStackFrame(symbolInfo, 0, NULL);
        }
    }
    SymCleanup(processHandle);
}
int main()
{
    print_stack_trace();
    return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment