Example #1
0
        private static ThreadInfo GetThreadInfo(ClrThread thread, DataTarget dataTarget,
                                                ClrRuntime runtime, StringBuilder sb, bool includeStackObjects)
        {
            var hasStackTrace = thread.StackTrace.Count > 0;

            var threadInfo = new ThreadInfo
            {
                OSThreadId      = thread.OSThreadId,
                ManagedThreadId = thread.ManagedThreadId,
                IsNative        = hasStackTrace == false,
                ThreadType      = thread.IsGC ? ThreadType.GC :
                                  thread.IsFinalizer ? ThreadType.Finalizer :
                                  hasStackTrace == false ? ThreadType.Native : ThreadType.Other
            };

            if (hasStackTrace)
            {
                foreach (var frame in thread.StackTrace)
                {
                    if (frame.DisplayString.Equals("GCFrame", StringComparison.OrdinalIgnoreCase) ||
                        frame.DisplayString.Equals("DebuggerU2MCatchHandlerFrame", StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    threadInfo.StackTrace.Add(frame.DisplayString);
                }
            }
            else if (dataTarget.DebuggerInterface != null)
            {
                var control      = (IDebugControl)dataTarget.DebuggerInterface;
                var sysObjs      = (IDebugSystemObjects)dataTarget.DebuggerInterface;
                var nativeFrames = new DEBUG_STACK_FRAME[100];
                var sybSymbols   = (IDebugSymbols)dataTarget.DebuggerInterface;

                threadInfo.IsNative = true;

                sysObjs.SetCurrentThreadId(threadInfo.OSThreadId);

                control.GetStackTrace(0, 0, 0, nativeFrames, 100, out var frameCount);

                for (var i = 0; i < frameCount; i++)
                {
                    sb.Clear();
                    sybSymbols.GetNameByOffset(nativeFrames[i].InstructionOffset, sb, sb.Capacity, out _, out _);

                    threadInfo.StackTrace.Add(sb.ToString());
                }
            }

            if (includeStackObjects)
            {
                threadInfo.StackObjects = GetStackObjects(runtime, thread);
            }

            return(threadInfo);
        }
Example #2
0
        private static void ShowStackTrace(int processId, uint attachTimeout, string outputPath)
        {
            if (processId == -1)
            {
                throw new InvalidOperationException("Uninitialized process id parameter");
            }

            var threadInfoList = new List <ThreadInfo>();

            using (DataTarget dataTarget = DataTarget.AttachToProcess(processId, attachTimeout))
            {
                var clrInfo      = dataTarget.ClrVersions[0];
                var runtime      = clrInfo.CreateRuntime();
                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);
            }
        }
Example #3
0
		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);
			}
		}