public static string GetFormattedStackTraceFrom(Thread targetThread) { var sb = new StringBuilder(); try { var dt = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, false); var rt = dt.ClrVersions.Single().CreateRuntime(); ClrThread clrThread = null; foreach (var t in rt.Threads) { if (t.ManagedThreadId == targetThread.ManagedThreadId) { clrThread = t; break; } } foreach (var frame in clrThread.EnumerateStackTrace()) { var method = frame.Method; if (method != null) { sb.AppendLine($" at {method.Signature}"); } } } catch (Exception e) { return(e.StackTrace); } return(sb.ToString()); }
private static void DumpStackTrace(ClrThread thread, TextWriter writer, CancellationToken cancellationToken) { // TODO: StackTrace property may be clipped, add a note var stackTrace = thread.EnumerateStackTrace().ToArray(); if (stackTrace.Length > 1) { writer.WriteLine(" Managed stack trace:"); foreach (var frame in stackTrace) { cancellationToken.ThrowIfCancellationRequested(); var moduleName = frame.Method?.Type.Module?.Name; if (moduleName != null) { moduleName = Path.GetFileName(moduleName); } writer.WriteLine($" - {frame} at {moduleName}"); } } else { writer.WriteLine(" No managed stack trace found for this thread."); } }
private static string GetStackTraceClrmd(ClrThread runtimeThread) { var sb = new StringBuilder(); foreach (var frame in runtimeThread.EnumerateStackTrace()) { if (frame.Method == null) { continue; } sb.AppendLine($" in {frame.Method}"); } return(sb.ToString()); }
public void MinidumpCallstackTest() { using DataTarget dt = TestTargets.NestedException.LoadMiniDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrThread thread = runtime.GetMainThread(); string[] frames = IntPtr.Size == 8 ? new[] { "Inner", "Inner", "Middle", "Outer", "Main" } : new[] { "Inner", "Middle", "Outer", "Main" }; int i = 0; foreach (ClrStackFrame frame in thread.EnumerateStackTrace()) { if (frame.Kind == ClrStackFrameKind.ManagedMethod) { Assert.NotEqual(0ul, frame.InstructionPointer); Assert.NotEqual(0ul, frame.StackPointer); Assert.NotNull(frame.Method); Assert.NotNull(frame.Method.Type); Assert.NotNull(frame.Method.Type.Module); Assert.Equal(frames[i++], frame.Method.Name); } } }
public static ClrStackFrame GetFrame(this ClrThread thread, string functionName) { return(thread.EnumerateStackTrace().Single(sf => sf.Method != null ? sf.Method.Name == functionName : false)); }
/// <summary> /// Enumerates a stack trace for a given thread. Note this method may loop infinitely in the case of /// stack corruption or other stack unwind issues which can happen in practice. When enumerating frames /// out of this method you should be careful to either set a maximum loop count, or to ensure the stack /// unwind is making progress by ensuring that ClrStackFrame.StackPointer is making progress (though it /// is expected that sometimes two frames may return the same StackPointer in some corner cases). /// </summary> /// <returns>An enumeration of stack frames.</returns> /// <inheritdoc /> public IEnumerable <IClrStackFrame> EnumerateStackTrace() => Thread.EnumerateStackTrace().Select(Converter.Convert);