Browse Source

Made the debugger is more aware of AppDomains. Most objects now know which appdomain they belong to.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4517 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 16 years ago
parent
commit
4dca3978ca
  1. 10
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Expressions/AstEvaluator.cs
  2. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ValueNode.cs
  3. 12
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/ICorDebug.cs
  4. 2
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/DebuggerHelpers.cs
  5. 17
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/AppDomain.cs
  6. 17
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/AppDomainCollection.cs
  7. 60
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs
  8. 23
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Module.cs
  9. 10
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs
  10. 27
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs
  11. 23
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs
  12. 6
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebuggeeState.cs
  13. 1
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/PauseSession.cs
  14. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/PrimitiveExpression.cs
  15. 13
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs
  16. 78
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs
  17. 9
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/MemberInfo.cs
  18. 8
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/MethodInfo.cs
  19. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.Array.cs
  20. 6
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.Object.cs
  21. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.Primitive.cs
  22. 29
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs

10
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Expressions/AstEvaluator.cs

@ -66,7 +66,7 @@ namespace Debugger.AddIn @@ -66,7 +66,7 @@ namespace Debugger.AddIn
if (i > 0) sb.Append(", ");
PropertyInfo itemProperty = val.Type.GetProperty("Item");
// TODO: Appdomain constriant for create value
Value item = val.GetPropertyValue(itemProperty, Eval.CreateValue(val.Process, i));
Value item = val.GetPropertyValue(itemProperty, Eval.CreateValue(val.AppDomain, i));
sb.Append(FormatValue(item));
}
sb.Append("}");
@ -196,7 +196,7 @@ namespace Debugger.AddIn @@ -196,7 +196,7 @@ namespace Debugger.AddIn
if (target.Type.IsPrimitive && target.PrimitiveValue is string) {
if (indexes.Count == 1 && indexes[0].Type.IsInteger) {
int index = (int)indexes[0].PrimitiveValue;
return Eval.CreateValue(context.Process, ((string)target.PrimitiveValue)[index]);
return Eval.CreateValue(context.AppDomain, ((string)target.PrimitiveValue)[index]);
} else {
throw new GetValueException("Expected single integer index");
}
@ -253,7 +253,7 @@ namespace Debugger.AddIn @@ -253,7 +253,7 @@ namespace Debugger.AddIn
public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
{
return Eval.CreateValue(context.Process, primitiveExpression.Value);
return Eval.CreateValue(context.AppDomain, primitiveExpression.Value);
}
public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)
@ -315,7 +315,7 @@ namespace Debugger.AddIn @@ -315,7 +315,7 @@ namespace Debugger.AddIn
if (result == null) throw new GetValueException("Unsuppored unary expression " + op);
return Eval.CreateValue(context.Process, result);
return Eval.CreateValue(context.AppDomain, result);
}
public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
@ -326,7 +326,7 @@ namespace Debugger.AddIn @@ -326,7 +326,7 @@ namespace Debugger.AddIn
object result = VisitBinaryOperatorExpressionInternal(left, right, binaryOperatorExpression.Op);
// Conver long to int if possible
if (result is long && int.MinValue <= (long)result && (long)result <= int.MaxValue) result = (int)(long)result;
return Eval.CreateValue(context.Process, result);
return Eval.CreateValue(context.AppDomain, result);
}
public object VisitBinaryOperatorExpressionInternal(Value leftValue, Value rightValue, BinaryOperatorType op)

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/ValueNode.cs

@ -111,7 +111,7 @@ namespace Debugger.AddIn.TreeModel @@ -111,7 +111,7 @@ namespace Debugger.AddIn.TreeModel
}
if (DebuggingOptions.Instance.ICorDebugVisualizerEnabled) {
AbstractNode info = ICorDebug.GetDebugInfoRoot(val.Process, val.CorValue);
AbstractNode info = ICorDebug.GetDebugInfoRoot(val.AppDomain, val.CorValue);
this.ChildNodes = PrependNode(info, this.ChildNodes);
}

12
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/ICorDebug.cs

@ -49,12 +49,12 @@ namespace Debugger.AddIn.TreeModel @@ -49,12 +49,12 @@ namespace Debugger.AddIn.TreeModel
}
}
public static InfoNode GetDebugInfoRoot(Process process, ICorDebugValue corValue)
public static InfoNode GetDebugInfoRoot(AppDomain appDomain, ICorDebugValue corValue)
{
return new InfoNode("ICorDebug", "", GetDebugInfo(process, corValue));
return new InfoNode("ICorDebug", "", GetDebugInfo(appDomain, corValue));
}
public static List<AbstractNode> GetDebugInfo(Process process, ICorDebugValue corValue)
public static List<AbstractNode> GetDebugInfo(AppDomain appDomain, ICorDebugValue corValue)
{
List<AbstractNode> items = new List<AbstractNode>();
@ -70,7 +70,7 @@ namespace Debugger.AddIn.TreeModel @@ -70,7 +70,7 @@ namespace Debugger.AddIn.TreeModel
ICorDebugValue2 corValue2 = corValue.CastTo<ICorDebugValue2>();
string fullname;
try {
fullname = DebugType.Create(process, corValue2.ExactType).FullName;
fullname = DebugType.Create(appDomain, corValue2.ExactType).FullName;
} catch (DebuggerException e) {
fullname = e.Message;
}
@ -100,7 +100,7 @@ namespace Debugger.AddIn.TreeModel @@ -100,7 +100,7 @@ namespace Debugger.AddIn.TreeModel
if (refValue.IsNull == 0) {
info.AddChild("Value", refValue.Value.ToString("X8"));
if (refValue.Dereference() != null) {
info.AddChild("Dereference", "", GetDebugInfo(process, refValue.Dereference()));
info.AddChild("Dereference", "", GetDebugInfo(appDomain, refValue.Dereference()));
} else {
info.AddChild("Dereference", "N/A");
}
@ -130,7 +130,7 @@ namespace Debugger.AddIn.TreeModel @@ -130,7 +130,7 @@ namespace Debugger.AddIn.TreeModel
if (corValue.Is<ICorDebugBoxValue>()) {
InfoNode info = new InfoNode("ICorDebugBoxValue", "");
ICorDebugBoxValue boxValue = corValue.CastTo<ICorDebugBoxValue>();
info.AddChild("Object", "", GetDebugInfo(process, boxValue.Object.CastTo<ICorDebugValue>()));
info.AddChild("Object", "", GetDebugInfo(appDomain, boxValue.Object.CastTo<ICorDebugValue>()));
items.Add(info);
}
if (corValue.Is<ICorDebugStringValue>()) {

2
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Visualizers/Utils/DebuggerHelpers.cs

@ -45,7 +45,7 @@ namespace Debugger.AddIn.Visualizers.Utils @@ -45,7 +45,7 @@ namespace Debugger.AddIn.Visualizers.Utils
{
if (DebuggerHelpers.hashCodeMethod == null)
{
DebugType typeRuntimeHelpers = DebugType.Create(WindowsDebugger.CurrentProcess, null, "System.Runtime.CompilerServices.RuntimeHelpers");
DebugType typeRuntimeHelpers = DebugType.Create(value.AppDomain, "System.Runtime.CompilerServices.RuntimeHelpers");
DebuggerHelpers.hashCodeMethod = typeRuntimeHelpers.GetMember("GetHashCode", BindingFlags.Public | BindingFlags.Static | BindingFlags.Method | BindingFlags.IncludeSuperType) as MethodInfo;
if (DebuggerHelpers.hashCodeMethod == null)
{

17
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/AppDomain.cs

@ -17,10 +17,9 @@ namespace Debugger @@ -17,10 +17,9 @@ namespace Debugger
ICorDebugAppDomain corAppDomain;
[Debugger.Tests.Ignore]
public Process Process {
get {
return process;
}
get { return process; }
}
public uint ID {
@ -29,6 +28,18 @@ namespace Debugger @@ -29,6 +28,18 @@ namespace Debugger
}
}
public Module Mscorlib {
get {
foreach(Module m in Process.Modules) {
if (m.FullPath == "mscorlib.dll" &&
m.AppDomain == this) {
return m;
}
}
throw new DebuggerException("Mscorlib not loaded");
}
}
internal ICorDebugAppDomain CorDebugAppDomain {
get {
return corAppDomain;

17
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/AppDomainCollection.cs

@ -12,18 +12,19 @@ using Debugger.Wrappers.CorDebug; @@ -12,18 +12,19 @@ using Debugger.Wrappers.CorDebug;
namespace Debugger
{
public partial class Process
public class AppDomainCollection: CollectionWithEvents<AppDomain>
{
List<AppDomain> appDomainCollection = new List<AppDomain>();
public AppDomainCollection(NDebugger dbgr): base(dbgr) {}
public AppDomain GetAppDomain(ICorDebugAppDomain corAppDomain)
{
foreach(AppDomain a in appDomainCollection) {
if (a.CorDebugAppDomain.Equals(corAppDomain)) {
return a;
public AppDomain this[ICorDebugAppDomain corAppDomain] {
get {
foreach(AppDomain a in this) {
if (a.CorDebugAppDomain.Equals(corAppDomain)) {
return a;
}
}
throw new DebuggerException("AppDomain not found");
}
throw new DebuggerException("AppDomain not found");
}
}
}

60
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs

@ -29,12 +29,19 @@ namespace Debugger @@ -29,12 +29,19 @@ namespace Debugger
{
delegate void EvalStarter(Eval eval);
AppDomain appDomain;
Process process;
string description;
ICorDebugEval corEval;
Value result;
EvalState state;
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
get { return appDomain; }
}
[Debugger.Tests.Ignore]
public Process Process {
get { return process; }
@ -75,20 +82,20 @@ namespace Debugger @@ -75,20 +82,20 @@ namespace Debugger
}
}
Eval(Process process, string description, ICorDebugEval corEval)
Eval(AppDomain appDomain, string description, ICorDebugEval corEval)
{
this.process = process;
this.appDomain = appDomain;
this.process = appDomain.Process;
this.description = description;
this.corEval = corEval;
this.state = EvalState.Evaluating;
}
/// <exception cref="GetValueException">Can not evaluate because no thread is selected</exception>
static ICorDebugEval CreateCorEval(Process process)
static ICorDebugEval CreateCorEval(AppDomain appDomain)
{
process.AssertPaused();
appDomain.Process.AssertPaused();
Thread targetThread = process.SelectedThread;
Thread targetThread = appDomain.Process.SelectedThread;
if (targetThread == null) {
throw new GetValueException("Can not evaluate because no thread is selected");
@ -106,12 +113,11 @@ namespace Debugger @@ -106,12 +113,11 @@ namespace Debugger
return targetThread.CorThread.CreateEval();
}
/// <exception cref="GetValueException">Can not evaluate in optimized code</exception>
static Eval CreateEval(Process process, string description, EvalStarter evalStarter)
static Eval CreateEval(AppDomain appDomain, string description, EvalStarter evalStarter)
{
ICorDebugEval corEval = CreateCorEval(process);
ICorDebugEval corEval = CreateCorEval(appDomain);
Eval newEval = new Eval(process, description, corEval);
Eval newEval = new Eval(appDomain, description, corEval);
try {
evalStarter(newEval);
@ -135,8 +141,8 @@ namespace Debugger @@ -135,8 +141,8 @@ namespace Debugger
}
}
process.ActiveEvals.Add(newEval);
process.AsyncContinue(DebuggeeStateAction.Keep);
appDomain.Process.ActiveEvals.Add(newEval);
appDomain.Process.AsyncContinue(DebuggeeStateAction.Keep);
return newEval;
}
@ -188,16 +194,16 @@ namespace Debugger @@ -188,16 +194,16 @@ namespace Debugger
} else {
state = EvalState.EvaluatedException;
}
result = new Value(process, new EmptyExpression(), corEval.Result);
result = new Value(AppDomain, new EmptyExpression(), corEval.Result);
}
}
#region Convenience methods
/// <summary> Synchronously calls a function and returns its return value </summary>
public static Value InvokeMethod(Process process, uint? domainID, System.Type type, string name, Value thisValue, Value[] args)
public static Value InvokeMethod(AppDomain appDomain, System.Type type, string name, Value thisValue, Value[] args)
{
return InvokeMethod(MethodInfo.GetFromName(process, domainID, type, name, args.Length), thisValue, args);
return InvokeMethod(MethodInfo.GetFromName(appDomain, type, name, args.Length), thisValue, args);
}
#endregion
@ -215,7 +221,7 @@ namespace Debugger @@ -215,7 +221,7 @@ namespace Debugger
public static Eval AsyncInvokeMethod(MethodInfo method, Value thisValue, Value[] args)
{
return CreateEval(
method.Process,
method.AppDomain,
"Function call: " + method.FullName,
delegate(Eval eval) {
MethodInvokeStarter(eval, method, thisValue, args);
@ -259,18 +265,18 @@ namespace Debugger @@ -259,18 +265,18 @@ namespace Debugger
);
}
public static Value CreateValue(Process process, object value)
public static Value CreateValue(AppDomain appDomain, object value)
{
if (value == null) {
ICorDebugClass corClass = DebugType.Create(process, null, typeof(object).FullName).CorType.Class;
ICorDebugEval corEval = CreateCorEval(process);
ICorDebugClass corClass = DebugType.Create(appDomain, typeof(object).FullName).CorType.Class;
ICorDebugEval corEval = CreateCorEval(appDomain);
ICorDebugValue corValue = corEval.CreateValue((uint)CorElementType.CLASS, corClass);
return new Value(process, new Expressions.PrimitiveExpression(value), corValue);
return new Value(appDomain, new Expressions.PrimitiveExpression(value), corValue);
} else if (value is string) {
return Eval.NewString(process, (string)value);
return Eval.NewString(appDomain, (string)value);
} else {
// TODO: Check if it is primitive type
Value val = Eval.NewObjectNoConstructor(DebugType.Create(process, null, value.GetType().FullName));
Value val = Eval.NewObjectNoConstructor(DebugType.Create(appDomain, value.GetType().FullName));
val.PrimitiveValue = value;
return val;
}
@ -304,17 +310,17 @@ namespace Debugger @@ -304,17 +310,17 @@ namespace Debugger
#region Convenience methods
public static Value NewString(Process process, string textToCreate)
public static Value NewString(AppDomain appDomain, string textToCreate)
{
return AsyncNewString(process, textToCreate).WaitForResult();
return AsyncNewString(appDomain, textToCreate).WaitForResult();
}
#endregion
public static Eval AsyncNewString(Process process, string textToCreate)
public static Eval AsyncNewString(AppDomain appDomain, string textToCreate)
{
return CreateEval(
process,
appDomain,
"New string: " + textToCreate,
delegate(Eval eval) {
eval.CorEval.CastTo<ICorDebugEval2>().NewStringWithLength(textToCreate, (uint)textToCreate.Length);
@ -334,7 +340,7 @@ namespace Debugger @@ -334,7 +340,7 @@ namespace Debugger
public static Eval AsyncNewObjectNoConstructor(DebugType debugType)
{
return CreateEval(
debugType.Process,
debugType.AppDomain,
"New object: " + debugType.FullName,
delegate(Eval eval) {
eval.CorEval.CastTo<ICorDebugEval2>().NewParameterizedObjectNoConstructor(debugType.CorType.Class, (uint)debugType.GenericArguments.Count, debugType.GenericArgumentsAsCorDebugType);

23
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Module.cs

@ -16,7 +16,8 @@ namespace Debugger @@ -16,7 +16,8 @@ namespace Debugger
{
public class Module: DebuggerObject, IDisposable
{
Process process;
AppDomain appDomain;
Process process;
bool unloaded = false;
string fullPath;
@ -35,17 +36,18 @@ namespace Debugger @@ -35,17 +36,18 @@ namespace Debugger
}
}
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
get { return appDomain; }
}
[Debugger.Tests.Ignore]
public Process Process {
get {
return process;
}
get { return process; }
}
NDebugger Debugger {
get {
return this.Process.Debugger;
}
get { return this.AppDomain.Process.Debugger; }
}
public MetaDataImport MetaData {
@ -164,9 +166,10 @@ namespace Debugger @@ -164,9 +166,10 @@ namespace Debugger
return names;
}
internal Module(Process process, ICorDebugModule pModule)
internal Module(AppDomain appDomain, ICorDebugModule pModule)
{
this.process = process;
this.appDomain = appDomain;
this.process = appDomain.Process;
corModule = pModule;
@ -207,7 +210,7 @@ namespace Debugger @@ -207,7 +210,7 @@ namespace Debugger
public void ResetJustMyCodeStatus()
{
uint unused = 0;
if (this.Process.Options.StepOverNoSymbols && !this.HasSymbols) {
if (process.Options.StepOverNoSymbols && !this.HasSymbols) {
// Optimization - set the code as non-user right away
corModule.CastTo<ICorDebugModule2>().SetJMCStatus(0, 0, ref unused);
return;

10
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs

@ -21,6 +21,7 @@ namespace Debugger @@ -21,6 +21,7 @@ namespace Debugger
EvalCollection activeEvals;
ModuleCollection modules;
ThreadCollection threads;
AppDomainCollection appDomains;
#region IExpirable
@ -90,6 +91,10 @@ namespace Debugger @@ -90,6 +91,10 @@ namespace Debugger
set { this.Threads.Selected = value; }
}
public AppDomainCollection AppDomains {
get { return appDomains; }
}
internal Process(NDebugger debugger, ICorDebugProcess corProcess)
{
this.debugger = debugger;
@ -100,6 +105,7 @@ namespace Debugger @@ -100,6 +105,7 @@ namespace Debugger
activeEvals = new EvalCollection(debugger);
modules = new ModuleCollection(debugger);
threads = new ThreadCollection(debugger);
appDomains = new AppDomainCollection(debugger);
}
internal ICorDebugProcess CorProcess {
@ -233,9 +239,7 @@ namespace Debugger @@ -233,9 +239,7 @@ namespace Debugger
[Debugger.Tests.Ignore]
public Process Process {
get {
return process;
}
get { return process; }
}
public ProcessEventArgs(Process process): base(process == null ? null : process.Debugger)

27
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs

@ -21,8 +21,8 @@ namespace Debugger @@ -21,8 +21,8 @@ namespace Debugger
/// </summary>
public class StackFrame: DebuggerObject
{
Process process;
Thread thread;
Process process;
ICorDebugILFrame corILFrame;
object corILFramePauseSession;
@ -33,11 +33,14 @@ namespace Debugger @@ -33,11 +33,14 @@ namespace Debugger
uint frameIndex;
/// <summary> The process in which this stack frame is executed </summary>
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
get { return thread.AppDomain; }
}
[Debugger.Tests.Ignore]
public Process Process {
get {
return process;
}
get { return process; }
}
/// <summary> Get the method which this stack frame is executing </summary>
@ -95,7 +98,7 @@ namespace Debugger @@ -95,7 +98,7 @@ namespace Debugger
this.frameIndex = frameIndex;
DebugType debugType = DebugType.Create(
this.Process,
this.AppDomain,
corFunction.Class,
corILFrame.CastTo<ICorDebugILFrame2>().EnumerateTypeParameters().ToList().ToArray()
);
@ -110,7 +113,7 @@ namespace Debugger @@ -110,7 +113,7 @@ namespace Debugger
internal ICorDebugILFrame CorILFrame {
get {
if (corILFramePauseSession != this.Process.PauseSession) {
if (corILFramePauseSession != process.PauseSession) {
// Reobtain the stackframe
StackFrame stackFrame = this.Thread.GetStackFrameAt(chainIndex, frameIndex);
if (stackFrame.MethodInfo != this.MethodInfo) throw new DebuggerException("The stack frame on the thread does not represent the same method anymore");
@ -138,21 +141,21 @@ namespace Debugger @@ -138,21 +141,21 @@ namespace Debugger
public void StepInto()
{
AsyncStepInto();
this.Process.WaitForPause();
process.WaitForPause();
}
/// <summary> Step over next instruction </summary>
public void StepOver()
{
AsyncStepOver();
this.Process.WaitForPause();
process.WaitForPause();
}
/// <summary> Step out of the stack frame </summary>
public void StepOut()
{
AsyncStepOut();
this.Process.WaitForPause();
process.WaitForPause();
}
/// <summary> Step into next instruction </summary>
@ -263,7 +266,7 @@ namespace Debugger @@ -263,7 +266,7 @@ namespace Debugger
/// </summary>
public Value GetThisValue()
{
return new Value(process, new ThisReferenceExpression(), GetThisCorValue());
return new Value(thread.AppDomain, new ThisReferenceExpression(), GetThisCorValue());
}
ICorDebugValue GetThisCorValue()
@ -300,7 +303,7 @@ namespace Debugger @@ -300,7 +303,7 @@ namespace Debugger
/// <param name="index"> Zero-based index </param>
public Value GetArgumentValue(int index)
{
return new Value(process, new ParameterIdentifierExpression(this.MethodInfo, index), GetArgumentCorValue(index));
return new Value(thread.AppDomain, new ParameterIdentifierExpression(this.MethodInfo, index), GetArgumentCorValue(index));
}
ICorDebugValue GetArgumentCorValue(int index)
@ -359,7 +362,7 @@ namespace Debugger @@ -359,7 +362,7 @@ namespace Debugger
/// <summary> Returns value of give local variable </summary>
public Value GetLocalVariableValue(ISymUnmanagedVariable symVar)
{
return new Value(this.Process, new LocalVariableIdentifierExpression(MethodInfo, symVar), GetLocalVariableCorValue(symVar));
return new Value(this.AppDomain, new LocalVariableIdentifierExpression(MethodInfo, symVar), GetLocalVariableCorValue(symVar));
}
ICorDebugValue GetLocalVariableCorValue(ISymUnmanagedVariable symVar)

23
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs

@ -17,7 +17,8 @@ namespace Debugger @@ -17,7 +17,8 @@ namespace Debugger
{
public partial class Thread: DebuggerObject
{
Process process;
AppDomain appDomain;
Process process;
uint id;
ICorDebugThread corThread;
@ -36,6 +37,11 @@ namespace Debugger @@ -36,6 +37,11 @@ namespace Debugger
public event EventHandler<ThreadEventArgs> NameChanged;
public event EventHandler<ThreadEventArgs> Exited;
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
get { return appDomain; }
}
[Debugger.Tests.Ignore]
public Process Process {
get { return process; }
@ -82,16 +88,17 @@ namespace Debugger @@ -82,16 +88,17 @@ namespace Debugger
}
}
internal Thread(Process process, ICorDebugThread corThread)
internal Thread(AppDomain appDomain, ICorDebugThread corThread)
{
this.process = process;
this.appDomain = appDomain;
this.process = appDomain.Process;
this.corThread = corThread;
this.id = CorThread.ID;
}
internal void NotifyExited()
{
if (this.hasExited) throw new DebuggerException("Already exited");
if (this.HasExited) throw new DebuggerException("Already exited");
process.TraceMessage("Thread " + this.ID + " exited");
if (process.SelectedThread == this) {
@ -159,7 +166,7 @@ namespace Debugger @@ -159,7 +166,7 @@ namespace Debugger
process.AssertPaused();
ICorDebugValue corValue = this.CorThread.Object;
return new Value(process, new EmptyExpression(), corValue);
return new Value(appDomain, new EmptyExpression(), corValue);
}
}
@ -191,7 +198,7 @@ namespace Debugger @@ -191,7 +198,7 @@ namespace Debugger
public Exception CurrentException {
get {
if (currentException_DebuggeeState == this.Process.DebuggeeState) {
if (currentException_DebuggeeState == process.DebuggeeState) {
return currentException;
} else {
return null;
@ -240,8 +247,8 @@ namespace Debugger @@ -240,8 +247,8 @@ namespace Debugger
return false;
}
Process.AsyncContinue(DebuggeeStateAction.Keep);
Process.WaitForPause();
process.AsyncContinue(DebuggeeStateAction.Keep);
process.WaitForPause();
return true;
}

6
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/DebuggeeState.cs

@ -21,11 +21,9 @@ namespace Debugger @@ -21,11 +21,9 @@ namespace Debugger
{
Process process;
[Tests.Ignore]
[Debugger.Tests.Ignore]
public Process Process {
get {
return process;
}
get { return process; }
}
public DebuggeeState(Process process)

1
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Debugger/PauseSession.cs

@ -16,6 +16,7 @@ namespace Debugger @@ -16,6 +16,7 @@ namespace Debugger
Process process;
PausedReason pausedReason;
[Debugger.Tests.Ignore]
public Process Process {
get { return process; }
}

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/PrimitiveExpression.cs

@ -35,7 +35,7 @@ namespace Debugger.Expressions @@ -35,7 +35,7 @@ namespace Debugger.Expressions
protected override Value EvaluateInternal(StackFrame context)
{
return Eval.CreateValue(context.Process, this.Value);
return Eval.CreateValue(context.AppDomain, this.Value);
}
#region GetHashCode and Equals

13
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs

@ -29,9 +29,7 @@ namespace Debugger @@ -29,9 +29,7 @@ namespace Debugger
[Debugger.Tests.Ignore]
public Process Process {
get {
return process;
}
get { return process; }
}
public bool IsInCallback {
@ -321,6 +319,7 @@ namespace Debugger @@ -321,6 +319,7 @@ namespace Debugger
EnterCallback(PausedReason.Other, "CreateAppDomain", pAppDomain);
pAppDomain.Attach();
process.AppDomains.Add(new AppDomain(process, pAppDomain));
ExitCallback();
}
@ -336,7 +335,7 @@ namespace Debugger @@ -336,7 +335,7 @@ namespace Debugger
{
EnterCallback(PausedReason.Other, "LoadModule " + pModule.Name, pAppDomain);
process.Modules.Add(new Module(process, pModule));
process.Modules.Add(new Module(process.AppDomains[pAppDomain], pModule));
ExitCallback();
}
@ -368,7 +367,7 @@ namespace Debugger @@ -368,7 +367,7 @@ namespace Debugger
// and we continue from this callback anyway
EnterCallback(PausedReason.Other, "CreateThread " + pThread.ID, pAppDomain);
process.Threads.Add(new Thread(process, pThread));
process.Threads.Add(new Thread(process.AppDomains[pAppDomain], pThread));
ExitCallback();
}
@ -433,6 +432,8 @@ namespace Debugger @@ -433,6 +432,8 @@ namespace Debugger
{
EnterCallback(PausedReason.Other, "ExitAppDomain", pAppDomain);
process.AppDomains.Remove(process.AppDomains[pAppDomain]);
ExitCallback();
}
@ -477,7 +478,7 @@ namespace Debugger @@ -477,7 +478,7 @@ namespace Debugger
// Watch out for the zeros and null!
// Exception -> Exception2(pAppDomain, pThread, null, 0, exceptionType, 0);
process.SelectedThread.CurrentException = new Exception(new Value(process, new Expressions.CurrentExceptionExpression(), process.SelectedThread.CorThread.CurrentException));
process.SelectedThread.CurrentException = new Exception(new Value(process.AppDomains[pAppDomain], new Expressions.CurrentExceptionExpression(), process.SelectedThread.CorThread.CurrentException));
process.SelectedThread.CurrentException_DebuggeeState = process.DebuggeeState;
process.SelectedThread.CurrentExceptionType = (ExceptionType)exceptionType;
process.SelectedThread.CurrentExceptionIsUnhandled = (ExceptionType)exceptionType == ExceptionType.Unhandled;

78
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs

@ -26,7 +26,8 @@ namespace Debugger.MetaData @@ -26,7 +26,8 @@ namespace Debugger.MetaData
/// </remarks>
public partial class DebugType: DebuggerObject
{
Process process;
AppDomain appDomain;
Process process;
ICorDebugType corType;
CorElementType corElementType;
string name;
@ -53,12 +54,15 @@ namespace Debugger.MetaData @@ -53,12 +54,15 @@ namespace Debugger.MetaData
}
}
/// <summary> Gets the process in which the type was loaded </summary>
/// <summary> Gets the appdomain in which the type was loaded </summary>
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
get { return appDomain; }
}
[Debugger.Tests.Ignore]
public Process Process {
get {
return process;
}
get { return process; }
}
internal ICorDebugType CorType {
@ -310,29 +314,30 @@ namespace Debugger.MetaData @@ -310,29 +314,30 @@ namespace Debugger.MetaData
}
// corType.Base does not work for arrays
if (this.IsArray) {
return DebugType.Create(this.Process, AppDomainID, "System.Array");
return DebugType.Create(this.AppDomain, "System.Array");
}
// corType.Base does not work for primitive types
if (this.IsPrimitive) {
return DebugType.Create(this.Process, AppDomainID, "System.Object");
return DebugType.Create(this.AppDomain, "System.Object");
}
if (this.IsPointer || this.IsVoid) {
return null;
}
ICorDebugType baseType = corType.Base;
if (baseType != null) {
return Create(process, baseType);
return Create(this.AppDomain, baseType);
} else {
return null;
}
}
}
DebugType(Process process, ICorDebugType corType)
DebugType(AppDomain appDomain, ICorDebugType corType)
{
if (corType == null) throw new ArgumentNullException("corType");
this.process = process;
this.appDomain = appDomain;
this.process = appDomain.Process;
this.corType = corType;
this.corElementType = (CorElementType)corType.Type;
@ -343,7 +348,7 @@ namespace Debugger.MetaData @@ -343,7 +348,7 @@ namespace Debugger.MetaData
if (this.IsClass || this.IsValueType || this.IsArray || this.IsPointer) {
foreach(ICorDebugType t in corType.EnumerateTypeParameters().Enumerator) {
typeArguments.Add(DebugType.Create(process, t));
typeArguments.Add(DebugType.Create(appDomain, t));
}
}
@ -360,7 +365,7 @@ namespace Debugger.MetaData @@ -360,7 +365,7 @@ namespace Debugger.MetaData
{
CorTokenType tokenType = (CorTokenType)(token & 0xFF000000);
if (tokenType == CorTokenType.TypeDef || tokenType == CorTokenType.TypeRef) {
return Create(module.Process, GetCorClass(module, token));
return Create(module.AppDomain, GetCorClass(module, token));
} else if (tokenType == CorTokenType.TypeSpec) {
Blob typeSpecBlob = module.MetaData.GetTypeSpecFromToken(token);
return Create(module, typeSpecBlob.GetData(), declaringType);
@ -388,21 +393,21 @@ namespace Debugger.MetaData @@ -388,21 +393,21 @@ namespace Debugger.MetaData
{
System.Type sysType = CorElementTypeToManagedType((CorElementType)(uint)sigType.ElementType);
if (sysType != null) {
return Create(module.Process, module.AppDomainID, sysType.FullName);
return Create(module.AppDomain, sysType.FullName);
}
if (sigType.ElementType == Mono.Cecil.Metadata.ElementType.Object) {
return Create(module.Process, module.AppDomainID, "System.Object");
return Create(module.AppDomain, "System.Object");
}
if (sigType is CLASS) {
ICorDebugClass corClass = GetCorClass(module, ((CLASS)sigType).Type.ToUInt());
return Create(module.Process, corClass);
return Create(module.AppDomain, corClass);
}
if (sigType is VALUETYPE) {
ICorDebugClass corClass = GetCorClass(module, ((VALUETYPE)sigType).Type.ToUInt());
return Create(module.Process, corClass);
return Create(module.AppDomain, corClass);
}
// Numbered generic reference
@ -413,7 +418,7 @@ namespace Debugger.MetaData @@ -413,7 +418,7 @@ namespace Debugger.MetaData
// Numbered generic reference
if (sigType is MVAR) {
return Create(module.Process, module.AppDomainID, "System.Object");
return Create(module.AppDomain, "System.Object");
}
if (sigType is GENERICINST) {
@ -426,15 +431,15 @@ namespace Debugger.MetaData @@ -426,15 +431,15 @@ namespace Debugger.MetaData
}
ICorDebugType genInstance = corClass.CastTo<ICorDebugClass2>().GetParameterizedType((uint)classOrValueType, genArgs);
return Create(module.Process, genInstance);
return Create(module.AppDomain, genInstance);
}
throw new NotImplementedException(sigType.ElementType.ToString());
}
public static DebugType Create(Process process, uint? domainID, string fullTypeName)
public static DebugType Create(AppDomain appDomain, string fullTypeName)
{
return Create(process, GetCorClass(process, domainID, fullTypeName, 0));
return Create(appDomain, GetCorClass(appDomain, fullTypeName, 0));
}
static ICorDebugClass GetCorClass(Module module, uint token)
@ -452,17 +457,16 @@ namespace Debugger.MetaData @@ -452,17 +457,16 @@ namespace Debugger.MetaData
ICorDebugClass enclosingClass = GetCorClass(module, refProps.ResolutionScope);
enclosingClassTk = enclosingClass.Token;
}
return GetCorClass(module.Process, module.AppDomainID, fullName, enclosingClassTk);
return GetCorClass(module.AppDomain, fullName, enclosingClassTk);
} else {
throw new DebuggerException("TypeDef or TypeRef expected");
}
}
static ICorDebugClass GetCorClass(Process process, uint? domainID, string fullTypeName, uint enclosingClass)
static ICorDebugClass GetCorClass(AppDomain appDomain, string fullTypeName, uint enclosingClass)
{
//
foreach(Module module in process.Modules) {
if (!domainID.HasValue || domainID == module.CorModule.Assembly.AppDomain.ID) {
foreach(Module module in appDomain.Process.Modules) {
if (module.AppDomain == appDomain) {
try {
uint token = module.MetaData.FindTypeDefPropsByName(fullTypeName, enclosingClass).Token;
return module.CorModule.GetClassFromToken(token);
@ -474,9 +478,9 @@ namespace Debugger.MetaData @@ -474,9 +478,9 @@ namespace Debugger.MetaData
throw new DebuggerException("Can not find type " + fullTypeName);
}
static public DebugType Create(Process process, ICorDebugClass corClass, params ICorDebugType[] typeArguments)
static public DebugType Create(AppDomain appDomain, ICorDebugClass corClass, params ICorDebugType[] typeArguments)
{
MetaDataImport metaData = process.Modules[corClass.Module].MetaData;
MetaDataImport metaData = appDomain.Process.Modules[corClass.Module].MetaData;
bool isValueType = false;
uint superClassToken = metaData.GetTypeDefProps(corClass.Token).SuperClassToken;
@ -499,15 +503,15 @@ namespace Debugger.MetaData @@ -499,15 +503,15 @@ namespace Debugger.MetaData
typeArguments
);
return Create(process, corType);
return Create(appDomain, corType);
}
/// <summary> Obtains instance of DebugType. Same types will return identical instance. </summary>
static public DebugType Create(Process process, ICorDebugType corType)
static public DebugType Create(AppDomain appDomain, ICorDebugType corType)
{
DateTime startTime = Util.HighPrecisionTimer.Now;
DebugType type = new DebugType(process, corType);
DebugType type = new DebugType(appDomain, corType);
// Get types with matching names from cache
List<DebugType> typesWithMatchingName;
@ -521,8 +525,8 @@ namespace Debugger.MetaData @@ -521,8 +525,8 @@ namespace Debugger.MetaData
foreach(DebugType loadedType in typesWithMatchingName) {
if (loadedType.Equals(type)) {
TimeSpan totalTime = Util.HighPrecisionTimer.Now - startTime;
if (process.Options.Verbose) {
process.TraceMessage("Type " + type.FullName + " was loaded already (" + totalTime.TotalMilliseconds + " ms)");
if (appDomain.Process.Options.Verbose) {
appDomain.Process.TraceMessage("Type " + type.FullName + " was loaded already (" + totalTime.TotalMilliseconds + " ms)");
}
return loadedType; // Type was loaded before
}
@ -535,14 +539,14 @@ namespace Debugger.MetaData @@ -535,14 +539,14 @@ namespace Debugger.MetaData
if (type.IsClass || type.IsValueType) {
type.LoadMemberInfo();
}
type.Process.Exited += delegate { typesWithMatchingName.Remove(type); };
type.AppDomain.Process.Exited += delegate { typesWithMatchingName.Remove(type); };
TimeSpan totalTime2 = Util.HighPrecisionTimer.Now - startTime;
string prefix = type.IsInterface ? "interface" : "type";
if (process.Options.Verbose) {
process.TraceMessage("Loaded {0} {1} ({2} ms)", prefix, type.FullName, totalTime2.TotalMilliseconds);
if (appDomain.Process.Options.Verbose) {
appDomain.Process.TraceMessage("Loaded {0} {1} ({2} ms)", prefix, type.FullName, totalTime2.TotalMilliseconds);
foreach(DebugType inter in type.Interfaces) {
process.TraceMessage(" - Implements {0}", inter.FullName);
appDomain.Process.TraceMessage(" - Implements {0}", inter.FullName);
}
}
@ -685,7 +689,7 @@ namespace Debugger.MetaData @@ -685,7 +689,7 @@ namespace Debugger.MetaData
public override bool Equals(object obj)
{
DebugType other = obj as DebugType;
if (other != null && this.Process == other.Process) {
if (other != null && this.AppDomain == other.AppDomain) {
if (this.IsArray) {
return other.IsArray &&
other.GetArrayRank() == this.GetArrayRank() &&

9
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/MemberInfo.cs

@ -21,11 +21,14 @@ namespace Debugger.MetaData @@ -21,11 +21,14 @@ namespace Debugger.MetaData
DebugType declaringType;
/// <summary> Gets the process in which the type was loaded </summary>
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
get { return declaringType.AppDomain; }
}
[Debugger.Tests.Ignore]
public Process Process {
get {
return declaringType.Process;
}
get { return this.AppDomain.Process; }
}
/// <summary> Gets the name of this member </summary>

8
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/MethodInfo.cs

@ -196,7 +196,7 @@ namespace Debugger.MetaData @@ -196,7 +196,7 @@ namespace Debugger.MetaData
foreach(byte b in code) {
codeTxt += b.ToString("X2") + " ";
}
this.Process.TraceMessage("Code of " + Name + ": " + codeTxt);
process.TraceMessage("Code of " + Name + ": " + codeTxt);
*/
uint token = 0;
@ -241,7 +241,7 @@ namespace Debugger.MetaData @@ -241,7 +241,7 @@ namespace Debugger.MetaData
}
if (token != 0) {
// this.Process.TraceMessage("Token: " + token.ToString("x"));
// process.TraceMessage("Token: " + token.ToString("x"));
MemberInfo member = this.DeclaringType.GetMember(token);
@ -351,13 +351,13 @@ namespace Debugger.MetaData @@ -351,13 +351,13 @@ namespace Debugger.MetaData
/// <summary>
/// Get a method from a managed type, method name and argument count
/// </summary>
public static MethodInfo GetFromName(Process process, uint? domainID, System.Type type, string methodName, int paramCount)
public static MethodInfo GetFromName(AppDomain appDomain, System.Type type, string methodName, int paramCount)
{
if (type.IsNested) throw new DebuggerException("Not implemented for nested types");
if (type.IsGenericType) throw new DebuggerException("Not implemented for generic types");
if (type.IsGenericParameter) throw new DebuggerException("Type can not be generic parameter");
DebugType debugType = DebugType.Create(process, domainID, type.FullName);
DebugType debugType = DebugType.Create(appDomain, type.FullName);
if (debugType == null) {
throw new DebuggerException("Type " + type.FullName + " not found");
}

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.Array.cs

@ -80,7 +80,7 @@ namespace Debugger @@ -80,7 +80,7 @@ namespace Debugger
{
int[] indices = (int[])elementIndices.Clone();
return new Value(Process, new ArrayIndexerExpression(this.Expression, indices), GetCorValueOfArrayElement(indices));
return new Value(this.AppDomain, new ArrayIndexerExpression(this.Expression, indices), GetCorValueOfArrayElement(indices));
}
// May be called later

6
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.Object.cs

@ -94,7 +94,7 @@ namespace Debugger @@ -94,7 +94,7 @@ namespace Debugger
{
Expression objectInstanceExpression = objectInstance != null ? objectInstance.Expression : new EmptyExpression();
return new Value(
fieldInfo.Process,
fieldInfo.AppDomain,
new MemberReferenceExpression(objectInstanceExpression, fieldInfo),
GetFieldCorValue(objectInstance, fieldInfo)
);
@ -150,7 +150,7 @@ namespace Debugger @@ -150,7 +150,7 @@ namespace Debugger
}
return new Value(
propertyInfo.Process,
propertyInfo.AppDomain,
new MemberReferenceExpression(objectInstanceExpression, propertyInfo, argumentExpressions.ToArray()),
Value.InvokeMethod(objectInstance, propertyInfo.GetMethod, arguments).CorValue
);
@ -222,7 +222,7 @@ namespace Debugger @@ -222,7 +222,7 @@ namespace Debugger
if (this.Type.IsPrimitive) return AsString;
if (this.Type.IsPointer) return "0x" + this.PointerAddress.ToString("X");
// if (!IsObject) // Can invoke on primitives
return Eval.InvokeMethod(Process, this.Type.AppDomainID, typeof(object), "ToString", this, new Value[] {}).AsString;
return Eval.InvokeMethod(this.AppDomain, typeof(object), "ToString", this, new Value[] {}).AsString;
}
#region Convenience overload methods

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.Primitive.cs

@ -46,7 +46,7 @@ namespace Debugger @@ -46,7 +46,7 @@ namespace Debugger
set {
if (this.Type.PrimitiveType == null) throw new DebuggerException("Value is not a primitive type");
if (this.Type.IsString) {
this.SetValue(Eval.NewString(this.Process, value.ToString()));
this.SetValue(Eval.NewString(this.AppDomain, value.ToString()));
} else {
if (value == null) throw new DebuggerException("Can not set primitive value to null");
object newValue;

29
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs

@ -22,6 +22,7 @@ namespace Debugger @@ -22,6 +22,7 @@ namespace Debugger
/// </summary>
public partial class Value: DebuggerObject
{
AppDomain appDomain;
Process process;
Expression expression;
ICorDebugValue corValue;
@ -57,12 +58,15 @@ namespace Debugger @@ -57,12 +58,15 @@ namespace Debugger
}
}
/// <summary> The process that owns the value </summary>
/// <summary> The appdomain that owns the value </summary>
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
get { return appDomain; }
}
[Debugger.Tests.Ignore]
public Process Process {
get {
return process;
}
get { return process; }
}
/// <summary> Returns true if the Value can not be used anymore.
@ -116,14 +120,14 @@ namespace Debugger @@ -116,14 +120,14 @@ namespace Debugger
ICorDebugValue corValue;
if (this.Type.IsPrimitive) {
// Get value type for the primive type
corValue = Eval.NewObjectNoConstructor(DebugType.Create(process, null, this.Type.FullName)).CorValue;
corValue = Eval.NewObjectNoConstructor(DebugType.Create(appDomain, this.Type.FullName)).CorValue;
} else {
corValue = Eval.NewObjectNoConstructor(this.Type).CorValue;
}
// Make the reference to box permanent
corValue = corValue.CastTo<ICorDebugReferenceValue>().Dereference().CastTo<ICorDebugHeapValue2>().CreateHandle(CorDebugHandleType.HANDLE_STRONG).CastTo<ICorDebugValue>();
// Create new value
Value newValue = new Value(process, expression, corValue);
Value newValue = new Value(appDomain, expression, corValue);
// Copy the data inside the box
newValue.CorGenericValue.RawValue = rawValue;
return newValue;
@ -143,15 +147,16 @@ namespace Debugger @@ -143,15 +147,16 @@ namespace Debugger
corValue = corValue.CastTo<ICorDebugReferenceValue>().Dereference().CastTo<ICorDebugHeapValue2>().CreateHandle(CorDebugHandleType.HANDLE_STRONG).CastTo<ICorDebugValue>();
}
}
return new Value(process, expression, corValue);
return new Value(appDomain, expression, corValue);
}
internal Value(Process process, Expression expression, ICorDebugValue corValue)
internal Value(AppDomain appDomain, Expression expression, ICorDebugValue corValue)
{
if (corValue == null) {
throw new ArgumentNullException("corValue");
}
this.process = process;
this.appDomain = appDomain;
this.process = appDomain.Process;
this.expression = expression;
this.corValue = corValue;
this.corValue_pauseSession = process.PauseSession;
@ -162,10 +167,10 @@ namespace Debugger @@ -162,10 +167,10 @@ namespace Debugger
{
// We were passed null reference and no metadata description
// (happens during CreateThread callback for the thread object)
this.type = DebugType.Create(this.Process, null, "System.Object");
this.type = DebugType.Create(appDomain, "System.Object");
} else {
ICorDebugType exactType = this.CorValue.CastTo<ICorDebugValue2>().ExactType;
this.type = DebugType.Create(this.Process, exactType);
this.type = DebugType.Create(appDomain, exactType);
}
}
@ -193,7 +198,7 @@ namespace Debugger @@ -193,7 +198,7 @@ namespace Debugger
if (corRef.Value == 0 || corRef.Dereference() == null) {
return null;
} else {
return new Value(this.Process, new DereferenceExpression(this.Expression), corRef.Dereference());
return new Value(this.AppDomain, new DereferenceExpression(this.Expression), corRef.Dereference());
}
}

Loading…
Cancel
Save