public DEBUG_STACK_FRAME_EX(DEBUG_STACK_FRAME dsf) { InstructionOffset = dsf.InstructionOffset; ReturnOffset = dsf.ReturnOffset; FrameOffset = dsf.FrameOffset; StackOffset = dsf.StackOffset; FuncTableEntry = dsf.FuncTableEntry; fixed(UInt64 *pParams = Params) { for (int i = 0; i < 4; ++i) { pParams[i] = dsf.Params[i]; } } fixed(UInt64 *pReserved = Reserved) { for (int i = 0; i < 6; ++i) { pReserved[i] = dsf.Reserved[i]; } } Virtual = dsf.Virtual; FrameNumber = dsf.FrameNumber; InlineFrameContext = 0xFFFFFFFF; Reserved1 = 0; }
public UnifiedStackFrame(DEBUG_STACK_FRAME nativeFrame, IDebugSymbols2 debugSymbols) { FrameOffset = nativeFrame.FrameOffset; Type = UnifiedStackFrameType.Native; InstructionPointer = nativeFrame.InstructionOffset; StackPointer = nativeFrame.StackOffset; uint moduleIndex; ulong dummy; if (0 != debugSymbols.GetModuleByOffset(InstructionPointer, 0, out moduleIndex, out dummy)) { //Some frames might not have modules associated with them, in which case this //will fail, and of course there is no function associated either. This happens //often with CLR JIT-compiled code. Module = "<Unknown>"; Method = "<Unknown>"; return; } StringBuilder methodName = new StringBuilder(1024); ulong displacement; uint dummy2; Util.VerifyHr(debugSymbols.GetNameByOffset(InstructionPointer, methodName, methodName.Capacity, out dummy2, out displacement)); string[] parts = methodName.ToString().Split('!'); Module = parts[0]; if (parts.Length > 1) { Method = parts[1]; } OffsetInMethod = displacement; uint sourceLine; ulong delta; StringBuilder sourceFile = new StringBuilder(1024); if (0 == debugSymbols.GetLineByOffset(InstructionPointer, out sourceLine, sourceFile, sourceFile.Capacity, out dummy2, out delta)) { SourceFileName = sourceFile.ToString(); SourceLineNumber = sourceLine; SourceLineNumberEnd = sourceLine; } }
public DEBUG_STACK_FRAME_EX(DEBUG_STACK_FRAME dsf) { InstructionOffset = dsf.InstructionOffset; ReturnOffset = dsf.ReturnOffset; FrameOffset = dsf.FrameOffset; StackOffset = dsf.StackOffset; FuncTableEntry = dsf.FuncTableEntry; fixed (UInt64* pParams = Params) { for (int i = 0; i < 4; ++i) pParams[i] = dsf.Params[i]; } fixed (UInt64* pReserved = Reserved) { for (int i = 0; i < 6; ++i) pReserved[i] = dsf.Reserved[i]; } Virtual = dsf.Virtual; FrameNumber = dsf.FrameNumber; InlineFrameContext = 0xFFFFFFFF; Reserved1 = 0; }
private IList<StackFrame> GetNativeStackTrace(uint threadId) { var debugControl = (IDebugControl) _target.DebuggerInterface; var symbols = (IDebugSymbols) _target.DebuggerInterface; var systemObjects = (IDebugSystemObjects) _target.DebuggerInterface; const int framesSize = 1024; uint framesFilled; var frames = new DEBUG_STACK_FRAME[framesSize]; uint engineThreadId; systemObjects.GetThreadIdBySystemId(threadId, out engineThreadId); systemObjects.SetCurrentThreadId(engineThreadId); debugControl.GetStackTrace(0, 0, 0, frames, framesSize, out framesFilled); var stackTrace = new List<StackFrame>(); foreach (DEBUG_STACK_FRAME f in frames.Take((int) framesFilled)) { const int nameBufferSize = 1024; var nameBuffer = new StringBuilder(nameBufferSize); uint nameSize; ulong displacement; if (0 != symbols.GetNameByOffset(f.InstructionOffset, nameBuffer, nameBufferSize, out nameSize, out displacement)) { nameBuffer = new StringBuilder("N/A"); } string[] parts = nameBuffer.ToString().Split('!'); string methodName = parts[0]; string moduleName = "N/A"; if (parts.Length > 1) { moduleName = parts[0]; methodName = parts[1]; } stackTrace.Add(new StackFrame { Type = StackFrameType.Native, InstructionPointer = f.InstructionOffset, StackPointer = f.StackOffset, MethodName = methodName, ModuleName = moduleName, MethodOffset = displacement }); } return stackTrace; }
private List<UnifiedStackFrame> GetNativeStackTrace(uint? engineThreadId, CONTEXT? context) { if (engineThreadId.HasValue) Util.VerifyHr(((IDebugSystemObjects)_debugClient).SetCurrentThreadId(engineThreadId.Value)); DEBUG_STACK_FRAME[] stackFrames = new DEBUG_STACK_FRAME[200]; uint framesFilled; if (context.HasValue) { int ctxSize = Marshal.SizeOf(context); IntPtr ctxPtr = Marshal.AllocHGlobal(ctxSize); IntPtr frameCtxsPtr = Marshal.AllocHGlobal(ctxSize * stackFrames.Length); try { Marshal.StructureToPtr(context, ctxPtr, false); Util.VerifyHr(((IDebugControl4)_debugClient).GetContextStackTrace( ctxPtr, (uint)ctxSize, stackFrames, stackFrames.Length, frameCtxsPtr, (uint)(stackFrames.Length * ctxSize), (uint)ctxSize, out framesFilled)); } finally { Marshal.FreeHGlobal(ctxPtr); Marshal.FreeHGlobal(frameCtxsPtr); } } else { Util.VerifyHr(((IDebugControl)_debugClient).GetStackTrace( 0, 0, 0, stackFrames, stackFrames.Length, out framesFilled)); } List<UnifiedStackFrame> stackTrace = new List<UnifiedStackFrame>(); for (uint i = 0; i < framesFilled; ++i) { stackTrace.Add(new UnifiedStackFrame(stackFrames[i], (IDebugSymbols2)_debugClient)); } return stackTrace; }
private unsafe List<UnifiedStackFrame> GetNativeStackTrace(ThreadInfo info) { Util.VerifyHr(((IDebugSystemObjects)_debugClient).SetCurrentThreadId(info.EngineThreadId)); DEBUG_STACK_FRAME[] stackFrames = new DEBUG_STACK_FRAME[400]; uint framesFilled; Util.VerifyHr(((IDebugControl)_debugClient).GetStackTrace(0, 0, 0, stackFrames, Marshal.SizeOf<DEBUG_STACK_FRAME>(), out framesFilled)); var stackTrace = _processQuerierStrategy.ConvertToUnified(stackFrames.Take((int)framesFilled), _runtime, info, _pid); return stackTrace; }
private static void ShowStackTrace(int processId, uint attachTimeout, string outputPath) { if (processId == -1) throw new InvalidOperationException("Uinitialized process id parameter"); var threadInfoList = new List<ThreadInfo>(); using (DataTarget dataTarget = DataTarget.AttachToProcess(processId, attachTimeout)) { var dacLocation = dataTarget.ClrVersions[0].TryGetDacLocation(); var runtime = dataTarget.CreateRuntime(dacLocation); var control = (IDebugControl)dataTarget.DebuggerInterface; var sysObjs = (IDebugSystemObjects)dataTarget.DebuggerInterface; var nativeFrames = new DEBUG_STACK_FRAME[100]; var sybSymbols = (IDebugSymbols)dataTarget.DebuggerInterface; var sb = new StringBuilder(1024 * 1024); foreach (ClrThread thread in runtime.Threads) { var threadInfo = new ThreadInfo { OSThreadId = thread.OSThreadId }; if (thread.StackTrace.Count > 0) { foreach (ClrStackFrame frame in thread.StackTrace) { if (frame.DisplayString.Equals("GCFrame") || frame.DisplayString.Equals("DebuggerU2MCatchHandlerFrame")) continue; threadInfo.StackTrace.Add(frame.DisplayString); } } else { threadInfo.IsNative = true; sysObjs.SetCurrentThreadId(threadInfo.OSThreadId); uint frameCount; control.GetStackTrace(0, 0, 0, nativeFrames, 100, out frameCount); for (int i = 0; i < frameCount; i++) { uint nameSize; ulong dis; sb.Clear(); sybSymbols.GetNameByOffset(nativeFrames[i].InstructionOffset, sb, sb.Capacity, out nameSize, out dis); threadInfo.StackTrace.Add(sb.ToString()); } } threadInfoList.Add(threadInfo); } } var mergedStackTraces = new List<StackInfo>(); foreach (var threadInfo in threadInfoList) { bool merged = false; foreach (var mergedStack in mergedStackTraces) { if (threadInfo.IsNative != mergedStack.NativeThreads) continue; if (threadInfo.StackTrace.SequenceEqual(mergedStack.StackTrace, StringComparer.InvariantCultureIgnoreCase) == false) continue; if (mergedStack.ThreadIds.Contains(threadInfo.OSThreadId) == false) mergedStack.ThreadIds.Add(threadInfo.OSThreadId); merged = true; break; } if (merged) continue; mergedStackTraces.Add(new StackInfo() { ThreadIds = new List<uint>() { threadInfo.OSThreadId }, StackTrace = threadInfo.StackTrace, NativeThreads = threadInfo.IsNative }); } var jsonSerializer = new JsonSerializer { Formatting = Formatting.Indented }; if (outputPath != null) { using (var output = File.Create(outputPath)) using (var streamWriter = new StreamWriter(output)) { jsonSerializer.Serialize(streamWriter, mergedStackTraces); } } else { jsonSerializer.Serialize(Console.Out, mergedStackTraces); } }
private List<UnifiedStackFrame> GetNativeStackTrace(uint engineThreadId) { Util.VerifyHr(((IDebugSystemObjects)_debugClient).SetCurrentThreadId(engineThreadId)); DEBUG_STACK_FRAME[] stackFrames = new DEBUG_STACK_FRAME[200]; uint framesFilled; Util.VerifyHr(((IDebugControl)_debugClient).GetStackTrace(0, 0, 0, stackFrames, stackFrames.Length, out framesFilled)); List<UnifiedStackFrame> stackTrace = new List<UnifiedStackFrame>(); for (uint i = 0; i < framesFilled; ++i) { stackTrace.Add(new UnifiedStackFrame(stackFrames[i], (IDebugSymbols2)_debugClient)); } return stackTrace; }