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 2c329ed30f..791bd0fddd 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/Threads/Function.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs index 10e4d9bf49..076f59f0de 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 @@ -115,7 +115,7 @@ namespace Debugger return new UnavailableValue(debugger, "Function has expired"); } else { try { - return new ObjectValue(debugger, CorILFrame.GetArgument(0), ContaingClass); + return new ObjectValue(debugger, new PersistentCorValue(debugger, CorILFrame.GetArgument(0)), ContaingClass); } catch (COMException e) { // System.Runtime.InteropServices.COMException (0x80131304): An IL variable is not available at the current native IP. // See Forum-8640 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 732e1686c1..b2313d434d 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 @@ -59,7 +59,7 @@ namespace Debugger } - internal unsafe ArrayValue(NDebugger debugger, ICorDebugValue corValue):base(debugger, corValue) + internal unsafe ArrayValue(NDebugger debugger, PersistentCorValue pCorValue):base(debugger, pCorValue) { corElementType = (CorElementType)CorArrayValue.ElementType; 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 ee7b084b93..a357ed853c 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 @@ -36,7 +36,7 @@ namespace Debugger } } - internal unsafe NullValue(NDebugger debugger, ICorDebugValue corValue):base(debugger, corValue) + internal unsafe NullValue(NDebugger debugger, PersistentCorValue pCorValue):base(debugger, pCorValue) { } 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 ced46a1e0d..8c5f646c12 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 @@ -85,13 +85,13 @@ namespace Debugger } } - internal unsafe ObjectValue(NDebugger debugger, ICorDebugValue corValue):base(debugger, corValue) + internal unsafe ObjectValue(NDebugger debugger, PersistentCorValue pCorValue):base(debugger, pCorValue) { corClass = this.CorValue.CastTo().Class; InitObjectVariable(); } - internal unsafe ObjectValue(NDebugger debugger, ICorDebugValue corValue, ICorDebugClass corClass):base(debugger, corValue) + internal unsafe ObjectValue(NDebugger debugger, PersistentCorValue pCorValue, ICorDebugClass corClass):base(debugger, pCorValue) { this.corClass = corClass; InitObjectVariable(); @@ -300,9 +300,9 @@ namespace Debugger } else { ICorDebugClass superClass = corModuleSuperclass.GetClassFromToken(classProps.SuperClassToken); if (corHandleValue != null) { - return new ObjectValue(debugger, corHandleValue.As(), superClass); + return new ObjectValue(debugger, new PersistentCorValue(debugger, corHandleValue.As()), superClass); } else { - return new ObjectValue(debugger, CorValue, superClass); + return new ObjectValue(debugger, new PersistentCorValue(debugger, CorValue), superClass); } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentCorValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentCorValue.cs new file mode 100644 index 0000000000..85b30311ff --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentCorValue.cs @@ -0,0 +1,89 @@ +// +// +// +// +// $Revision$ +// + +using System; + +using Debugger.Wrappers.CorDebug; + +namespace Debugger +{ + /// + /// PersistentValue is a container used to obtain the value of a given object even after continue. + /// + public class PersistentCorValue + { + /// + /// Delegate that is used to get value. This delegate may be called at any time and should never return null. + /// + public delegate ICorDebugValue CorValueGetter(); + + + NDebugger debugger; + + public ICorDebugValue CorValue; + // ICorDebugHandleValue can be used to get corValue back after Continue() + public ICorDebugHandleValue corHandleValue; + public PauseSession pauseSessionAtCreation; + public DebugeeState debugeeStateAtCreation; + + public bool IsExpired { + get { + if (corHandleValue == null) { + return pauseSessionAtCreation != debugger.PauseSession; + } else { + return debugeeStateAtCreation != debugger.DebugeeState; + } + } + } + + public ICorDebugValue CorValueProp { + get { + if (this.IsExpired) throw new DebuggerException("CorValue has expired"); + + if (pauseSessionAtCreation == debugger.PauseSession) { + return CorValue; + } else { + if (corHandleValue == null) { + throw new DebuggerException("CorValue has expired"); + } else { + CorValue = Value.DereferenceUnbox(corHandleValue.As()); + pauseSessionAtCreation = debugger.PauseSession; + return CorValue; + } + } + } + } + + public ICorDebugHandleValue SoftReference { + get { + if (this.IsExpired) throw new DebuggerException("CorValue has expired"); + + if (corHandleValue != null) return corHandleValue; + + ICorDebugHeapValue2 heapValue = this.CorValueProp.As(); + if (heapValue == null) { // TODO: Investigate - hmmm, value types are not at heap? + return null; + } else { + return heapValue.CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION); + } + } + } + + public PersistentCorValue(NDebugger debugger, ICorDebugValue corValue) + { + this.debugger = debugger; + if (corValue != null) { + if (corValue.Is()) { + corHandleValue = corValue.As(); + } + this.CorValue = Value.DereferenceUnbox(corValue); + } + this.pauseSessionAtCreation = debugger.PauseSession; + this.debugeeStateAtCreation = debugger.DebugeeState; + } + } +} 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 e86833bb58..f702315991 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 @@ -51,7 +51,7 @@ namespace Debugger } } - internal PrimitiveValue(NDebugger debugger, ICorDebugValue corValue):base(debugger, corValue) + internal PrimitiveValue(NDebugger debugger, PersistentCorValue pCorValue):base(debugger, pCorValue) { } 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 abcabdcadb..9b926313ce 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 @@ -16,11 +16,7 @@ namespace Debugger public abstract class Value: RemotingObjectBase { protected NDebugger debugger; - ICorDebugValue corValue; - // ICorDebugHandleValue can be used to get corValue back after Continue() - protected ICorDebugHandleValue corHandleValue; - PauseSession pauseSessionAtCreation; - DebugeeState debugeeStateAtCreation; + PersistentCorValue pCorValue; public event EventHandler ValueChanged; @@ -30,36 +26,21 @@ namespace Debugger } } + protected ICorDebugHandleValue corHandleValue { + get { + return pCorValue.corHandleValue; + } + } + internal ICorDebugValue CorValue { get { - if (this.IsExpired) throw new DebuggerException("CorValue has expired"); - - if (pauseSessionAtCreation == debugger.PauseSession) { - return corValue; - } else { - if (corHandleValue == null) { - throw new DebuggerException("CorValue has expired"); - } else { - corValue = DereferenceUnbox(corHandleValue.As()); - pauseSessionAtCreation = debugger.PauseSession; - return corValue; - } - } + return pCorValue.CorValueProp; } } protected ICorDebugHandleValue SoftReference { get { - if (this.IsExpired) throw new DebuggerException("CorValue has expired"); - - if (corHandleValue != null) return corHandleValue; - - ICorDebugHeapValue2 heapValue = this.CorValue.As(); - if (heapValue == null) { // TODO: Investigate - hmmm, value types are not at heap? - return null; - } else { - return heapValue.CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION); - } + return pCorValue.SoftReference; } } @@ -68,11 +49,7 @@ namespace Debugger /// public bool IsExpired { get { - if (corHandleValue == null) { - return pauseSessionAtCreation != debugger.PauseSession; - } else { - return debugeeStateAtCreation != debugger.DebugeeState; - } + return pCorValue.IsExpired; } } @@ -134,17 +111,10 @@ namespace Debugger } } - protected Value(NDebugger debugger, ICorDebugValue corValue) + protected Value(NDebugger debugger, PersistentCorValue pCorValue) { this.debugger = debugger; - if (corValue != null) { - if (corValue.Is()) { - corHandleValue = corValue.As(); - } - this.corValue = DereferenceUnbox(corValue); - } - this.pauseSessionAtCreation = debugger.PauseSession; - this.debugeeStateAtCreation = debugger.DebugeeState; + this.pCorValue = pCorValue; } public override string ToString() @@ -242,7 +212,7 @@ namespace Debugger { ICorDebugValue derefed = Value.DereferenceUnbox(corValue); if (derefed == null) { - return new NullValue(debugger, corValue); + return new NullValue(debugger, new PersistentCorValue(debugger, corValue)); } CorElementType type = Value.GetCorType(derefed); @@ -264,16 +234,16 @@ namespace Debugger case CorElementType.I: case CorElementType.U: case CorElementType.STRING: - return new PrimitiveValue(debugger, corValue); + return new PrimitiveValue(debugger, new PersistentCorValue(debugger, corValue)); case CorElementType.ARRAY: case CorElementType.SZARRAY: // Short-cut for single dimension zero lower bound array - return new ArrayValue(debugger, corValue); + return new ArrayValue(debugger, new PersistentCorValue(debugger, corValue)); case CorElementType.VALUETYPE: case CorElementType.CLASS: case CorElementType.OBJECT: // Short-cut for Class "System.Object" - return new ObjectValue(debugger, corValue); + return new ObjectValue(debugger, new PersistentCorValue(debugger, corValue)); default: // Unknown type return new UnavailableValue(debugger, "Unknown value type");