Example #1
0
        public override bool Generate(CommandExecutionContext context)
        {
            var target = context.NativeDbgEngTarget;
            var lastEvent = target.GetLastEventInformation();
            if (lastEvent == null)
                return false;

            var stackTraces = new UnifiedStackTraces(target.DebuggerInterface, context);
            var threadWithException = stackTraces.Threads.SingleOrDefault(t => t.OSThreadId == lastEvent.OSThreadId);
            if (threadWithException == null)
                return false;

            Exception = new ExceptionInfo
            {
                ExceptionCode = lastEvent.ExceptionRecord?.ExceptionCode ?? 0
            };
            if (Exception.ExceptionCode== 0)
                return false;

            OSThreadId = threadWithException.OSThreadId;
            ManagedThreadId = threadWithException.ManagedThread?.ManagedThreadId ?? 0;

            // Note that we want the thread's stack from the exception context,
            // and not from wherever it is right now.
            Exception.StackFrames = stackTraces.GetStackTraceFromStoredEvent()
                                                .Where(f => f.Type != UnifiedStackFrameType.Special)
                                                .Select(f => f.DisplayString)
                                                .ToList();

            // Note that we might have an exception, but if it wasn't managed
            // then the Thread.CurrentException field will be null.
            var exception = threadWithException.ManagedThread?.CurrentException;
            if (exception == null)
                return true;

            Exception.ExceptionType = exception.Type.Name;
            Exception.ExceptionMessage = exception.Message;

            exception = exception.Inner;
            var exceptionInfo = Exception;
            while (exception != null)
            {
                exceptionInfo.InnerException = new ExceptionInfo();
                exceptionInfo = exceptionInfo.InnerException;

                exceptionInfo.ExceptionType = exception.Type.Name;
                exceptionInfo.ExceptionMessage = exception.Message;
                exceptionInfo.StackFrames = exception.StackTrace.Select(f => f.DisplayString).ToList();

                exception = exception.Inner;
            }

            if (Exception != null)
                Recommendations.Add(new UnhandledExceptionOccurred { Exception = Exception });

            return true;
        }
Example #2
0
        public override bool Generate(CommandExecutionContext context)
        {
            var target = context.NativeDbgEngTarget;
            var unifiedStackTraces = new UnifiedStackTraces(target.DebuggerInterface, context);
            var blockingObjectsStrategy = new DumpFileBlockingObjectsStrategy(context.Runtime, unifiedStackTraces, target);
            foreach (var thread in unifiedStackTraces.Threads)
            {
                // This function is created lazily because we don't need the managed
                // code state for each thread.
                Func<bool> checkManagedCodeStateForThisThread = () =>
                        unifiedStackTraces.GetStackTrace(thread.EngineThreadId)
                                            .Any(f => f.Type == UnifiedStackFrameType.Managed);
                var threadWithBlockingInfo = blockingObjectsStrategy.GetThreadWithBlockingObjects(thread);
                var threadInfo = new ThreadInfo
                {
                    ManagedThreadId = threadWithBlockingInfo.ManagedThreadId,
                    OSThreadId = threadWithBlockingInfo.OSThreadId,
                    IsRunningManagedCode = checkManagedCodeStateForThisThread
                };

                foreach (var blockingObject in threadWithBlockingInfo.BlockingObjects)
                {
                    var lockInfo = new LockInfo
                    {
                        Reason = blockingObject.Reason.ToString()
                    };
                    if (blockingObject.Type == UnifiedBlockingType.ClrBlockingObject)
                    {
                        lockInfo.Object = blockingObject.ManagedObjectAddress;
                        lockInfo.ManagedObjectType = context.Heap.GetObjectType(lockInfo.Object)?.Name;
                    }
                    else
                    {
                        lockInfo.Object = blockingObject.Handle;
                        lockInfo.OSObjectName = blockingObject.KernelObjectName;
                    }
                    lockInfo.OwnerThreadOSIds.AddRange(blockingObject.OwnerOSThreadIds);
                    threadInfo.Locks.Add(lockInfo);
                }

                Threads.Add(threadInfo);

                RecommendFinalizerThreadBlocked(context);
                RecommendDeadlockedThreads();
            }

            return Threads.Any();
        }
Example #3
0
        public override bool Generate(CommandExecutionContext context)
        {
            var managedThreadNames = GetManagedThreadNames(context.Heap);

            var target = context.NativeDbgEngTarget;
            IDebugSystemObjects3 sysObjects = (IDebugSystemObjects3)target.DebuggerInterface;
            sysObjects.GetCurrentProcessUpTime(out _processUpTimeInSeconds);

            var debugAdvanced = (IDebugAdvanced2)target.DebuggerInterface;
            var stackTraces = new UnifiedStackTraces(target.DebuggerInterface, context);
            foreach (var thread in stackTraces.Threads)
            {
                var stackTrace = stackTraces.GetStackTrace(thread.Index);
                var threadInfo = new ThreadInfo
                {
                    EngineThreadId = thread.EngineThreadId,
                    OSThreadId = thread.OSThreadId,
                    ManagedThreadId = thread.ManagedThread?.ManagedThreadId ?? -1,
                    SpecialDescription = thread.ManagedThread?.SpecialDescription()
                };

                string threadName;
                if (managedThreadNames.TryGetValue(threadInfo.ManagedThreadId, out threadName))
                    threadInfo.ThreadName = threadName;

                threadInfo.Fill(debugAdvanced);
                foreach (var frame in stackTrace)
                {
                    threadInfo.StackFrames.Add(new StackFrame
                    {
                        Module = frame.Module,
                        Method = frame.Method,
                        SourceFileName = frame.SourceFileName,
                        SourceLineNumber = frame.SourceLineNumber
                    });
                }
                Threads.Add(threadInfo);
            }

            RecommendFinalizerThreadHighCPU(context);
            RecommendHighNumberOfThreads();

            return true;
        }