Browse Source

All values are created in PersistentValue

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1548 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 19 years ago
parent
commit
c9652ebf4a
  1. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs
  2. 44
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs
  3. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs
  4. 10
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs
  5. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs
  6. 23
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs
  7. 34
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentCorValue.cs
  8. 107
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentValue.cs
  9. 70
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs
  10. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs

@ -41,7 +41,7 @@ namespace Debugger @@ -41,7 +41,7 @@ namespace Debugger
this.thread = thread;
corValue = thread.CorThread.CurrentException;
exceptionType = thread.CurrentExceptionType;
runtimeValue = Value.CreateValue(debugger, corValue);
runtimeValue = new PersistentValue(debugger, corValue).Value;
runtimeValueException = runtimeValue as ObjectValue;
if (runtimeValueException != null) {
while (runtimeValueException.Type != "System.Exception") {

44
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs

@ -433,21 +433,19 @@ namespace Debugger @@ -433,21 +433,19 @@ namespace Debugger
{
return new Variable(debugger,
GetParameterName(index),
new PersistentValue(delegate { return GetArgumentValue(index); }));
new PersistentValue(debugger, delegate { return GetArgumentCorValue(index); } ));
}
Value GetArgumentValue(int index)
ICorDebugValue GetArgumentCorValue(int index)
{
if (this.HasExpired) {
return new UnavailableValue(debugger, "Function has expired");
} else {
try {
// Non-static functions include 'this' as first argument
return Value.CreateValue(debugger, CorILFrame.GetArgument((uint)(IsStatic? index : (index + 1))));
} catch (COMException e) {
if ((uint)e.ErrorCode == 0x80131304) return new UnavailableValue(debugger, "Unavailable in optimized code");
throw;
}
if (this.HasExpired) throw new CannotGetValueException("Function has expired");
try {
// Non-static functions include 'this' as first argument
return CorILFrame.GetArgument((uint)(IsStatic? index : (index + 1)));
} catch (COMException e) {
if ((uint)e.ErrorCode == 0x80131304) throw new CannotGetValueException("Unavailable in optimized code");
throw;
}
}
@ -488,22 +486,18 @@ namespace Debugger @@ -488,22 +486,18 @@ namespace Debugger
{
return new Variable(debugger,
symVar.Name,
new PersistentValue(delegate { return GetValueOfLocalVariable(symVar); }));
new PersistentValue(debugger, delegate { return GetCorValueOfLocalVariable(symVar); }));
}
Value GetValueOfLocalVariable(ISymUnmanagedVariable symVar)
ICorDebugValue GetCorValueOfLocalVariable(ISymUnmanagedVariable symVar)
{
if (this.HasExpired) {
return new UnavailableValue(debugger, "Function has expired");
} else {
ICorDebugValue corValue;
try {
corValue = CorILFrame.GetLocalVariable((uint)symVar.AddressField1);
} catch (COMException e) {
if ((uint)e.ErrorCode == 0x80131304) return new UnavailableValue(debugger, "Unavailable in optimized code");
throw;
}
return Value.CreateValue(debugger, corValue);
if (this.HasExpired) throw new CannotGetValueException("Function has expired");
try {
return CorILFrame.GetLocalVariable((uint)symVar.AddressField1);
} catch (COMException e) {
if ((uint)e.ErrorCode == 0x80131304) throw new CannotGetValueException("Unavailable in optimized code");
throw;
}
}
}

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs

@ -114,7 +114,7 @@ namespace Debugger @@ -114,7 +114,7 @@ namespace Debugger
if (!HasBeenLoaded) throw new DebuggerException("Thread has not started jet");
process.AssertPaused();
return Value.CreateValue(debugger, corThread.Object);
return new PersistentValue(debugger, corThread.Object).Value;
}
}

10
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs

@ -109,22 +109,20 @@ namespace Debugger @@ -109,22 +109,20 @@ namespace Debugger
return new Variable(debugger,
elementName,
new PersistentValue(delegate { return GetValueOfItem(indices, pValue); }));
new PersistentValue(debugger, delegate { return GetCorValueOfItem(indices, pValue); }));
}
Value GetValueOfItem(uint[] indices, PersistentValue pValue)
ICorDebugValue GetCorValueOfItem(uint[] indices, PersistentValue pValue)
{
ArrayValue updatedVal = pValue.Value as ArrayValue;
if (this.IsEquivalentValue(updatedVal)) {
ICorDebugValue element;
unsafe {
fixed (void* pIndices = indices) {
element = updatedVal.CorArrayValue.GetElement(rank, new IntPtr(pIndices));
return updatedVal.CorArrayValue.GetElement(rank, new IntPtr(pIndices));
}
}
return Value.CreateValue(debugger, element);
} else {
return new UnavailableValue(debugger, "Value is not array");
throw new CannotGetValueException("Value is not array");
}
}

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs

@ -168,7 +168,7 @@ namespace Debugger @@ -168,7 +168,7 @@ namespace Debugger
protected internal virtual void OnEvalComplete(bool successful)
{
// Eval result should be ICorDebugHandleValue so it should survive Continue()
result = Value.CreateValue(debugger, corEval.Result);
result = new PersistentValue(debugger, corEval.Result).Value;
debugeeStateWhenEvaluated = debugger.DebugeeState;

23
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs

@ -136,19 +136,16 @@ namespace Debugger @@ -136,19 +136,16 @@ namespace Debugger
field.Name,
field.IsStatic,
field.IsPublic,
new PersistentValue(delegate { return GetValueOfField(field, pValue); }));
new PersistentValue(debugger, delegate { return GetCorValueOfField(field, pValue); }));
}
}
Value GetValueOfField(FieldProps field, PersistentValue pValue)
ICorDebugValue GetCorValueOfField(FieldProps field, PersistentValue pValue)
{
Value updatedVal = pValue.Value;
if (updatedVal is UnavailableValue) return updatedVal;
if (this.IsEquivalentValue(updatedVal)) {
return GetValue(updatedVal, field);
} else {
return new UnavailableValue(debugger, "Object type changed");
}
if (updatedVal is UnavailableValue) throw new CannotGetValueException(updatedVal.AsString);
if (!this.IsEquivalentValue(updatedVal)) throw new CannotGetValueException("Object type changed");
return GetCorValue(updatedVal, field);
}
public IEnumerable<Variable> GetPropertyVariables(PersistentValue pValue)
@ -205,7 +202,7 @@ namespace Debugger @@ -205,7 +202,7 @@ namespace Debugger
objVal.ClassToken == this.ClassToken;
}
Value GetValue(Value val, FieldProps field)
ICorDebugValue GetCorValue(Value val, FieldProps field)
{
// Current frame is used to resolve context specific static values (eg. ThreadStatic)
ICorDebugFrame curFrame = null;
@ -214,15 +211,13 @@ namespace Debugger @@ -214,15 +211,13 @@ namespace Debugger
}
try {
ICorDebugValue fieldValue;
if (field.IsStatic) {
fieldValue = corClass.GetStaticFieldValue(field.Token, curFrame);
return corClass.GetStaticFieldValue(field.Token, curFrame);
} else {
fieldValue = (val.CorValue.CastTo<ICorDebugObjectValue>()).GetFieldValue(corClass, field.Token);
return (val.CorValue.CastTo<ICorDebugObjectValue>()).GetFieldValue(corClass, field.Token);
}
return Value.CreateValue(debugger, fieldValue);
} catch {
return new UnavailableValue(debugger);
throw new CannotGetValueException();
}
}

34
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentCorValue.cs

@ -16,19 +16,19 @@ namespace Debugger @@ -16,19 +16,19 @@ namespace Debugger
/// </summary>
public class PersistentCorValue
{
/// <summary>
/// Delegate that is used to get value. This delegate may be called at any time and should never return null.
/// </summary>
public delegate ICorDebugValue CorValueGetter();
NDebugger debugger;
public ICorDebugValue CorValue;
ICorDebugValue corValue;
// ICorDebugHandleValue can be used to get corValue back after Continue()
public ICorDebugHandleValue corHandleValue;
public PauseSession pauseSessionAtCreation;
public DebugeeState debugeeStateAtCreation;
PauseSession pauseSessionAtCreation;
DebugeeState debugeeStateAtCreation;
public NDebugger Debugger {
get {
return debugger;
}
}
public bool IsExpired {
get {
@ -40,19 +40,19 @@ namespace Debugger @@ -40,19 +40,19 @@ namespace Debugger
}
}
public ICorDebugValue CorValueProp {
public ICorDebugValue CorValue {
get {
if (this.IsExpired) throw new DebuggerException("CorValue has expired");
if (pauseSessionAtCreation == debugger.PauseSession) {
return CorValue;
return corValue;
} else {
if (corHandleValue == null) {
throw new DebuggerException("CorValue has expired");
} else {
CorValue = Value.DereferenceUnbox(corHandleValue.As<ICorDebugValue>());
corValue = PersistentValue.DereferenceUnbox(corHandleValue.As<ICorDebugValue>());
pauseSessionAtCreation = debugger.PauseSession;
return CorValue;
return corValue;
}
}
}
@ -64,7 +64,7 @@ namespace Debugger @@ -64,7 +64,7 @@ namespace Debugger
if (corHandleValue != null) return corHandleValue;
ICorDebugHeapValue2 heapValue = this.CorValueProp.As<ICorDebugHeapValue2>();
ICorDebugHeapValue2 heapValue = this.CorValue.As<ICorDebugHeapValue2>();
if (heapValue == null) { // TODO: Investigate - hmmm, value types are not at heap?
return null;
} else {
@ -77,10 +77,8 @@ namespace Debugger @@ -77,10 +77,8 @@ namespace Debugger
{
this.debugger = debugger;
if (corValue != null) {
if (corValue.Is<ICorDebugHandleValue>()) {
corHandleValue = corValue.As<ICorDebugHandleValue>();
}
this.CorValue = Value.DereferenceUnbox(corValue);
this.corHandleValue = corValue.As<ICorDebugHandleValue>();
this.corValue = PersistentValue.DereferenceUnbox(corValue);
}
this.pauseSessionAtCreation = debugger.PauseSession;
this.debugeeStateAtCreation = debugger.DebugeeState;

107
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentValue.cs

@ -12,7 +12,10 @@ using Debugger.Wrappers.CorDebug; @@ -12,7 +12,10 @@ using Debugger.Wrappers.CorDebug;
namespace Debugger
{
/// <summary>
/// PersistentValue is a container used to obtain the value of a given object even after continue.
/// PersistentValue is a container which holds data necessaty to obtain
/// the value of a given object even after continue. This level of
/// abstraction is necessary because the type of a value can change
/// (eg for local variable of type object)
/// </summary>
public class PersistentValue
{
@ -21,6 +24,11 @@ namespace Debugger @@ -21,6 +24,11 @@ namespace Debugger
/// </summary>
public delegate Value ValueGetter();
/// <summary>
/// Delegate that is used to get value. This delegate may be called at any time and should never return null.
/// </summary>
public delegate ICorDebugValue CorValueGetter();
ValueGetter getter;
@ -34,5 +42,102 @@ namespace Debugger @@ -34,5 +42,102 @@ namespace Debugger
{
this.getter = getter;
}
public PersistentValue(NDebugger debugger, ICorDebugValue corValue)
{
Value val = CreateValue(debugger, corValue);
this.getter = delegate { return val; };
}
public PersistentValue(NDebugger debugger, CorValueGetter corValueGetter)
{
this.getter = delegate {
try {
return CreateValue(debugger, corValueGetter());
} catch (CannotGetValueException e) {
return new UnavailableValue(debugger, e.Message);
}
};
}
internal static ICorDebugValue DereferenceUnbox(ICorDebugValue corValue)
{
if (corValue.Is<ICorDebugReferenceValue>()) {
int isNull = corValue.CastTo<ICorDebugReferenceValue>().IsNull;
if (isNull == 0) {
ICorDebugValue dereferencedValue;
try {
dereferencedValue = (corValue.CastTo<ICorDebugReferenceValue>()).Dereference();
} catch {
// Error during dereferencing
return null;
}
return DereferenceUnbox(dereferencedValue); // Try again
} else {
return null;
}
}
if (corValue.Is<ICorDebugBoxValue>()) {
return DereferenceUnbox(corValue.CastTo<ICorDebugBoxValue>().Object.CastTo<ICorDebugValue>()); // Try again
}
return corValue;
}
static Value CreateValue(NDebugger debugger, ICorDebugValue corValue)
{
ICorDebugValue derefed = DereferenceUnbox(corValue);
if (derefed == null) {
return new NullValue(debugger, new PersistentCorValue(debugger, corValue));
}
CorElementType type = Value.GetCorType(derefed);
switch(type)
{
case CorElementType.BOOLEAN:
case CorElementType.CHAR:
case CorElementType.I1:
case CorElementType.U1:
case CorElementType.I2:
case CorElementType.U2:
case CorElementType.I4:
case CorElementType.U4:
case CorElementType.I8:
case CorElementType.U8:
case CorElementType.R4:
case CorElementType.R8:
case CorElementType.I:
case CorElementType.U:
case CorElementType.STRING:
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, new PersistentCorValue(debugger, corValue));
case CorElementType.VALUETYPE:
case CorElementType.CLASS:
case CorElementType.OBJECT: // Short-cut for Class "System.Object"
return new ObjectValue(debugger, new PersistentCorValue(debugger, corValue));
default: // Unknown type
return new UnavailableValue(debugger, "Unknown value type");
}
}
}
class CannotGetValueException: System.Exception
{
public CannotGetValueException():this("Unable to get value")
{
}
public CannotGetValueException(string message):base(message)
{
}
}
}

70
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs

@ -34,7 +34,7 @@ namespace Debugger @@ -34,7 +34,7 @@ namespace Debugger
internal ICorDebugValue CorValue {
get {
return pCorValue.CorValueProp;
return pCorValue.CorValue;
}
}
@ -181,73 +181,5 @@ namespace Debugger @@ -181,73 +181,5 @@ namespace Debugger
if (manType == null) return "<unknown>";
return manType.ToString();
}
internal static ICorDebugValue DereferenceUnbox(ICorDebugValue corValue)
{
if (corValue.Is<ICorDebugReferenceValue>()) {
int isNull = corValue.CastTo<ICorDebugReferenceValue>().IsNull;
if (isNull == 0) {
ICorDebugValue dereferencedValue;
try {
dereferencedValue = (corValue.CastTo<ICorDebugReferenceValue>()).Dereference();
} catch {
// Error during dereferencing
return null;
}
return DereferenceUnbox(dereferencedValue); // Try again
} else {
return null;
}
}
if (corValue.Is<ICorDebugBoxValue>()) {
return DereferenceUnbox(corValue.CastTo<ICorDebugBoxValue>().Object.CastTo<ICorDebugValue>()); // Try again
}
return corValue;
}
internal static Value CreateValue(NDebugger debugger, ICorDebugValue corValue)
{
ICorDebugValue derefed = Value.DereferenceUnbox(corValue);
if (derefed == null) {
return new NullValue(debugger, new PersistentCorValue(debugger, corValue));
}
CorElementType type = Value.GetCorType(derefed);
switch(type)
{
case CorElementType.BOOLEAN:
case CorElementType.CHAR:
case CorElementType.I1:
case CorElementType.U1:
case CorElementType.I2:
case CorElementType.U2:
case CorElementType.I4:
case CorElementType.U4:
case CorElementType.I8:
case CorElementType.U8:
case CorElementType.R4:
case CorElementType.R8:
case CorElementType.I:
case CorElementType.U:
case CorElementType.STRING:
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, new PersistentCorValue(debugger, corValue));
case CorElementType.VALUETYPE:
case CorElementType.CLASS:
case CorElementType.OBJECT: // Short-cut for Class "System.Object"
return new ObjectValue(debugger, new PersistentCorValue(debugger, corValue));
default: // Unknown type
return new UnavailableValue(debugger, "Unknown value type");
}
}
}
}

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs

@ -98,7 +98,7 @@ namespace Debugger @@ -98,7 +98,7 @@ namespace Debugger
}
}
public Variable(NDebugger debugger, ICorDebugValue corValue, string name):this(Value.CreateValue(debugger, corValue), name)
public Variable(NDebugger debugger, ICorDebugValue corValue, string name):this(new PersistentValue(debugger, corValue).Value, name)
{
}

Loading…
Cancel
Save