ThreadProperties GetThreadProperties_CorDebug(DnThread thread, ThreadProperties oldProperties, bool isCreateThread, bool forceReadName, bool isMainThread) { debuggerThread.VerifyAccess(); var appDomain = TryGetEngineAppDomain(thread.AppDomainOrNull)?.AppDomain; ulong id = (uint)thread.VolatileThreadId; // If it was created, it could already have a new name so always try to read it if (isCreateThread) { forceReadName = true; } var managedId = oldProperties?.ManagedId; // Always retry calling ClrDac since it sometimes fails the first time we call it if (managedId == null) { managedId = GetManagedId_ClrDac(thread); } // If we should read the name, it means the CLR thread object is available so we // should also read the managed ID. if (managedId == null && forceReadName) { managedId = GetManagedId(thread, appDomain); } // If it's a new thread, it has no name (m_Name is null) var name = forceReadName ? GetThreadName(thread, appDomain) : oldProperties?.Name; int suspendedCount = thread.CorThread.IsSuspended ? 1 : 0; var userState = thread.CorThread.UserState; var kind = GetThreadKind(thread, isMainThread); return(new ThreadProperties(appDomain, kind, id, managedId, name, suspendedCount, userState)); }
public DbgEngineThread.UpdateOptions Compare(ThreadProperties other) { var options = DbgEngineThread.UpdateOptions.None; if (other.AppDomain != AppDomain) { options |= DbgEngineThread.UpdateOptions.AppDomain; } if (other.Kind != Kind) { options |= DbgEngineThread.UpdateOptions.Kind; } if (other.Id != Id) { options |= DbgEngineThread.UpdateOptions.Id; } if (other.ManagedId != ManagedId) { options |= DbgEngineThread.UpdateOptions.ManagedId; } if (other.Name != Name) { options |= DbgEngineThread.UpdateOptions.Name; } if (other.SuspendedCount != SuspendedCount) { options |= DbgEngineThread.UpdateOptions.SuspendedCount; } if (other.UserState != UserState) { options |= DbgEngineThread.UpdateOptions.State; } return(options); }