|
|
@ -23,21 +23,17 @@ namespace Debugger |
|
|
|
/// Delegate that is used to get value. This delegate may be called at any time and should never return null.
|
|
|
|
/// Delegate that is used to get value. This delegate may be called at any time and should never return null.
|
|
|
|
/// </summary>
|
|
|
|
/// </summary>
|
|
|
|
public delegate Value ValueGetter(); |
|
|
|
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(); |
|
|
|
public delegate ICorDebugValue CorValueGetter(); |
|
|
|
|
|
|
|
public delegate bool IsExpiredDelegate(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NDebugger debugger; |
|
|
|
NDebugger debugger; |
|
|
|
|
|
|
|
|
|
|
|
ValueGetter getter; |
|
|
|
CorValueGetter corValueGetter; |
|
|
|
ICorDebugValue corValue; |
|
|
|
ValueGetter valueGetter; |
|
|
|
// ICorDebugHandleValue can be used to get corValue back after Continue()
|
|
|
|
IsExpiredDelegate isExpired; |
|
|
|
public ICorDebugHandleValue corHandleValue; |
|
|
|
|
|
|
|
PauseSession pauseSessionAtCreation; |
|
|
|
public ICorDebugValue initValue; |
|
|
|
DebugeeState debugeeStateAtCreation; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public NDebugger Debugger { |
|
|
|
public NDebugger Debugger { |
|
|
|
get { |
|
|
|
get { |
|
|
@ -45,37 +41,25 @@ namespace Debugger |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Value Value { |
|
|
|
public ICorDebugValue CorValue { |
|
|
|
get { |
|
|
|
get { |
|
|
|
return getter(); |
|
|
|
return corValueGetter(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public bool IsExpired { |
|
|
|
public Value Value { |
|
|
|
get { |
|
|
|
get { |
|
|
|
if (corHandleValue == null) { |
|
|
|
try { |
|
|
|
return pauseSessionAtCreation != debugger.PauseSession; |
|
|
|
return valueGetter(); |
|
|
|
} else { |
|
|
|
} catch (CannotGetValueException e) { |
|
|
|
return debugeeStateAtCreation != debugger.DebugeeState; |
|
|
|
return new UnavailableValue(debugger, e.Message); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public ICorDebugValue CorValue { |
|
|
|
public bool IsExpired { |
|
|
|
get { |
|
|
|
get { |
|
|
|
if (this.IsExpired) throw new DebuggerException("CorValue has expired"); |
|
|
|
return isExpired(); |
|
|
|
|
|
|
|
|
|
|
|
if (pauseSessionAtCreation == debugger.PauseSession) { |
|
|
|
|
|
|
|
return corValue; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (corHandleValue == null) { |
|
|
|
|
|
|
|
throw new DebuggerException("CorValue has expired"); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
corValue = PersistentValue.DereferenceUnbox(corHandleValue.As<ICorDebugValue>()); |
|
|
|
|
|
|
|
pauseSessionAtCreation = debugger.PauseSession; |
|
|
|
|
|
|
|
return corValue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -83,44 +67,46 @@ namespace Debugger |
|
|
|
get { |
|
|
|
get { |
|
|
|
if (this.IsExpired) throw new DebuggerException("CorValue has expired"); |
|
|
|
if (this.IsExpired) throw new DebuggerException("CorValue has expired"); |
|
|
|
|
|
|
|
|
|
|
|
if (corHandleValue != null) return corHandleValue; |
|
|
|
if (this.initValue != null && this.initValue.Is<ICorDebugHandleValue>()) { |
|
|
|
|
|
|
|
return this.initValue.As<ICorDebugHandleValue>(); |
|
|
|
ICorDebugHeapValue2 heapValue = this.CorValue.As<ICorDebugHeapValue2>(); |
|
|
|
} else if (this.initValue != null && this.initValue.Is<ICorDebugHeapValue2>()) { |
|
|
|
if (heapValue == null) { // TODO: Investigate - hmmm, value types are not at heap?
|
|
|
|
return this.initValue.As<ICorDebugHeapValue2>().CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION); |
|
|
|
return null; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return heapValue.CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION); |
|
|
|
return null; // Value type
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public PersistentValue(ValueGetter getter) |
|
|
|
public PersistentValue(ValueGetter getter) |
|
|
|
{ |
|
|
|
{ |
|
|
|
this.getter = getter; |
|
|
|
this.valueGetter = getter; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public PersistentValue(NDebugger debugger, ICorDebugValue corValue) |
|
|
|
public PersistentValue(NDebugger debugger, ICorDebugValue corValue) |
|
|
|
{ |
|
|
|
{ |
|
|
|
this.debugger = debugger; |
|
|
|
this.debugger = debugger; |
|
|
|
if (corValue != null) { |
|
|
|
this.initValue = corValue; |
|
|
|
this.corHandleValue = corValue.As<ICorDebugHandleValue>(); |
|
|
|
PauseSession pauseSessionAtCreation = debugger.PauseSession; |
|
|
|
this.corValue = PersistentValue.DereferenceUnbox(corValue); |
|
|
|
DebugeeState debugeeStateAtCreation = debugger.DebugeeState; |
|
|
|
} |
|
|
|
|
|
|
|
this.pauseSessionAtCreation = debugger.PauseSession; |
|
|
|
this.corValueGetter = delegate { |
|
|
|
this.debugeeStateAtCreation = debugger.DebugeeState; |
|
|
|
if (this.IsExpired) throw new DebuggerException("CorValue has expired"); |
|
|
|
|
|
|
|
|
|
|
|
this.getter = delegate { return CreateValue(debugger, corValue); }; |
|
|
|
return PersistentValue.DereferenceUnbox(this.initValue); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
this.isExpired = delegate { |
|
|
|
|
|
|
|
if (this.initValue != null && this.initValue.Is<ICorDebugHandleValue>()) { |
|
|
|
|
|
|
|
return debugeeStateAtCreation != debugger.DebugeeState; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return pauseSessionAtCreation != debugger.PauseSession; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
this.valueGetter = delegate { return CreateValue(debugger, corValue); }; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public PersistentValue(NDebugger debugger, CorValueGetter corValueGetter) |
|
|
|
public PersistentValue(NDebugger debugger, CorValueGetter corValueGetter) |
|
|
|
{ |
|
|
|
{ |
|
|
|
this.getter = delegate { |
|
|
|
this.valueGetter = delegate { return CreateValue(debugger, corValueGetter()); }; |
|
|
|
try { |
|
|
|
|
|
|
|
return CreateValue(debugger, corValueGetter()); |
|
|
|
|
|
|
|
} catch (CannotGetValueException e) { |
|
|
|
|
|
|
|
return new UnavailableValue(debugger, e.Message); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal static ICorDebugValue DereferenceUnbox(ICorDebugValue corValue) |
|
|
|
internal static ICorDebugValue DereferenceUnbox(ICorDebugValue corValue) |
|
|
|