From 6e62dad949058b4a20d3f220c3dd600e1391e36b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Sat, 12 Nov 2005 12:33:33 +0000 Subject: [PATCH] Redesigned debugger evaluation interface git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@728 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Debugger.Core.csproj | 4 +- .../Debugger/DebuggerEvents/PausedReason.cs | 3 +- .../Src/Debugger/Internal/ManagedCallback.cs | 22 ++-- .../Project/Src/Debugger/NDebugger.cs | 16 +-- .../Project/Src/Threads/Function.cs | 4 +- .../Project/Src/Variables/Evals/Eval.cs | 92 ++++++++------- ...DebugEvalEventArgs.cs => EvalEventArgs.cs} | 21 ++-- .../Project/Src/Variables/Evals/EvalQueue.cs | 58 ---------- .../Src/Variables/Evals/NDebugger-Evals.cs | 108 ++++++++++++++++++ .../Project/Src/Variables/PropertyVariable.cs | 12 +- 10 files changed, 201 insertions(+), 139 deletions(-) rename src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/{CorDebugEvalEventArgs.cs => EvalEventArgs.cs} (54%) delete mode 100644 src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/EvalQueue.cs create mode 100644 src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/NDebugger-Evals.cs diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj index e5de4ea2de..07d24b2286 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj @@ -88,9 +88,7 @@ - - @@ -203,6 +201,8 @@ + + diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebuggerEvents/PausedReason.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebuggerEvents/PausedReason.cs index dd80d24340..6b75236cde 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebuggerEvents/PausedReason.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebuggerEvents/PausedReason.cs @@ -1,4 +1,4 @@ -// +// // 2002-2005 AlphaSierraPapa // GNU General Public License // @@ -9,6 +9,7 @@ namespace Debugger { public enum PausedReason:int { + AllEvalsComplete, StepComplete, Breakpoint, Break, diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs index f00b623c99..0f70c743bf 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Internal/ManagedCallback.cs @@ -28,8 +28,6 @@ namespace Debugger Process callingProcess; Thread callingThread; - public event EventHandler CorDebugEvalCompleted; - public ManagedCallback(NDebugger debugger) { this.debugger = debugger; @@ -196,18 +194,26 @@ namespace Debugger ExitCallback_Continue(); } - - public void EvalComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval eval) + + public void EvalComplete(ICorDebugAppDomain pAppDomain, ICorDebugThread pThread, ICorDebugEval corEval) { EnterCallback("EvalComplete", pThread); - if (CorDebugEvalCompleted != null) { - CorDebugEvalCompleted(this, new CorDebugEvalEventArgs(debugger, eval)); + // Let the eval know it that the CorEval has finished + // this will also remove the eval form PendingEvals collection + Eval eval = debugger.GetEval(corEval); + if (eval != null) { + eval.OnEvalComplete(new EvalEventArgs(debugger, eval)); } - ExitCallback_Paused(PausedReason.EvalComplete); + if (debugger.PendingEvals.Count > 0) { + debugger.SetupNextEvaluation(); + ExitCallback_Continue(); + } else { + ExitCallback_Paused(PausedReason.AllEvalsComplete); + } } - + public void DebuggerError(ICorDebugProcess pProcess, int errorHR, uint errorCode) { EnterCallback("DebuggerError", pProcess); diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs index e94523af3b..82b044cb00 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/NDebugger.cs @@ -1,4 +1,4 @@ -// +// // 2002-2005 AlphaSierraPapa // GNU General Public License // @@ -22,17 +22,9 @@ namespace Debugger ICorDebug corDebug; ManagedCallback managedCallback; ManagedCallbackProxy managedCallbackProxy; - + ApartmentState requiredApartmentState; - - EvalQueue evalQueue; - - internal EvalQueue EvalQueue { - get { - return evalQueue; - } - } - + public ApartmentState RequiredApartmentState { get { return requiredApartmentState; @@ -117,8 +109,6 @@ namespace Debugger currentProcess = null; - evalQueue = new EvalQueue(this); - TraceMessage("Reset done"); corDebug.Terminate(); diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs index ff968af39d..14cc2b1c12 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs @@ -1,4 +1,4 @@ -// +// // 2002-2005 AlphaSierraPapa // GNU General Public License // @@ -448,7 +448,7 @@ namespace Debugger evalArgs = new ICorDebugValue[] {ThisVariable.CorValue}; } Eval eval = new Eval(debugger, evalCorFunction, evalArgs); - debugger.EvalQueue.AddEval(eval); + debugger.AddEval(eval); properties.Add(new PropertyVariable(debugger, eval, method.Name.Remove(0, 4))); } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs index 4729e17bfb..2a3818f146 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs @@ -1,4 +1,4 @@ -// +// // 2002-2005 AlphaSierraPapa // GNU General Public License // @@ -9,76 +9,86 @@ using System; using System.Collections; using System.Runtime.InteropServices; +using Debugger; using Debugger.Interop.CorDebug; using Debugger.Interop.MetaData; namespace Debugger { - class Eval + /// + /// This class holds information about function evaluation. + /// + public class Eval { NDebugger debugger; - + ICorDebugEval corEval; ICorDebugFunction corFunction; ICorDebugValue[] args; - bool complete = false; - public event EventHandler EvalComplete; - - protected virtual void OnEvalComplete(DebuggerEventArgs e) - { - if (EvalComplete != null) { - EvalComplete(this, e); + bool completed = false; + Variable result; + + public event EventHandler EvalComplete; + + /// + /// True if the evaluation has been completed. + /// + public bool Completed { + get { + return completed; + } + } + + /// + /// The result of the evaluation if the evaluation is complete and has returned a value. Null otherwise. + /// + public Variable Result { + get { + if (completed) { + return result; + } else { + return null; + } + } + } + + internal ICorDebugEval CorEval { + get { + return corEval; } } - public Eval(NDebugger debugger, ICorDebugFunction corFunction, ICorDebugValue[] args) + internal Eval(NDebugger debugger, ICorDebugFunction corFunction, ICorDebugValue[] args) { this.debugger = debugger; this.corFunction = corFunction; this.args = args; - debugger.ManagedCallback.CorDebugEvalCompleted += new EventHandler(CorDebugEvalCompletedInManagedCallback); } - /// - /// Executes the evaluation and doesn't return until value is evaluated. - /// - /// - /// - public void PerformEval() - { - AsyncPerformEval(); - while (!complete) { - System.Windows.Forms.Application.DoEvents(); - } - } - - /// - /// Executes the evaluation and resumes debugger. - /// - public void AsyncPerformEval() + /// True is setup was successful + internal bool SetupEvaluation() { debugger.AssertPaused(); - + + // TODO: What if this thread is not suitable? debugger.CurrentThread.CorThread.CreateEval(out corEval); corEval.CallFunction(corFunction, (uint)args.Length, args); - - debugger.Continue(); + + return true; } - public ICorDebugValue GetResult() + protected internal virtual void OnEvalComplete(EvalEventArgs e) { + completed = true; + ICorDebugValue corValue; corEval.GetResult(out corValue); - return corValue; - } - - void CorDebugEvalCompletedInManagedCallback(object sender, CorDebugEvalEventArgs e) - { - if (e.CorDebugEval == corEval) { - complete = true; - OnEvalComplete(new DebuggerEventArgs(debugger)); + result = VariableFactory.CreateVariable(debugger, corValue, "eval result"); + + if (EvalComplete != null) { + EvalComplete(this, e); } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/CorDebugEvalEventArgs.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/EvalEventArgs.cs similarity index 54% rename from src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/CorDebugEvalEventArgs.cs rename to src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/EvalEventArgs.cs index 7cbe867e95..66e6d5eed9 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/CorDebugEvalEventArgs.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/EvalEventArgs.cs @@ -1,4 +1,4 @@ -// +// // 2002-2005 AlphaSierraPapa // GNU General Public License // @@ -6,24 +6,29 @@ // using System; -using Debugger.Interop.CorDebug; namespace Debugger { [Serializable] - class CorDebugEvalEventArgs : DebuggerEventArgs + public class EvalEventArgs : DebuggerEventArgs { - ICorDebugEval corDebugEval; + Eval eval; - public ICorDebugEval CorDebugEval { + public Eval Eval { get { - return corDebugEval; + return eval; } } - public CorDebugEvalEventArgs(NDebugger debugger, ICorDebugEval corDebugEval): base(debugger) + public Variable Result { + get { + return eval.Result; + } + } + + public EvalEventArgs(NDebugger debugger, Eval eval): base(debugger) { - this.corDebugEval = corDebugEval; + this.eval = eval; } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/EvalQueue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/EvalQueue.cs deleted file mode 100644 index ff72910449..0000000000 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/EvalQueue.cs +++ /dev/null @@ -1,58 +0,0 @@ -// -// 2002-2005 AlphaSierraPapa -// GNU General Public License -// -// $Revision$ -// - -using System; -using System.Collections; -using System.Runtime.InteropServices; - -using Debugger.Interop.CorDebug; -using Debugger.Interop.MetaData; - -namespace Debugger -{ - class EvalQueue - { - NDebugger debugger; - - ArrayList waitingEvals = new ArrayList(); - - public event EventHandler AllEvalsComplete; - - public EvalQueue(NDebugger debugger) - { - this.debugger = debugger; - } - - public void AddEval(Eval eval) - { - waitingEvals.Add(eval); - } - - public void PerformAllEvals() - { - while (waitingEvals.Count > 0) { - PerformNextEval(); - } - } - - public void PerformNextEval() - { - if (waitingEvals.Count == 0) { - throw new DebuggerException("No eval in queue to perform."); - } - Eval eval = (Eval)waitingEvals[0]; - waitingEvals.Remove(eval); - eval.PerformEval(); - - if (waitingEvals.Count == 0) { - if (AllEvalsComplete != null) { - AllEvalsComplete(this, new DebuggerEventArgs(debugger)); - } - } - } - } -} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/NDebugger-Evals.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/NDebugger-Evals.cs new file mode 100644 index 0000000000..e6411dd516 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/NDebugger-Evals.cs @@ -0,0 +1,108 @@ +// +// 2002-2005 AlphaSierraPapa +// GNU General Public License +// +// $Revision$ +// + +using System; +using System.Collections.Generic; + +using Debugger.Interop.CorDebug; + +namespace Debugger +{ + public partial class NDebugger + { + List pendingEvalsCollection = new List(); + + public event EventHandler EvalAdded; + public event EventHandler EvalCompleted; + public event EventHandler AllEvelsCompleted; + + protected virtual void OnEvalAdded(EvalEventArgs e) + { + if (EvalAdded != null) { + EvalAdded(this, e); + } + } + + protected virtual void OnEvalCompleted(EvalEventArgs e) + { + if (EvalCompleted != null) { + EvalCompleted(this, e); + } + } + + protected virtual void OnAllEvelsCompleted(DebuggerEventArgs e) + { + if (AllEvelsCompleted != null) { + AllEvelsCompleted(this, e); + } + } + + public IList PendingEvals { + get { + return pendingEvalsCollection.AsReadOnly(); + } + } + + internal Eval GetEval(ICorDebugEval corEval) { + return pendingEvalsCollection.Find(delegate (Eval eval) {return eval.CorEval == corEval;}); + } + + /// + /// Adds eval to a list of pending evals. + /// The evaluation of pending evals should be started by calling StartEvaluation in paused stated. + /// The the debugger will continue until all evals are done and will stop with PausedReason.AllEvalsComplete + /// + internal Eval AddEval(Eval eval) + { + pendingEvalsCollection.Add(eval); + + eval.EvalComplete += EvalComplete; + + OnEvalAdded(new EvalEventArgs(this, eval)); + + return eval; + } + + // Removes eval from collection and fires events for the eval + void EvalComplete(object sender, EvalEventArgs e) + { + pendingEvalsCollection.Remove(e.Eval); + + OnEvalCompleted(e); + + if (pendingEvalsCollection.Count == 0) { + OnAllEvelsCompleted(new DebuggerEventArgs(this)); + } + } + + // return true if there was eval to setup and it was setup + internal bool SetupNextEvaluation() + { + if (pendingEvalsCollection.Count > 0) { + return pendingEvalsCollection[0].SetupEvaluation(); + } else { + return false; + } + } + + /// + /// Starts evaluation of pending evals. + /// + public bool StartEvaluation() + { + this.AssertPaused(); + + // TODO: Investigate other threads, are they alowed to run? + if (SetupNextEvaluation()) { + this.Continue(); + return true; + } else { + return false; + } + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PropertyVariable.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PropertyVariable.cs index 7556390445..eccf84ec68 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PropertyVariable.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PropertyVariable.cs @@ -1,4 +1,4 @@ -// +// // 2002-2005 AlphaSierraPapa // GNU General Public License // @@ -20,7 +20,7 @@ namespace Debugger internal PropertyVariable(NDebugger debugger, Eval eval, string name):base(debugger, null, name) { this.eval = eval; - eval.EvalComplete += new EventHandler(EvalComplete); + eval.EvalComplete += new EventHandler(EvalComplete); } public bool IsEvaluated { @@ -71,7 +71,7 @@ namespace Debugger /// public void Evaluate() { - eval.PerformEval(); + //eval.PerformEval(); } /// @@ -79,12 +79,12 @@ namespace Debugger /// public void AsyncEvaluate() { - eval.AsyncPerformEval(); + //eval.AsyncPerformEval(); } - void EvalComplete(object sender, DebuggerEventArgs args) + void EvalComplete(object sender, EvalEventArgs args) { - currentValue = VariableFactory.CreateVariable(debugger, eval.GetResult(), Name); + currentValue = VariableFactory.CreateVariable(debugger, eval.Result.CorValue, Name); OnValueEvaluated(); }