对于 Windows x64 系统,Microsoft 的StackWalk64函数来自dbghelp.h. 根据我的经验,它可靠地识别堆栈上的堆栈帧,因此可用于确定调用堆栈的深度。
唯一的问题是获取CONTEXT当前线程的有效值,因为根据文档, GetThreadContext不能用于当前线程。您可能必须先挂起线程;就我而言,图书馆正在为我做这件事,所以我不在这里包含代码。
给定一个有效的CONTEXT Context,设置必要的数据:
STACKFRAME64 StackFrame;
StackFrame.AddrPC.Offset = Context.Rip;
StackFrame.AddrPC.Mode = AddrModeFlat;
StackFrame.AddrFrame.Offset = Context.Rbp; // maybe .Rsp
StackFrame.AddrFrame.Mode = AddrModeFlat;
StackFrame.AddrStack.Offset = Context.Rsp;
StackFrame.AddrStack.Mode = AddrModeFlat;
// Arguments for StackWalk64
DWORD MachineType = IMAGE_FILE_MACHINE_AMD64;
HANDLE hProcess = GetCurrentProcess();
HANDLE hThread = GetCurrentThread();
LPSTACKFRAME64 pStackFrame = &StackFrame;
PVOID ContextRecord = &Context;
PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine = NULL;
PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine = SymFunctionTableAccess64;
PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine = SymGetModuleBase64;
PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress = NULL;
然后走茎:
int depth = 0;
while (StackWalk64(
MachineType,
hProcess,
hThread,
&StackFrame,
ContextRecord,
ReadMemoryRoutine,
FunctionTableAccessRoutine,
GetModuleBaseRoutine,
TranslateAddress)
)
{
++depth;
}