public static ParallelStack Build(ClrRuntime runtime)
        {
            var ps          = new ParallelStack();
            var stackFrames = new List <ClrStackFrame>(64);

            foreach (var thread in runtime.Threads)
            {
                stackFrames.Clear();

                foreach (var stackFrame in thread.StackTrace.Reverse())
                {
                    if (stackFrame.Kind != ClrStackFrameType.ManagedMethod)
                    {
                        continue;
                    }

                    stackFrames.Add(stackFrame);
                }

                if (stackFrames.Count == 0)
                {
                    continue;
                }

                ps.AddStack(thread.ManagedThreadId, stackFrames.ToArray());
            }

            return(ps);
        }
        private void WriteStack(ParallelStack stack, int increment = 0)
        {
            var alignment = new string(' ', padding *increment);

            if (stack.Stacks.Count == 0)
            {
                var lastFrame = stack.Frame;
                Console.Write($"{Environment.NewLine}{alignment}");
                WriteFrameSeparator(" ~~~~");
                //Console.Write($"{Environment.NewLine}{alignment}{stack.ThreadIds.Count,padding} ");
                WriteCount($"{Environment.NewLine}{alignment}{stack.ThreadIds.Count,padding} ");
                WriteFrame(lastFrame);
                return;
            }

            foreach (var nextStackFrame in stack.Stacks.OrderBy(s => s.ThreadIds.Count))
            {
                WriteStack(nextStackFrame,
                           (nextStackFrame.ThreadIds.Count == stack.ThreadIds.Count) ? increment : increment + 1);
            }

            var currentFrame = stack.Frame;

            //Console.Write($"{Environment.NewLine}{alignment}{stack.ThreadIds.Count,padding} ");
            WriteCount($"{Environment.NewLine}{alignment}{stack.ThreadIds.Count,padding} ");
            WriteFrame(currentFrame);
        }
        private void AddStack(int threadId, ClrStackFrame[] frames, int index = 0)
        {
            ThreadIds.Add(threadId);
            var firstFrame = frames[index].DisplayString;
            var callstack  = Stacks.FirstOrDefault(s => s.Frame.Text == firstFrame);

            if (callstack == null)
            {
                callstack = new ParallelStack(frames[index]);
                Stacks.Add(callstack);
            }

            if (index == frames.Length - 1)
            {
                callstack.ThreadIds.Add(threadId);
                return;
            }

            callstack.AddStack(threadId, frames, index + 1);
        }
        static ParallelStack BuildParallelStacks(string dumpFile, string dacFilePath)
        {
            DataTarget    dataTarget = null;
            ParallelStack ps         = null;

            try
            {
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    dataTarget = DataTarget.LoadCrashDump(dumpFile);
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    dataTarget = DataTarget.LoadCoreDump(dumpFile);
                }
                else
                {
                    Console.WriteLine("Unsupported platform...");
                    return(null);
                }

                var runtime = CreateRuntime(dataTarget, dacFilePath);
                if (runtime == null)
                {
                    return(null);
                }

                ps = ParallelStack.Build(runtime);
            }
            finally
            {
                dataTarget?.Dispose();
            }

            return(ps);
        }