/// <summary> /// Reads the stack trace from context using StackWalkEx. /// </summary> /// <param name="thread">The thread.</param> /// <param name="contextAddress">The context address.</param> private StackTrace ReadStackTraceFromContext(Thread thread, IntPtr contextAddress) { List<_DEBUG_STACK_FRAME_EX> frames = new List<_DEBUG_STACK_FRAME_EX>(); List<ThreadContext> contexts = new List<ThreadContext>(); STACKFRAME_EX stackFrame = new STACKFRAME_EX(); while (true) { if (!StackWalkEx(thread.Process.ActualProcessorType, (IntPtr)thread.Process.SystemId, (IntPtr)thread.SystemId, ref stackFrame, contextAddress, ReadMemory, GetFunctionTableAccess, GetModuleBaseAddress, null, 0)) break; frames.Add(new _DEBUG_STACK_FRAME_EX() { FrameNumber = (uint)frames.Count, FrameOffset = stackFrame.AddrFrame.Offset, FuncTableEntry = (ulong)stackFrame.FuncTableEntry.ToInt64(), InlineFrameContext = stackFrame.InlineFrameContext, InstructionOffset = stackFrame.AddrPC.Offset, Params = null, Reserved = null, Reserved1 = 0, ReturnOffset = stackFrame.AddrReturn.Offset, StackOffset = stackFrame.AddrStack.Offset, Virtual = stackFrame.Virtual, }); contexts.Add(ThreadContext.PtrToStructure(thread.Process, contextAddress)); } return new StackTrace(thread, frames.ToArray(), contexts.ToArray()); }
private static extern bool StackWalkEx( ImageFileMachine MachineType, IntPtr hProcess, IntPtr hThread, ref STACKFRAME_EX StackFrame, IntPtr ContextRecord, ReadProcessMemoryProc64 ReadMemoryRoutine, FunctionTableAccessProc64 FunctionTableAccessRoutine, GetModuleBaseProc64 GetModuleBaseRoutine, TranslateAddressProc64 TranslateAddress, uint Flags);