diff --git a/src/AddIns/Debugger/Debugger.Core/Eval.cs b/src/AddIns/Debugger/Debugger.Core/Eval.cs index 319ef0a2fa..3097dacfc2 100644 --- a/src/AddIns/Debugger/Debugger.Core/Eval.cs +++ b/src/AddIns/Debugger/Debugger.Core/Eval.cs @@ -91,8 +91,8 @@ namespace Debugger this.process = appDomain.Process; this.description = description; this.state = EvalState.Evaluating; - - this.corEval = CreateCorEval(appDomain, out this.thread); + this.thread = GetEvaluationThread(appDomain); + this.corEval = thread.CorThread.CreateEval(); try { evalStarter(this); @@ -132,36 +132,23 @@ namespace Debugger appDomain.Process.AsyncContinue(DebuggeeStateAction.Keep, this.Process.UnsuspendedThreads, CorDebugThreadState.THREAD_RUN); } } - - static ICorDebugEval CreateCorEval(AppDomain appDomain, out Thread thread) + + static Thread GetEvaluationThread(AppDomain appDomain) { appDomain.Process.AssertPaused(); - thread = appDomain.Process.SelectedThread; + Thread st = appDomain.Process.SelectedThread; + if (st != null && !st.Suspended && !st.IsInNativeCode && st.IsAtSafePoint && st.CorThread.GetAppDomain().GetID() == appDomain.ID) { + return st; + } - if (thread.CorThread.GetAppDomain().GetID() != appDomain.ID) { - foreach(Thread t in appDomain.Process.Threads) { - if (t.CorThread.GetAppDomain().GetID() == appDomain.ID && - !t.Suspended && - !t.IsInNativeCode && - t.IsAtSafePoint) - { - thread = t; - break; - } + foreach(Thread t in appDomain.Process.Threads) { + if (!t.Suspended && !t.IsInNativeCode && t.IsAtSafePoint && t.CorThread.GetAppDomain().GetID() == appDomain.ID) { + return t; } } - if (thread == null) - throw new GetValueException("Can not evaluate because no thread is selected"); - if (thread.IsInNativeCode) - throw new GetValueException("Can not evaluate because native frame is on top of stack"); - if (!thread.IsAtSafePoint) - throw new GetValueException("Can not evaluate because thread is not at a safe point"); - if (thread.Suspended) - throw new GetValueException("Can not evaluate on suspended thread"); - - return thread.CorThread.CreateEval(); + throw new GetValueException("No suitable thread for evaluation"); } internal bool IsCorEval(ICorDebugEval corEval) @@ -293,8 +280,8 @@ namespace Debugger { if (value == null) { ICorDebugClass corClass = appDomain.ObjectType.CorType.GetClass(); - Thread thread; - ICorDebugEval corEval = CreateCorEval(appDomain, out thread); + Thread thread = GetEvaluationThread(appDomain); + ICorDebugEval corEval = thread.CorThread.CreateEval(); ICorDebugValue corValue = corEval.CreateValue((uint)CorElementType.CLASS, corClass); return new Value(appDomain, corValue); } else if (value is string) { diff --git a/src/AddIns/Debugger/Debugger.Core/Process.cs b/src/AddIns/Debugger/Debugger.Core/Process.cs index 80edab580d..430819d80c 100644 --- a/src/AddIns/Debugger/Debugger.Core/Process.cs +++ b/src/AddIns/Debugger/Debugger.Core/Process.cs @@ -416,12 +416,12 @@ namespace Debugger internal Thread[] UnsuspendedThreads { get { - List threadsToRun = new List(this.Threads.Count); + List unsuspendedThreads = new List(this.Threads.Count); foreach(Thread t in this.Threads) { if (!t.Suspended) - threadsToRun.Add(t); + unsuspendedThreads.Add(t); } - return threadsToRun.ToArray(); + return unsuspendedThreads.ToArray(); } } @@ -435,17 +435,18 @@ namespace Debugger internal CorDebugThreadState NewThreadState = CorDebugThreadState.THREAD_RUN; + /// Null to keep current setting + /// What happens to created threads. Null to keep current setting internal void AsyncContinue(DebuggeeStateAction action, Thread[] threadsToRun, CorDebugThreadState? newThreadState) { AssertPaused(); if (threadsToRun != null) { // corProcess.SetAllThreadsDebugState(CorDebugThreadState.THREAD_SUSPEND, null); -// TODO: There is second unreported thread, stopping it prevents the debugee from exiting -// uint count = corProcess.EnumerateThreads().GetCount(); -// ICorDebugThread[] ts = new ICorDebugThread[count]; +// Note: There is unreported thread, stopping it prevents the debugee from exiting +// It is not corProcess.GetHelperThreadID +// ICorDebugThread[] ts = new ICorDebugThread[corProcess.EnumerateThreads().GetCount()]; // corProcess.EnumerateThreads().Next((uint)ts.Length, ts); -// uint helper = corProcess.GetHelperThreadID(); try { foreach(Thread t in this.Threads) { t.CorThread.SetDebugState(CorDebugThreadState.THREAD_SUSPEND);