From: Igor Bagdamyan <37334640+En3Tho@users.noreply.github.com> Date: Tue, 5 Dec 2023 21:27:40 +0000 (+0300) Subject: An additional flag to parallel stacks to include runtime stacks to pstacks command... X-Git-Tag: accepted/tizen/unified/20241231.014852~40^2~266 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=61546f5ce268b18850652e61a2857f8984a748e7;p=platform%2Fcore%2Fdotnet%2Fdiagnostics.git An additional flag to parallel stacks to include runtime stacks to pstacks command (#4423) This adds "-r" flag to include Runtime stacks to pstacks output It will still ignore the frame if it's method is null. It's just a matter of checking for both Runtime and Managed kinds Sometimes it might be useful to have those too, for example like in https://github.com/dotnet/diagnostics/issues/4418 when it is still useful to know which threads are in locked state --- diff --git a/src/Microsoft.Diagnostics.ExtensionCommands/ParallelStacks.Runtime/ParallelStack.cs b/src/Microsoft.Diagnostics.ExtensionCommands/ParallelStacks.Runtime/ParallelStack.cs index f2653bb8d..c3287f0cd 100644 --- a/src/Microsoft.Diagnostics.ExtensionCommands/ParallelStacks.Runtime/ParallelStack.cs +++ b/src/Microsoft.Diagnostics.ExtensionCommands/ParallelStacks.Runtime/ParallelStack.cs @@ -11,7 +11,7 @@ namespace ParallelStacks.Runtime { public class ParallelStack { - public static ParallelStack Build(ClrRuntime runtime) + public static ParallelStack Build(ClrRuntime runtime, bool includeRuntimeStacks) { ParallelStack ps = new(); List stackFrames = new(64); @@ -20,7 +20,11 @@ namespace ParallelStacks.Runtime stackFrames.Clear(); foreach (ClrStackFrame stackFrame in thread.EnumerateStackTrace().Reverse()) { - if ((stackFrame.Kind != ClrStackFrameKind.ManagedMethod) || (stackFrame.Method == null)) + bool shouldAdd = + stackFrame.Kind == ClrStackFrameKind.ManagedMethod + || (includeRuntimeStacks && stackFrame.Kind == ClrStackFrameKind.Runtime); + + if ((!shouldAdd) || (stackFrame.Method == null)) { continue; } @@ -39,7 +43,7 @@ namespace ParallelStacks.Runtime return ps; } - public static ParallelStack Build(string dumpFile, string dacFilePath) + public static ParallelStack Build(string dumpFile, string dacFilePath, bool includeRuntimeStacks) { DataTarget dataTarget = null; ParallelStack ps = null; @@ -63,7 +67,7 @@ namespace ParallelStacks.Runtime return null; } - ps = ParallelStack.Build(runtime); + ps = ParallelStack.Build(runtime, includeRuntimeStacks); } finally { @@ -73,7 +77,7 @@ namespace ParallelStacks.Runtime return ps; } - public static ParallelStack Build(int pid, string dacFilePath) + public static ParallelStack Build(int pid, string dacFilePath, bool includeRuntimeStacks) { DataTarget dataTarget = null; ParallelStack ps = null; @@ -100,7 +104,7 @@ namespace ParallelStacks.Runtime return null; } - ps = ParallelStack.Build(runtime); + ps = ParallelStack.Build(runtime, includeRuntimeStacks); } finally { diff --git a/src/Microsoft.Diagnostics.ExtensionCommands/ParallelStacksCommand.cs b/src/Microsoft.Diagnostics.ExtensionCommands/ParallelStacksCommand.cs index 3320f11d3..0b9a987e4 100644 --- a/src/Microsoft.Diagnostics.ExtensionCommands/ParallelStacksCommand.cs +++ b/src/Microsoft.Diagnostics.ExtensionCommands/ParallelStacksCommand.cs @@ -17,9 +17,12 @@ namespace Microsoft.Diagnostics.ExtensionCommands [Option(Name = "--allthreads", Aliases = new string[] { "-a" }, Help = "Displays all threads per group instead of at most 4 by default.")] public bool AllThreads { get; set; } + [Option(Name = "--runtime", Aliases = new string[] { "-r" }, Help = "Displays runtime stacks in addition to managed ones.")] + public bool IncludeRuntimeStacks { get; set; } + public override void Invoke() { - ParallelStack ps = ParallelStack.Build(Runtime); + ParallelStack ps = ParallelStack.Build(Runtime, IncludeRuntimeStacks); if (ps == null) { return;