public virtual List <UnifiedBlockingObject> GetUnmanagedBlockingObjects(uint osThreadId) { var result = new List <UnifiedBlockingObject>(); if (_unifiedStackTraces != null && _stackWalker != null) { var threadInfo = _unifiedStackTraces.Threads.SingleOrDefault(ti => ti.OSThreadId == osThreadId); if (threadInfo != null) { var stack = _unifiedStackTraces.GetStackTrace(threadInfo.EngineThreadId); foreach (var frame in stack) { _stackWalker.SetFrameParameters(frame); UnifiedBlockingObject blockingObject; if (_stackWalker.GetCriticalSectionBlockingObject(frame, out blockingObject)) { result.Add(blockingObject); } else if (_stackWalker.GetThreadSleepBlockingObject(frame, out blockingObject)) { result.Add(blockingObject); } result.AddRange(frame.Handles.Select(GetUnifiedBlockingObjectForHandle)); } } } return(result); }
private void FillFaultingThreadAndModuleInformation(CommandExecutionContext context) { UnifiedStackTraces stackTrace = new UnifiedStackTraces(_dbgEngTarget.DebuggerInterface, context); _triageInformation.TotalThreadCount = (int)stackTrace.NumThreads; _triageInformation.ManagedThreadCount = stackTrace.Threads.Count(t => t.IsManagedThread); LastEventInformation lastEventInformation = _dbgEngTarget.GetLastEventInformation(); if (lastEventInformation == null) { return; } ThreadInformation faultingThread = stackTrace.Threads.SingleOrDefault(t => t.OSThreadId == lastEventInformation.OSThreadId); if (faultingThread == null) { return; } _triageInformation.FaultingThreadOSID = faultingThread.OSThreadId; _triageInformation.IsFaultingThreadManaged = faultingThread.IsManagedThread; _triageInformation.EventDescription = lastEventInformation.EventDescription; if (lastEventInformation.ExceptionRecord.HasValue) { _triageInformation.ExceptionCode = lastEventInformation.ExceptionRecord.Value.ExceptionCode; } if (faultingThread.IsManagedThread && faultingThread.ManagedThread.CurrentException != null) { _triageInformation.ManagedExceptionType = faultingThread.ManagedThread.CurrentException.Type.Name; } var frames = stackTrace.GetStackTrace(faultingThread.Index); UnifiedStackFrame faultingFrame = frames.FirstOrDefault(f => f.Module != null && !WellKnownMicrosoftModules.Contains(f.Module)); if (faultingFrame != null) { _triageInformation.FaultingModule = faultingFrame.Module; _triageInformation.FaultingMethod = faultingFrame.Method; } if (ShowFaultingStack) { context.WriteLine("Faulting call stack:"); stackTrace.PrintStackTrace(context, frames); } }
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); }
public void Execute(CommandExecutionContext context) { _context = context; if (IncludeNativeThreads) { using (var target = context.CreateTemporaryDbgEngTarget()) { var tracer = new UnifiedStackTraces(target.DebuggerInterface, context); context.WriteLine("Stack tree for {0} threads:", tracer.NumThreads); var allStacks = from thread in tracer.Threads let frames = from frame in tracer.GetStackTrace(thread.Index) where frame.Type != UnifiedStackFrameType.Special select frame.DisplayString select new ThreadAndStack { ManagedThreadId = thread.IsManagedThread ? thread.ManagedThread.ManagedThreadId : 0, OSThreadId = thread.OSThreadId, Stack = frames.Reverse() }; ProcessStacks(allStacks); } } else { context.WriteLine("Stack tree for {0} threads:", context.Runtime.Threads.Count); var allStacks = from thread in context.Runtime.Threads let frames = from frame in thread.StackTrace where frame.Kind == ClrStackFrameType.ManagedMethod select frame.DisplayString select new ThreadAndStack { ManagedThreadId = thread.ManagedThreadId, Stack = frames.Reverse() }; ProcessStacks(allStacks); } }
private void FillFaultingThreadAndModuleInformation(CommandExecutionContext context) { UnifiedStackTraces stackTrace = new UnifiedStackTraces(_dbgEngTarget.DebuggerInterface, context); _triageInformation.TotalThreadCount = (int)stackTrace.NumThreads; _triageInformation.ManagedThreadCount = stackTrace.Threads.Count(t => t.IsManagedThread); LastEventInformation lastEventInformation = _dbgEngTarget.GetLastEventInformation(); if (lastEventInformation == null) return; ThreadInformation faultingThread = stackTrace.Threads.SingleOrDefault(t => t.OSThreadId == lastEventInformation.OSThreadId); if (faultingThread == null) return; _triageInformation.FaultingThreadOSID = faultingThread.OSThreadId; _triageInformation.IsFaultingThreadManaged = faultingThread.IsManagedThread; _triageInformation.EventDescription = lastEventInformation.EventDescription; if (lastEventInformation.ExceptionRecord.HasValue) { _triageInformation.ExceptionCode = lastEventInformation.ExceptionRecord.Value.ExceptionCode; } if (faultingThread.IsManagedThread && faultingThread.ManagedThread.CurrentException != null) { _triageInformation.ManagedExceptionType = faultingThread.ManagedThread.CurrentException.Type.Name; } var frames = stackTrace.GetStackTrace(faultingThread.Index); UnifiedStackFrame faultingFrame = frames.FirstOrDefault(f => f.Module != null && !WellKnownMicrosoftModules.Contains(f.Module)); if (faultingFrame != null) { _triageInformation.FaultingModule = faultingFrame.Module; _triageInformation.FaultingMethod = faultingFrame.Method; } if (ShowFaultingStack) { context.WriteLine("Faulting call stack:"); stackTrace.PrintStackTrace(context, frames); } }