diff --git a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DynamicTreeDebuggerRow.cs b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DynamicTreeDebuggerRow.cs index 97c98330ec..d59bade1fd 100644 --- a/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DynamicTreeDebuggerRow.cs +++ b/src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Service/DynamicTreeDebuggerRow.cs @@ -192,6 +192,7 @@ namespace ICSharpCode.SharpDevelop.Services subMenu[2].Text = subCollection.Name; subMenu[3].Text = subCollection.Value; subMenu.ShowMinusWhileExpanded = true; + subMenu.ShowPlus = !subCollection.IsEmpty; EventHandler populate = null; populate = delegate { 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 300aef46f9..4201ab43a2 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Debugger.Core.csproj @@ -381,6 +381,7 @@ + diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Util.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Util.cs new file mode 100644 index 0000000000..19bc9342e9 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/Util.cs @@ -0,0 +1,39 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; + +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + public static class Util + { + public static List MergeLists(T a, IEnumerable b) + { + return MergeLists(new T[] {a}, b); + } + + public static List MergeLists(IEnumerable a, T b) + { + return MergeLists(a, new T[] {b}); + } + + public static List MergeLists(IEnumerable a, IEnumerable b) + { + List newList = new List(); + if (a != null) newList.AddRange(a); + if (b != null) newList.AddRange(b); + return newList; + } + } +} diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs index 5111515ab7..111fe09881 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs @@ -133,19 +133,17 @@ namespace Debugger } } - public override bool MayHaveSubVariables { - get { - return true; - } + protected override bool GetMayHaveSubVariables() + { + return true; } - public override VariableCollection SubVariables { - get { - return new VariableCollection(GetSubVariables()); - } + protected override VariableCollection GetSubVariables() + { + return new VariableCollection(GetSubVariablesEnum()); } - IEnumerable GetSubVariables() + IEnumerable GetSubVariablesEnum() { uint[] indices = new uint[rank]; diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.CallFunctionEval.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.CallFunctionEval.cs index ee7424919d..4edbf95751 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.CallFunctionEval.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.CallFunctionEval.cs @@ -25,14 +25,6 @@ namespace Debugger Variable thisValue; Variable[] args; - static List MergeLists(IEnumerable a, IEnumerable b) - { - List newList = new List(); - if (a != null) newList.AddRange(a); - if (b != null) newList.AddRange(b); - return newList; - } - public CallFunctionEval(NDebugger debugger, string moduleName, string containgType, string functionName, bool reevaluateAfterDebuggeeStateChange, Variable thisValue, Variable[] args) :this(debugger, null, reevaluateAfterDebuggeeStateChange, thisValue, args) { @@ -42,7 +34,7 @@ namespace Debugger } public CallFunctionEval(NDebugger debugger, ICorDebugFunction corFunction, bool reevaluateAfterDebuggeeStateChange, Variable thisValue, Variable[] args) - :base(debugger, reevaluateAfterDebuggeeStateChange, thisValue == null? args : MergeLists(new Variable[] {thisValue}, args).ToArray()) + :base(debugger, reevaluateAfterDebuggeeStateChange, thisValue == null? args : Util.MergeLists(new Variable[] {thisValue}, args).ToArray()) { this.corFunction = corFunction; this.thisValue = thisValue; diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/NullValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/NullValue.cs index 217ad561b8..0058c1572c 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/NullValue.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/NullValue.cs @@ -41,10 +41,9 @@ namespace Debugger } - public override bool MayHaveSubVariables { - get { - return false; - } + protected override bool GetMayHaveSubVariables() + { + return false; } } } 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 1342948d6d..c90b8699b2 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 @@ -78,16 +78,14 @@ namespace Debugger } } - public override bool MayHaveSubVariables { - get { - return true; - } + protected override bool GetMayHaveSubVariables() + { + return true; } - public override VariableCollection SubVariables { - get { - return topClass.SubVariables; - } + protected override VariableCollection GetSubVariables() + { + return topClass.SubVariables; } } } 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 11fe6d4679..2abae1c13f 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 @@ -55,10 +55,9 @@ namespace Debugger { } - public override bool MayHaveSubVariables { - get { - return false; - } + protected override bool GetMayHaveSubVariables() + { + return false; } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/UnavailableValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/UnavailableValue.cs index fcaf9eed73..4e173a62f9 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/UnavailableValue.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/UnavailableValue.cs @@ -33,10 +33,9 @@ namespace Debugger this.message = message; } - public override bool MayHaveSubVariables { - get { - return false; - } + protected override bool GetMayHaveSubVariables() + { + return false; } } } 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 92ebc77d34..f3465691d2 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 @@ -63,16 +63,37 @@ namespace Debugger } } - public abstract bool MayHaveSubVariables { - get; + public bool MayHaveSubVariables { + get { + #if DEBUG + return true; + #else + return GetMayHaveSubVariables(); + #endif + } } - public virtual VariableCollection SubVariables { + protected abstract bool GetMayHaveSubVariables(); + + public VariableCollection SubVariables { get { - return new VariableCollection(new Variable[] {}); + VariableCollection subVars = GetSubVariables(); + #if DEBUG + return new VariableCollection(subVars.Name, + subVars.Value, + Util.MergeLists(variable.GetDebugInfo(), subVars.SubCollections).ToArray(), + subVars.Items); + #else + return subVars; + #endif } } + protected virtual VariableCollection GetSubVariables() + { + return new VariableCollection(new Variable[] {}); + } + public Variable this[string variableName] { get { foreach(Variable v in SubVariables) { 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 c7bac653a6..4df9c686ac 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 @@ -6,6 +6,7 @@ // using System; +using System.Collections.Generic; using Debugger.Wrappers.CorDebug; @@ -267,6 +268,73 @@ namespace Debugger throw new CannotGetValueException("Unknown value type"); } } + + public VariableCollection GetDebugInfo() + { + return GetDebugInfo(this.RawCorValue); + } + + public static VariableCollection GetDebugInfo(ICorDebugValue corValue) + { + List items = new List(); + + if (corValue.Is()) { + List more = new List(); + more.Add(new VariableCollection("type", ((CorElementType)corValue.Type).ToString())); + more.Add(new VariableCollection("size", corValue.Size.ToString())); + more.Add(new VariableCollection("address", corValue.Address.ToString("X"))); + items.Add(new VariableCollection("ICorDebugValue", "", more, null)); + } + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugValue2", "", null, null)); + if (corValue.Is()) { + List more = new List(); + try { + byte[] bytes = corValue.CastTo().RawValue; + for(int i = 0; i < bytes.Length; i += 8) { + string val = ""; + for(int j = i; j < bytes.Length && j < i + 8; j++) { + val += bytes[j].ToString("X2") + " "; + } + more.Add(new VariableCollection("data" + i.ToString("X2"), val)); + } + } catch (ArgumentException) { + more.Add(new VariableCollection("data", "N/A")); + } + items.Add(new VariableCollection("ICorDebugGenericValue", "", more, null)); + } + if (corValue.Is()) { + List more = new List(); + ICorDebugReferenceValue refValue = corValue.CastTo(); + bool isNull = refValue.IsNull != 0; + more.Add(new VariableCollection("isNull", isNull.ToString())); + if (!isNull) { + more.Add(new VariableCollection("address", refValue.Value.ToString("X"))); + VariableCollection deRef = GetDebugInfo(refValue.Dereference()); + more.Add(new VariableCollection("dereferenced", deRef.Value, deRef.SubCollections, deRef.Items)); + } + items.Add(new VariableCollection("ICorDebugReferenceValue", "", more, null)); + } + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugHeapValue", "", null, null)); + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugHeapValue2", "", null, null)); + if (corValue.Is()) { + List more = new List(); + bool isValue = corValue.CastTo().IsValueClass != 0; + more.Add(new VariableCollection("isValue", isValue.ToString())); + items.Add(new VariableCollection("ICorDebugObjectValue", "", more, null)); + } + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugObjectValue2", "", null, null)); + if (corValue.Is()) { + List more = new List(); + VariableCollection unboxed = GetDebugInfo(corValue.CastTo().Object.CastTo()); + more.Add(new VariableCollection("unboxed", unboxed.Value, unboxed.SubCollections, unboxed.Items)); + items.Add(new VariableCollection("ICorDebugBoxValue", "", more, null)); + } + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugStringValue", "", null, null)); + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugArrayValue", "", null, null)); + if (corValue.Is()) items.Add(new VariableCollection("ICorDebugHandleValue", "", null, null)); + + return new VariableCollection("$debugInfo", ((CorElementType)corValue.Type).ToString(), items.ToArray(), null); + } } class CannotGetValueException: System.Exception 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 2b1c2df436..589ca77449 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 @@ -59,10 +59,8 @@ namespace Debugger public bool IsEmpty { get { - foreach(VariableCollection col in SubCollections) { - if (!col.IsEmpty) return false; - } - return !Items.GetEnumerator().MoveNext(); + return !SubCollections.GetEnumerator().MoveNext() && + !Items.GetEnumerator().MoveNext(); } } @@ -71,12 +69,24 @@ namespace Debugger { } + public VariableCollection(string name, string val):this(name, val, null, null) + { + } + public VariableCollection(string name, string val, IEnumerable subCollectionsEnum, IEnumerable collectionEnum) { this.name = name; this.val = val; - this.subCollectionsEnum = subCollectionsEnum; - this.collectionEnum = collectionEnum; + if (subCollectionsEnum != null) { + this.subCollectionsEnum = subCollectionsEnum; + } else { + this.subCollectionsEnum = new VariableCollection[0]; + } + if (collectionEnum != null) { + this.collectionEnum = collectionEnum; + } else { + this.collectionEnum = new Variable[0]; + } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugGenericValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugGenericValue.cs index 6c40aa2325..40415a8a69 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugGenericValue.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugGenericValue.cs @@ -12,6 +12,24 @@ namespace Debugger.Wrappers.CorDebug public partial class ICorDebugGenericValue { + public unsafe Byte[] RawValue { + get { + Byte[] retValue = new Byte[(int)Size]; + IntPtr pValue = Marshal.AllocHGlobal(retValue.Length); + GetValue(pValue); + Marshal.Copy(pValue, retValue, 0, retValue.Length); + Marshal.FreeHGlobal(pValue); + return retValue; + } + set { + if (Size != value.Length) throw new ArgumentException("Incorrect length"); + IntPtr pValue = Marshal.AllocHGlobal(value.Length); + Marshal.Copy(value, 0, pValue, value.Length); + SetValue(pValue); + Marshal.FreeHGlobal(pValue); + } + } + public unsafe object Value { get { object retValue;