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 afdfed6fdb..eb9e28ac9e 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 @@ -79,7 +79,15 @@ namespace Debugger public Value Result { get { if (completed) { - return result; + if (successful) { + return result; + } else { + ObjectValue exception = (ObjectValue)result; + while (exception.Type != "System.Exception") { + exception = exception.BaseClass; + } + return new UnavailableValue(debugger, result.Type + ": " + exception["_message"].Value.AsString); + } } else { return null; } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs index ae3fbf722d..ed263d6e25 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs @@ -23,13 +23,53 @@ namespace Debugger MetaData metaData; ICorDebugModule corModuleSuperclass; ObjectValue baseClass; + internal string toString; + Eval toStringEval; TypeDefProps classProps; public override string AsString { - get{ - return "{" + Type + "}"; - } + get{ + if (toString != null) { + return toString; + } else { + if (toStringEval == null) { + // Set up eval of ToString() + + ObjectValue baseClass = this; + while (baseClass.HasBaseClass) { + baseClass = baseClass.BaseClass; + } + foreach(MethodProps method in baseClass.Module.MetaData.EnumMethods(baseClass.ClassToken)) { + if (method.Name == "ToString") { + ICorDebugValue[] evalArgs; + ICorDebugFunction evalCorFunction; + baseClass.Module.CorModule.GetFunctionFromToken(method.Token, out evalCorFunction); + // We need to pass reference + ICorDebugHeapValue2 heapValue = this.CorValue as ICorDebugHeapValue2; + if (heapValue == null) { + toString = "{" + Type + "}"; + return toString; + } + ICorDebugHandleValue corHandle; + heapValue.CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION, out corHandle); + evalArgs = new ICorDebugValue[] {corHandle}; + toStringEval = new Eval(debugger, evalCorFunction, evalArgs); + // Do not add evals if we just evaluated them, otherwise we get infinite loop + if (debugger.IsPaused && debugger.PausedReason != PausedReason.AllEvalsComplete) { + debugger.AddEval(toStringEval); + //toStringEval.SetupEvaluation(debugger.CurrentThread); + } + toStringEval.EvalComplete += delegate { + toString = toStringEval.Result.AsString; + this.OnValueChanged(); + }; + } + } + } + return "{" + Type + "}"; + } + } } public override string Type { @@ -37,8 +77,19 @@ namespace Debugger return classProps.Name; } } - - + + public Module Module { + get { + return debugger.GetModule(corModule); + } + } + + public uint ClassToken { + get { + return classProps.Token; + } + } + internal unsafe ObjectValue(NDebugger debugger, ICorDebugValue corValue):base(debugger, corValue) { ((ICorDebugObjectValue)this.corValue).GetClass(out corClass); @@ -56,7 +107,7 @@ namespace Debugger uint classToken; corClass.GetToken(out classToken); corClass.GetModule(out corModule); - metaData = debugger.GetModule(corModule).MetaData; + metaData = Module.MetaData; classProps = metaData.GetTypeDefProps(classToken); diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PrimitiveValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PrimitiveValue.cs index 29816e2c41..8377836c64 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PrimitiveValue.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PrimitiveValue.cs @@ -15,14 +15,6 @@ namespace Debugger { public class PrimitiveValue: Value { - public event EventHandler ValueChanged; - - protected virtual void OnValueChanged() { - if (ValueChanged != null) { - ValueChanged(this, new ValueEventArgs(this)); - } - } - public override string AsString { get { if (Primitive != null) { 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 0da0e76da2..7a0ebb4ceb 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 @@ -17,7 +17,7 @@ namespace Debugger public event EventHandler ValueEvaluated; - internal PropertyVariable(Eval eval, string name):base(eval.Debugger, null, name) + internal PropertyVariable(Eval eval, string name):base(eval.Debugger, new UnavailableValue(eval.Debugger), name) { this.Eval = eval; } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs index 43beebb60c..becb0377db 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs @@ -19,6 +19,8 @@ namespace Debugger protected ICorDebugValue corValue; + public event EventHandler ValueChanged; + public NDebugger Debugger { get { return debugger; @@ -47,6 +49,12 @@ namespace Debugger } } + protected virtual void OnValueChanged() { + if (ValueChanged != null) { + ValueChanged(this, new ValueEventArgs(this)); + } + } + public virtual Type ManagedType { get { return CorTypeToManagedType(CorType); diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs index e625e8d40b..9e53242a02 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs @@ -38,9 +38,7 @@ namespace Debugger } internal set { val = value; - if (val is PrimitiveValue) { - ((PrimitiveValue)val).ValueChanged += delegate { OnValueChanged(); }; - } + val.ValueChanged += delegate { OnValueChanged(); }; OnValueChanged(); } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs index c105a0e1d7..f283eaa0df 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs @@ -159,9 +159,11 @@ namespace Debugger if (this.Contains(newVariable.Name)) { Variable oldVariable = this[newVariable.Name]; // Update existing variable + if (oldVariable.Value is ObjectValue && newVariable.Value is ObjectValue && debugger.PausedReason == PausedReason.AllEvalsComplete) { + ((ObjectValue)newVariable.Value).toString = ((ObjectValue)oldVariable.Value).toString; + } if (oldVariable is PropertyVariable) { - Eval newEval = ((PropertyVariable)newVariable).Eval; - ((PropertyVariable)oldVariable).Eval = newEval; + ((PropertyVariable)oldVariable).Eval = ((PropertyVariable)newVariable).Eval; } else { oldVariable.Value = newVariable.Value; }