private void DisplayThreadData(WaitData data, bool allData) { // Save the process id value for the first item as this is the // process that owns the thread. we'll use this to check for // items used by other threads, from other processes later. int startingPID = data.Nodes[0].ProcessId; StringBuilder sb = new StringBuilder(); if (data.IsDeadlock) { sb.Append("DEADLOCKED: "); } for (int i = 0; i < data.NodeCount; i++) { WaitChainNativeMethods.WAITCHAIN_NODE_INFO node = data.Nodes[i]; if (node.ObjectType == WaitChainNativeMethods.WCT_OBJECT_TYPE.Thread) { String procName = Windows.GetProcesses().ContainsKey(node.ProcessId) ? Windows.GetProcesses()[node.ProcessId].Name : "???"; sb.Append(string.Format(" PID: {0} {1} TID: {2}", node.ProcessId, procName, node.ThreadId)); //Is this a block on a thread from another process? if ((i > 0) && (startingPID != node.ProcessId)) { // Yes, so show the PID and name. sb.Append(string.Format(" PID:{0} {1} TID:{2}", node.ProcessId, procName, node.ThreadId)); } if (allData) { sb.Append(string.Format(" Status: {0} Wait: {1} CS: {2:N0}", node.ObjectStatus, node.WaitTime, node.ContextSwitches)); } if (node.ObjectStatus != WaitChainNativeMethods.WCT_OBJECT_STATUS.Blocked) { sb.Append(string.Format(" Status: {0}", node.ObjectStatus)); } } else { sb.Append(string.Format(" {0} Status: {1}", node.ObjectType, node.ObjectStatus)); String name = node.ObjectName; if (!String.IsNullOrEmpty(name)) { sb.Append(string.Format(" Name: {0}", name)); } } threadTree.Nodes.Add(sb.ToString()); } }
public WaitData GetThreadWaitChain(int threadId) { WaitChainNativeMethods.WAITCHAIN_NODE_INFO[] data = new WaitChainNativeMethods.WAITCHAIN_NODE_INFO[WaitChainNativeMethods.WCT_MAX_NODE_COUNT]; int isDeadlock; int nodeCount = WaitChainNativeMethods.WCT_MAX_NODE_COUNT; WaitData retData = null; if (WaitChainNativeMethods.GetThreadWaitChain(waitChainHandle, threadId, ref nodeCount, data, out isDeadlock)) { retData = new WaitData(data, nodeCount, isDeadlock == 1); } return(retData); }
public WaitData GetThreadWaitChain(int threadId) { WaitChainNativeMethods.WAITCHAIN_NODE_INFO[] data = new WaitChainNativeMethods.WAITCHAIN_NODE_INFO[WaitChainNativeMethods.WCT_MAX_NODE_COUNT]; int isDeadlock = 0; int nodeCount = WaitChainNativeMethods.WCT_MAX_NODE_COUNT; WaitData retData = null; if (WaitChainNativeMethods.GetThreadWaitChain(waitChainHandle, threadId, ref nodeCount, data, out isDeadlock)) { retData = new WaitData(data, (int)nodeCount, isDeadlock == 1); } return (retData); }
private void DisplayThreadData(WaitData data, bool allData) { // Save the process id value for the first item as this is the // process that owns the thread. we'll use this to check for // items used by other threads, from other processes later. int startingPID = data.Nodes[0].ProcessId; StringBuilder sb = new StringBuilder(); if (data.IsDeadlock) { sb.Append("DEADLOCKED: "); } for (int i = 0; i < data.NodeCount; i++) { WaitChainNativeMethods.WAITCHAIN_NODE_INFO node = data.Nodes[i]; if (WaitChainNativeMethods.WCT_OBJECT_TYPE.Thread == node.ObjectType) { var processes = Windows.GetProcesses(); String procName = processes.ContainsKey(node.ProcessId) ? processes[node.ProcessId].Name : "???"; switch (node.ObjectStatus) { case WaitChainNativeMethods.WCT_OBJECT_STATUS.PidOnly: case WaitChainNativeMethods.WCT_OBJECT_STATUS.PidOnlyRpcss: sb.Append(string.Format(" PID: {0} {1}", node.ProcessId, procName)); break; default: { sb.Append(string.Format(" TID: {0}", node.ThreadId)); //Is this a block on a thread from another process? if ((i > 0) && (startingPID != node.ProcessId)) { // Yes, so show the PID and name. sb.Append(string.Format(" PID:{0} {1}", node.ProcessId, procName)); } if (allData) { sb.Append(string.Format(" Status: {0} Wait: {1} CS: {2:N0}", node.ObjectStatus, node.WaitTime, node.ContextSwitches)); } else if (node.ObjectStatus != WaitChainNativeMethods.WCT_OBJECT_STATUS.Blocked) { sb.Append(string.Format(" Status: {0}", node.ObjectStatus)); } break; } } } else { switch (node.ObjectType) { case WaitChainNativeMethods.WCT_OBJECT_TYPE.CriticalSection: case WaitChainNativeMethods.WCT_OBJECT_TYPE.SendMessage: case WaitChainNativeMethods.WCT_OBJECT_TYPE.Mutex: case WaitChainNativeMethods.WCT_OBJECT_TYPE.Alpc: case WaitChainNativeMethods.WCT_OBJECT_TYPE.COM: case WaitChainNativeMethods.WCT_OBJECT_TYPE.ThreadWait: case WaitChainNativeMethods.WCT_OBJECT_TYPE.ProcessWait: case WaitChainNativeMethods.WCT_OBJECT_TYPE.COMActivation: case WaitChainNativeMethods.WCT_OBJECT_TYPE.Unknown: { sb.Append(string.Format(" {0} Status: {1}", node.ObjectType, node.ObjectStatus)); String name = node.ObjectName(); if (!String.IsNullOrEmpty(name)) { sb.Append(string.Format(" Name: {0}", name)); } } break; default: { sb.Append(string.Format(" UNKNOWN Object Type Enum: {0}", node.ObjectType.ToString())); break; } } } threadNode.Nodes.Add(sb.ToString()); threadNode.ExpandAll(); } }