internal void SendThreadEvents(object sender, EventArgs e) { List <DebuggedThread> deadThreads; List <DebuggedThread> newThreads; lock (_threadList) { deadThreads = _deadThreads; _deadThreads = null; newThreads = _newThreads; _newThreads = null; } if (newThreads != null) { foreach (var newt in newThreads) { _callback.OnThreadStart(newt); } } if (deadThreads != null) { foreach (var dead in deadThreads) { // Send the destroy event outside the lock _callback.OnThreadExit(dead, 0); } } }
internal void SendThreadEvents(object sender, EventArgs e) { if (_debugger.Engine.ProgramCreateEventSent) { List <DebuggedThread> deadThreads; List <DebuggedThread> newThreads; lock (_threadList) { deadThreads = _deadThreads; _deadThreads = null; newThreads = _newThreads; _newThreads = null; } if (newThreads != null) { if (newThreads.Count == _threadList.Count) { // These are the first threads. Send a processInfoUpdateEvent too. AD7ProcessInfoUpdatedEvent.Send(_debugger.Engine, _debugger.LaunchOptions.ExePath, (uint)_debugger.PidByInferior("i1")); } foreach (var newt in newThreads) { // If we are child process debugging, check and see if its a child thread if (!(_debugger.IsChildProcessDebugging && newt.ChildThread)) { _callback.OnThreadStart(newt); } } } if (deadThreads != null) { foreach (var dead in deadThreads) { // If we are child process debugging, check and see if its a child thread if (!(_debugger.IsChildProcessDebugging && dead.ChildThread)) { // Send the destroy event outside the lock _callback.OnThreadExit(dead, 0); } } } } }
internal async Task ThreadCreatedEvent(int id, string groupId) { // Mark that the threads have changed lock (_threadList) { { var thread = _threadList.Find(t => t.Id == id); if (thread == null) { _stateChange = true; } } // This must go before getting the thread-info for the thread since that method call is async. // The threadId must be added to the thread-group before the new thread is created or else it will // be marked as a child thread and then thread-created and thread-exited won't be sent to the UI if (string.IsNullOrEmpty(groupId)) { groupId = c_defaultGroupId; } if (!_threadGroups.ContainsKey(groupId)) { _threadGroups[groupId] = new List <int>(); } _threadGroups[groupId].Add(id); } // Run Thread-info now to get the target-id // ClrDbg doesn't support getting threadInfo while running. ResultValue resVal = null; if (id >= 0 && _debugger.LaunchOptions.DebuggerMIMode != MIMode.Clrdbg) { uint?tid = null; tid = (uint)id; Results results = await _debugger.MICommandFactory.ThreadInfo(tid); if (results.ResultClass != ResultClass.done) { Debug.Fail("Thread info not successful"); } else { var tlist = results.Find <ValueListValue>("threads"); Debug.Assert(tlist.Content.Length == 1, "Expected 1 thread, received more than one thread."); resVal = tlist.Content.FirstOrDefault(item => item.FindInt("id") == id); } } lock (_threadList) { if (resVal != null) { bool bNew = false; var thread = SetThreadInfoFromResultValue(resVal, out bNew); Debug.Assert(thread.Id == id, "thread.Id and id should match"); if (bNew) { _callback.OnThreadStart(thread); } } } }