コード例 #1
0
        public static ParallelStack Build(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
                {
                    throw new InvalidOperationException("Unsupported platform...");
                }

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

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

            return(ps);
        }
コード例 #2
0
        private static void RenderStack(ParallelStack stack, IRenderer visitor, int increment = 0)
        {
            var alignment = new string(' ', Padding *increment);

            if (stack.Stacks.Count == 0)
            {
                var lastFrame = stack.Frame;
                visitor.Write($"{Environment.NewLine}{alignment}");
                visitor.WriteFrameSeparator($" ~~~~ {FormatThreadIdList(visitor, stack.ThreadIds)}");
                visitor.WriteCount($"{Environment.NewLine}{alignment}{stack.ThreadIds.Count,Padding} ");

                RenderFrame(lastFrame, visitor);
                return;
            }

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

            var currentFrame = stack.Frame;

            visitor.WriteCount($"{Environment.NewLine}{alignment}{stack.ThreadIds.Count,Padding} ");
            RenderFrame(currentFrame, visitor);
        }
コード例 #3
0
        private static void RenderStackHtml(ParallelStack stack, IHtmlRenderer visitor, int increment = 0)
        {
            if (stack.Stacks.Count == 0)
            {
                var lastFrame = stack.Frame;
                visitor.EnterFrameGroupEnd(increment);
                visitor.WriteFrameSeparator($" ~~~~ {FormatThreadIdList(visitor, stack.ThreadIds)}");
                visitor.LeaveFrameGroupEnd();
                visitor.EnterFrame(increment);
                visitor.WriteCount($"{stack.ThreadIds.Count,Padding}");
                RenderFrame(lastFrame, visitor);
                visitor.LeaveFrame();

                return;
            }

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

            var currentFrame = stack.Frame;

            visitor.EnterFrame(increment);
            visitor.WriteCount($"{stack.ThreadIds.Count,Padding}");
            RenderFrame(currentFrame, visitor);
            visitor.LeaveFrame();
        }
コード例 #4
0
        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.OSThreadId, stackFrames.ToArray());
            }

            return(ps);
        }
コード例 #5
0
        public static ParallelStack Build(ClrRuntime runtime)
        {
            var ps          = new ParallelStack();
            var stackFrames = new List <ClrStackFrame>(64);

            foreach (var thread in runtime.Threads)
            {
                stackFrames.Clear();
#if ClrMD1
                foreach (var stackFrame in thread.StackTrace.Reverse())
#else
                foreach (var stackFrame in thread.EnumerateStackTrace().Reverse())
#endif
                {
#if ClrMD1
                    if (stackFrame.Kind != ClrStackFrameType.ManagedMethod)
#else
                    if ((stackFrame.Kind != ClrStackFrameKind.ManagedMethod) || (stackFrame.Method == null))
#endif
                    { continue; }

                    stackFrames.Add(stackFrame);
                }

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

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

            return(ps);
        }
コード例 #6
0
        public static void RenderHtml(this ParallelStack stacks, IHtmlRenderer visitor)
        {
            visitor.EnterRender(stacks);
            foreach (var stack in stacks.Stacks)
            {
                visitor.EnterStackRoot();
                RenderStackHtml(stack, visitor);
                visitor.LeaveStackRoot();
            }

            visitor.EndRender();
        }
コード例 #7
0
        public static ParallelStack Build(int pid, string dacFilePath)
        {
            DataTarget    dataTarget = null;
            ParallelStack ps         = null;

            try
            {
#if ClrMD1
                const uint msecTimeout = 2000;

                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    dataTarget = DataTarget.AttachToProcess(pid, msecTimeout, AttachFlag.NonInvasive);
                }
                else
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    // ClrMD implementation for Linux is available only for Passive
                    dataTarget = DataTarget.AttachToProcess(pid, msecTimeout, AttachFlag.Passive);
                }
#else
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    dataTarget = DataTarget.AttachToProcess(pid, true);
                }
                else
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    // ClrMD implementation for Linux is available only for Passive
                    dataTarget = DataTarget.AttachToProcess(pid, true);
                }
#endif
                else
                {
                    throw new InvalidOperationException("Unsupported platform...");
                }

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

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

            return(ps);
        }
コード例 #8
0
        private void AddStack(uint 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);
        }
コード例 #9
0
        public static void Run(string name, string version, string[] args)
        {
            if (args.Length == 0)
            {
                ShowHelp(name, version, "Missing dump file path or process ID...");
                return;
            }

            string dacFilePath = (args.Length >= 2) ? args[1] : null;

            if (dacFilePath != null)
            {
                if (!File.Exists(dacFilePath))
                {
                    Console.WriteLine($"{dacFilePath} file does not exist...");
                    return;
                }
            }

            ParallelStack ps;

            var input = args[0];

            // attach to live process
            if (int.TryParse(input, out var pid))
            {
                try
                {
                    ps = ParallelStack.Build(pid, dacFilePath);
                }
                catch (InvalidOperationException x)
                {
                    Console.WriteLine($"Impossible to build call stacks: {x.Message}");
                    return;
                }
            }
            // open memory dump
            else
            {
                if (!File.Exists(input))
                {
                    Console.WriteLine($"'{input}' does not exist...");
                    return;
                }

                try
                {
                    ps = ParallelStack.Build(input, dacFilePath);
                }
                catch (InvalidOperationException x)
                {
                    Console.WriteLine($"Impossible to build call stacks: {x.Message}");
                    return;
                }
            }

            int threadIDsCountlimit = 4;
            var visitor             = new ConsoleRenderer(useDml: false, limit: threadIDsCountlimit);

            Console.WriteLine();
            foreach (var stack in ps.Stacks)
            {
                Console.Write("________________________________________________");
                stack.Render(visitor);
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();
            }

            Console.WriteLine($"==> {ps.ThreadIds.Count} threads with {ps.Stacks.Count} roots{Environment.NewLine}");
        }
コード例 #10
0
 public static void Render(this ParallelStack stacks, IRenderer visitor)
 {
     RenderStack(stacks, visitor);
 }
コード例 #11
0
 public override void EnterRender(ParallelStack stacks)
 {
     _bufferHtml.Append($"<p><span class=\"{TitleClassName}\">{stacks.ThreadIds.Count} threads for {stacks.Stacks.Count} roots</span></p>");
 }