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; }
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(); }
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; }