Windows C++ 函数调用堆栈获取 - 32位系统示例
#include <Windows.h>
#include
// 函数堆栈调用情况的回调函数 BOOL CALLBACK StackWalkCallback( In PVOID pStackFrame, In PVOID pContext ) { PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)malloc(sizeof(IMAGEHLP_SYMBOL) + 256); pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); pSymbol->MaxNameLength = 255;
DWORD64 dw64Displacement = 0;
if (SymGetSymFromAddr(GetCurrentProcess(), (DWORD64)pStackFrame, &dw64Displacement, pSymbol))
{
std::cout << pSymbol->Name << std::endl;
}
free(pSymbol);
return TRUE;
}
void PrintCallStack() { // 初始化符号引擎 SymInitialize(GetCurrentProcess(), NULL, TRUE);
// 获取当前线程的堆栈帧
CONTEXT context;
RtlCaptureContext(&context);
STACKFRAME64 stackFrame;
memset(&stackFrame, 0, sizeof(STACKFRAME64));
DWORD machineType;
#ifdef _M_IX86 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 machineType = IMAGE_FILE_MACHINE_AMD64; stackFrame.AddrPC.Offset = context.Rip; stackFrame.AddrPC.Mode = AddrModeFlat; stackFrame.AddrFrame.Offset = context.Rbp; stackFrame.AddrFrame.Mode = AddrModeFlat; stackFrame.AddrStack.Offset = context.Rsp; stackFrame.AddrStack.Mode = AddrModeFlat; #elif _M_IA64 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 architecture" #endif
// 遍历堆栈帧并输出函数名
while (StackWalk64(machineType, GetCurrentProcess(), GetCurrentThread(),
&stackFrame, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
{
StackWalkCallback((PVOID)stackFrame.AddrPC.Offset, NULL);
}
// 清理符号引擎
SymCleanup(GetCurrentProcess());
}
int main() { PrintCallStack();
return 0;
}
原文地址: https://www.cveoy.top/t/topic/pd4Q 著作权归作者所有。请勿转载和采集!