void SetCurrentThread_DbgThread(DbgThreadImpl newThread) { Dispatcher.VerifyAccess(); if (!(newThread?.Process is DbgProcessImpl newProcess) || newProcess.State != DbgProcessState.Paused || newThread.IsClosed) { return; } DbgCurrentObjectChangedEventArgs <DbgProcess> processEventArgs; DbgCurrentObjectChangedEventArgs <DbgRuntime> runtimeEventArgs; DbgCurrentObjectChangedEventArgs <DbgThread> threadEventArgs; lock (lockObj) { var newRuntime = (DbgRuntimeImpl)newThread.Runtime; var newCurrentProcess = new CurrentObject <DbgProcessImpl>(newProcess, dbgCurrentProcess.currentProcess.Break); var newCurrentRuntime = new CurrentObject <DbgRuntimeImpl>(newRuntime, newProcess.CurrentRuntime.Break); newRuntime.SetCurrentThread_DbgThread(newThread); Debug.Assert(newRuntime.CurrentThread.Current == newThread); var newCurrentThread = newRuntime.CurrentThread; processEventArgs = new DbgCurrentObjectChangedEventArgs <DbgProcess>(currentChanged: dbgCurrentProcess.currentProcess.Current != newCurrentProcess.Current, breakChanged: dbgCurrentProcess.currentProcess.Break != newCurrentProcess.Break); runtimeEventArgs = new DbgCurrentObjectChangedEventArgs <DbgRuntime>(currentChanged: dbgCurrentRuntime.currentRuntime.Current != newCurrentRuntime.Current, breakChanged: dbgCurrentRuntime.currentRuntime.Break != newCurrentRuntime.Break); threadEventArgs = new DbgCurrentObjectChangedEventArgs <DbgThread>(currentChanged: dbgCurrentThread.currentThread.Current != newCurrentThread.Current, breakChanged: dbgCurrentThread.currentThread.Break != newCurrentThread.Break); dbgCurrentProcess.currentProcess = newCurrentProcess; dbgCurrentRuntime.currentRuntime = newCurrentRuntime; dbgCurrentThread.currentThread = newCurrentThread; } RaiseCurrentObjectEvents_DbgThread(processEventArgs, runtimeEventArgs, threadEventArgs); }
internal void Add_DbgThread(DbgThreadImpl thread) { Dispatcher.VerifyAccess(); lock (lockObj) threads.Add(thread); ThreadsChanged?.Invoke(this, new DbgCollectionChangedEventArgs <DbgThread>(thread, added: true)); }
DbgThreadImpl GetThread_NoLock(DbgThreadImpl thread) { if (thread?.IsClosed == false) { return(thread); } return(threads.FirstOrDefault(a => a.IsMain) ?? (threads.Count == 0 ? null : threads[0])); }
internal DbgStackWalker CreateStackWalker(DbgThreadImpl thread) { var stackWalker = owner.Dispatcher2.Invoke(() => CreateStackWalker_DbgThread(thread)); if (stackWalker == null) { // Invoke() returns null if shutdown has started but we can't return null stackWalker = new DbgStackWalkerImpl(thread, new NullDbgEngineStackWalker()); } CloseOnContinue(stackWalker); return(stackWalker); }
internal void Remove_DbgThread(DbgThreadImpl thread, DbgEngineMessageFlags messageFlags) { Dispatcher.VerifyAccess(); lock (lockObj) { bool b = threads.Remove(thread); if (!b) { return; } } owner.RemoveThread_DbgThread(this, thread, messageFlags); ThreadsChanged?.Invoke(this, new DbgCollectionChangedEventArgs <DbgThread>(thread, added: false)); thread.Close(Dispatcher); }
DbgStackWalker CreateStackWalker_DbgThread(DbgThreadImpl thread) { Dispatcher.VerifyAccess(); DbgEngineStackWalker engineStackWalker; if (Engine.IsClosed) { engineStackWalker = new NullDbgEngineStackWalker(); } else { engineStackWalker = Engine.CreateStackWalker(thread); } return(new DbgStackWalkerImpl(thread, engineStackWalker)); }
internal void StepComplete_DbgThread(DbgThreadImpl thread, string error, bool forciblyCanceled) { Dispatcher.VerifyAccess(); var engine = thread.RuntimeImpl.Engine; Debug.Assert(IsOurEngine(engine)); if (!IsOurEngine(engine)) { return; } var e = new DbgMessageStepCompleteEventArgs(thread, error); e.Pause = !forciblyCanceled; OnConditionalBreak_DbgThread(engine, e, thread, DbgEngineMessageFlags.None); }
internal void StepComplete_DbgThread(DbgThreadImpl thread, string error) { Dispatcher.VerifyAccess(); var engine = thread.RuntimeImpl.Engine; Debug.Assert(IsOurEngine(engine)); if (!IsOurEngine(engine)) { return; } var e = new DbgMessageStepCompleteEventArgs(thread, error); // This is a good default value... e.Pause = true; OnConditionalBreak_DbgThread(engine, e, thread, DbgEngineMessageFlags.None); }
internal DbgStackWalker CreateStackWalker(DbgThreadImpl thread) { DbgEngineStackWalker engineStackWalker; if (Engine.IsClosed) { engineStackWalker = new NullDbgEngineStackWalker(); } else { engineStackWalker = Engine.CreateStackWalker(thread); } var stackWalker = new DbgStackWalkerImpl(thread, engineStackWalker); CloseOnContinue(stackWalker); return(stackWalker); }
public override DbgEngineThread CreateThread <T>(DbgAppDomain appDomain, string kind, ulong id, ulong?managedId, string name, int suspendedCount, ReadOnlyCollection <DbgStateInfo> state, DbgEngineMessageFlags messageFlags, T data, Action <DbgEngineThread> onCreated) { if (disposed) { throw new ObjectDisposedException(nameof(DbgObjectFactoryImpl)); } var thread = new DbgThreadImpl(runtime, VerifyOptionalAppDomain(appDomain), kind, id, managedId, name, suspendedCount, state); if (data != null) { thread.GetOrCreateData(() => data); } var engineThread = new DbgEngineThreadImpl(thread); onCreated?.Invoke(engineThread); owner.Dispatcher.BeginInvoke(() => owner.AddThread_DbgThread(runtime, thread, messageFlags)); return(engineThread); }
internal DbgThread SetBreakThread(DbgThreadImpl thread, bool tryOldCurrentThread = false) { Dispatcher.VerifyAccess(); DbgThreadImpl newCurrent, newBreak; lock (lockObj) { newBreak = GetThread_NoLock(thread); if (tryOldCurrentThread && currentThread.Current?.IsClosed == false) { newCurrent = currentThread.Current; } else { newCurrent = newBreak; } } Debug.Assert((newBreak != null) == (newCurrent != null)); currentThread = new CurrentObject <DbgThreadImpl>(newCurrent, newBreak); return(newCurrent); }
void SetIP_DbgThread(DbgThreadImpl thread, DbgCodeLocation location) { Dispatcher.VerifyAccess(); OnBeforeContinuing_DbgThread(); Engine.SetIP(thread, location); }
internal bool CanSetIP(DbgThreadImpl thread, DbgCodeLocation location) => Engine.CanSetIP(thread, location);
internal void SetIP(DbgThreadImpl thread, DbgCodeLocation location) => Dispatcher.BeginInvoke(() => SetIP_DbgThread(thread, location));
internal DbgStepper CreateStepper(DbgThreadImpl thread) => new DbgStepperImpl(owner, thread, Engine.CreateStepper(thread));
internal void Thaw(DbgThreadImpl thread) => Engine.Thaw(thread);
internal void Freeze(DbgThreadImpl thread) => Engine.Freeze(thread);
internal void SetCurrentThread_DbgThread(DbgThreadImpl thread) { owner.Dispatcher.VerifyAccess(); currentThread = new CurrentObject <DbgThreadImpl>(thread, currentThread.Break); }
public DbgEngineThreadImpl(DbgThreadImpl thread) => this.thread = thread ?? throw new ArgumentNullException(nameof(thread));