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
if (i > 0) sb.Append(", "); if (i > 0) sb.Append(", ");
PropertyInfo itemProperty = val.Type.GetProperty("Item"); PropertyInfo itemProperty = val.Type.GetProperty("Item");
// TODO: Appdomain constriant for create value // 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(FormatValue(item));
} }
sb.Append("}"); sb.Append("}");
@ -196,7 +196,7 @@ namespace Debugger.AddIn
if (target.Type.IsPrimitive && target.PrimitiveValue is string) { if (target.Type.IsPrimitive && target.PrimitiveValue is string) {
if (indexes.Count == 1 && indexes[0].Type.IsInteger) { if (indexes.Count == 1 && indexes[0].Type.IsInteger) {
int index = (int)indexes[0].PrimitiveValue; 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 { } else {
throw new GetValueException("Expected single integer index"); throw new GetValueException("Expected single integer index");
} }
@ -253,7 +253,7 @@ namespace Debugger.AddIn
public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data) 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) public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)
@ -315,7 +315,7 @@ namespace Debugger.AddIn
if (result == null) throw new GetValueException("Unsuppored unary expression " + op); 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) public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
@ -326,7 +326,7 @@ namespace Debugger.AddIn
object result = VisitBinaryOperatorExpressionInternal(left, right, binaryOperatorExpression.Op); object result = VisitBinaryOperatorExpressionInternal(left, right, binaryOperatorExpression.Op);
// Conver long to int if possible // Conver long to int if possible
if (result is long && int.MinValue <= (long)result && (long)result <= int.MaxValue) result = (int)(long)result; 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) 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
} }
if (DebuggingOptions.Instance.ICorDebugVisualizerEnabled) { 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); 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
} }
} }
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>(); List<AbstractNode> items = new List<AbstractNode>();
@ -70,7 +70,7 @@ namespace Debugger.AddIn.TreeModel
ICorDebugValue2 corValue2 = corValue.CastTo<ICorDebugValue2>(); ICorDebugValue2 corValue2 = corValue.CastTo<ICorDebugValue2>();
string fullname; string fullname;
try { try {
fullname = DebugType.Create(process, corValue2.ExactType).FullName; fullname = DebugType.Create(appDomain, corValue2.ExactType).FullName;
} catch (DebuggerException e) { } catch (DebuggerException e) {
fullname = e.Message; fullname = e.Message;
} }
@ -100,7 +100,7 @@ namespace Debugger.AddIn.TreeModel
if (refValue.IsNull == 0) { if (refValue.IsNull == 0) {
info.AddChild("Value", refValue.Value.ToString("X8")); info.AddChild("Value", refValue.Value.ToString("X8"));
if (refValue.Dereference() != null) { if (refValue.Dereference() != null) {
info.AddChild("Dereference", "", GetDebugInfo(process, refValue.Dereference())); info.AddChild("Dereference", "", GetDebugInfo(appDomain, refValue.Dereference()));
} else { } else {
info.AddChild("Dereference", "N/A"); info.AddChild("Dereference", "N/A");
} }
@ -130,7 +130,7 @@ namespace Debugger.AddIn.TreeModel
if (corValue.Is<ICorDebugBoxValue>()) { if (corValue.Is<ICorDebugBoxValue>()) {
InfoNode info = new InfoNode("ICorDebugBoxValue", ""); InfoNode info = new InfoNode("ICorDebugBoxValue", "");
ICorDebugBoxValue boxValue = corValue.CastTo<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); items.Add(info);
} }
if (corValue.Is<ICorDebugStringValue>()) { 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
{ {
if (DebuggerHelpers.hashCodeMethod == null) 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; DebuggerHelpers.hashCodeMethod = typeRuntimeHelpers.GetMember("GetHashCode", BindingFlags.Public | BindingFlags.Static | BindingFlags.Method | BindingFlags.IncludeSuperType) as MethodInfo;
if (DebuggerHelpers.hashCodeMethod == null) if (DebuggerHelpers.hashCodeMethod == null)
{ {

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

@ -17,10 +17,9 @@ namespace Debugger
ICorDebugAppDomain corAppDomain; ICorDebugAppDomain corAppDomain;
[Debugger.Tests.Ignore]
public Process Process { public Process Process {
get { get { return process; }
return process;
}
} }
public uint ID { public uint ID {
@ -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 { internal ICorDebugAppDomain CorDebugAppDomain {
get { get {
return corAppDomain; return corAppDomain;

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

@ -12,18 +12,19 @@ using Debugger.Wrappers.CorDebug;
namespace Debugger 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) public AppDomain this[ICorDebugAppDomain corAppDomain] {
{ get {
foreach(AppDomain a in appDomainCollection) { foreach(AppDomain a in this) {
if (a.CorDebugAppDomain.Equals(corAppDomain)) { if (a.CorDebugAppDomain.Equals(corAppDomain)) {
return a; 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
{ {
delegate void EvalStarter(Eval eval); delegate void EvalStarter(Eval eval);
AppDomain appDomain;
Process process; Process process;
string description; string description;
ICorDebugEval corEval; ICorDebugEval corEval;
Value result; Value result;
EvalState state; EvalState state;
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
get { return appDomain; }
}
[Debugger.Tests.Ignore] [Debugger.Tests.Ignore]
public Process Process { public Process Process {
get { return process; } get { return process; }
@ -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.description = description;
this.corEval = corEval; this.corEval = corEval;
this.state = EvalState.Evaluating; this.state = EvalState.Evaluating;
} }
/// <exception cref="GetValueException">Can not evaluate because no thread is selected</exception> static ICorDebugEval CreateCorEval(AppDomain appDomain)
static ICorDebugEval CreateCorEval(Process process)
{ {
process.AssertPaused(); appDomain.Process.AssertPaused();
Thread targetThread = process.SelectedThread; Thread targetThread = appDomain.Process.SelectedThread;
if (targetThread == null) { if (targetThread == null) {
throw new GetValueException("Can not evaluate because no thread is selected"); throw new GetValueException("Can not evaluate because no thread is selected");
@ -106,12 +113,11 @@ namespace Debugger
return targetThread.CorThread.CreateEval(); return targetThread.CorThread.CreateEval();
} }
/// <exception cref="GetValueException">Can not evaluate in optimized code</exception> static Eval CreateEval(AppDomain appDomain, string description, EvalStarter evalStarter)
static Eval CreateEval(Process process, 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 { try {
evalStarter(newEval); evalStarter(newEval);
@ -135,8 +141,8 @@ namespace Debugger
} }
} }
process.ActiveEvals.Add(newEval); appDomain.Process.ActiveEvals.Add(newEval);
process.AsyncContinue(DebuggeeStateAction.Keep); appDomain.Process.AsyncContinue(DebuggeeStateAction.Keep);
return newEval; return newEval;
} }
@ -188,16 +194,16 @@ namespace Debugger
} else { } else {
state = EvalState.EvaluatedException; state = EvalState.EvaluatedException;
} }
result = new Value(process, new EmptyExpression(), corEval.Result); result = new Value(AppDomain, new EmptyExpression(), corEval.Result);
} }
} }
#region Convenience methods #region Convenience methods
/// <summary> Synchronously calls a function and returns its return value </summary> /// <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 #endregion
@ -215,7 +221,7 @@ namespace Debugger
public static Eval AsyncInvokeMethod(MethodInfo method, Value thisValue, Value[] args) public static Eval AsyncInvokeMethod(MethodInfo method, Value thisValue, Value[] args)
{ {
return CreateEval( return CreateEval(
method.Process, method.AppDomain,
"Function call: " + method.FullName, "Function call: " + method.FullName,
delegate(Eval eval) { delegate(Eval eval) {
MethodInvokeStarter(eval, method, thisValue, args); MethodInvokeStarter(eval, method, thisValue, args);
@ -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) { if (value == null) {
ICorDebugClass corClass = DebugType.Create(process, null, typeof(object).FullName).CorType.Class; ICorDebugClass corClass = DebugType.Create(appDomain, typeof(object).FullName).CorType.Class;
ICorDebugEval corEval = CreateCorEval(process); ICorDebugEval corEval = CreateCorEval(appDomain);
ICorDebugValue corValue = corEval.CreateValue((uint)CorElementType.CLASS, corClass); 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) { } else if (value is string) {
return Eval.NewString(process, (string)value); return Eval.NewString(appDomain, (string)value);
} else { } else {
// TODO: Check if it is primitive type // 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; val.PrimitiveValue = value;
return val; return val;
} }
@ -304,17 +310,17 @@ namespace Debugger
#region Convenience methods #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 #endregion
public static Eval AsyncNewString(Process process, string textToCreate) public static Eval AsyncNewString(AppDomain appDomain, string textToCreate)
{ {
return CreateEval( return CreateEval(
process, appDomain,
"New string: " + textToCreate, "New string: " + textToCreate,
delegate(Eval eval) { delegate(Eval eval) {
eval.CorEval.CastTo<ICorDebugEval2>().NewStringWithLength(textToCreate, (uint)textToCreate.Length); eval.CorEval.CastTo<ICorDebugEval2>().NewStringWithLength(textToCreate, (uint)textToCreate.Length);
@ -334,7 +340,7 @@ namespace Debugger
public static Eval AsyncNewObjectNoConstructor(DebugType debugType) public static Eval AsyncNewObjectNoConstructor(DebugType debugType)
{ {
return CreateEval( return CreateEval(
debugType.Process, debugType.AppDomain,
"New object: " + debugType.FullName, "New object: " + debugType.FullName,
delegate(Eval eval) { delegate(Eval eval) {
eval.CorEval.CastTo<ICorDebugEval2>().NewParameterizedObjectNoConstructor(debugType.CorType.Class, (uint)debugType.GenericArguments.Count, debugType.GenericArgumentsAsCorDebugType); 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
{ {
public class Module: DebuggerObject, IDisposable public class Module: DebuggerObject, IDisposable
{ {
Process process; AppDomain appDomain;
Process process;
bool unloaded = false; bool unloaded = false;
string fullPath; string fullPath;
@ -35,17 +36,18 @@ namespace Debugger
} }
} }
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
get { return appDomain; }
}
[Debugger.Tests.Ignore] [Debugger.Tests.Ignore]
public Process Process { public Process Process {
get { get { return process; }
return process;
}
} }
NDebugger Debugger { NDebugger Debugger {
get { get { return this.AppDomain.Process.Debugger; }
return this.Process.Debugger;
}
} }
public MetaDataImport MetaData { public MetaDataImport MetaData {
@ -164,9 +166,10 @@ namespace Debugger
return names; 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; corModule = pModule;
@ -207,7 +210,7 @@ namespace Debugger
public void ResetJustMyCodeStatus() public void ResetJustMyCodeStatus()
{ {
uint unused = 0; 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 // Optimization - set the code as non-user right away
corModule.CastTo<ICorDebugModule2>().SetJMCStatus(0, 0, ref unused); corModule.CastTo<ICorDebugModule2>().SetJMCStatus(0, 0, ref unused);
return; return;

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

@ -21,6 +21,7 @@ namespace Debugger
EvalCollection activeEvals; EvalCollection activeEvals;
ModuleCollection modules; ModuleCollection modules;
ThreadCollection threads; ThreadCollection threads;
AppDomainCollection appDomains;
#region IExpirable #region IExpirable
@ -90,6 +91,10 @@ namespace Debugger
set { this.Threads.Selected = value; } set { this.Threads.Selected = value; }
} }
public AppDomainCollection AppDomains {
get { return appDomains; }
}
internal Process(NDebugger debugger, ICorDebugProcess corProcess) internal Process(NDebugger debugger, ICorDebugProcess corProcess)
{ {
this.debugger = debugger; this.debugger = debugger;
@ -100,6 +105,7 @@ namespace Debugger
activeEvals = new EvalCollection(debugger); activeEvals = new EvalCollection(debugger);
modules = new ModuleCollection(debugger); modules = new ModuleCollection(debugger);
threads = new ThreadCollection(debugger); threads = new ThreadCollection(debugger);
appDomains = new AppDomainCollection(debugger);
} }
internal ICorDebugProcess CorProcess { internal ICorDebugProcess CorProcess {
@ -233,9 +239,7 @@ namespace Debugger
[Debugger.Tests.Ignore] [Debugger.Tests.Ignore]
public Process Process { public Process Process {
get { get { return process; }
return process;
}
} }
public ProcessEventArgs(Process process): base(process == null ? null : process.Debugger) 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
/// </summary> /// </summary>
public class StackFrame: DebuggerObject public class StackFrame: DebuggerObject
{ {
Process process;
Thread thread; Thread thread;
Process process;
ICorDebugILFrame corILFrame; ICorDebugILFrame corILFrame;
object corILFramePauseSession; object corILFramePauseSession;
@ -33,11 +33,14 @@ namespace Debugger
uint frameIndex; uint frameIndex;
/// <summary> The process in which this stack frame is executed </summary> /// <summary> The process in which this stack frame is executed </summary>
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
get { return thread.AppDomain; }
}
[Debugger.Tests.Ignore] [Debugger.Tests.Ignore]
public Process Process { public Process Process {
get { get { return process; }
return process;
}
} }
/// <summary> Get the method which this stack frame is executing </summary> /// <summary> Get the method which this stack frame is executing </summary>
@ -95,7 +98,7 @@ namespace Debugger
this.frameIndex = frameIndex; this.frameIndex = frameIndex;
DebugType debugType = DebugType.Create( DebugType debugType = DebugType.Create(
this.Process, this.AppDomain,
corFunction.Class, corFunction.Class,
corILFrame.CastTo<ICorDebugILFrame2>().EnumerateTypeParameters().ToList().ToArray() corILFrame.CastTo<ICorDebugILFrame2>().EnumerateTypeParameters().ToList().ToArray()
); );
@ -110,7 +113,7 @@ namespace Debugger
internal ICorDebugILFrame CorILFrame { internal ICorDebugILFrame CorILFrame {
get { get {
if (corILFramePauseSession != this.Process.PauseSession) { if (corILFramePauseSession != process.PauseSession) {
// Reobtain the stackframe // Reobtain the stackframe
StackFrame stackFrame = this.Thread.GetStackFrameAt(chainIndex, frameIndex); 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"); 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
public void StepInto() public void StepInto()
{ {
AsyncStepInto(); AsyncStepInto();
this.Process.WaitForPause(); process.WaitForPause();
} }
/// <summary> Step over next instruction </summary> /// <summary> Step over next instruction </summary>
public void StepOver() public void StepOver()
{ {
AsyncStepOver(); AsyncStepOver();
this.Process.WaitForPause(); process.WaitForPause();
} }
/// <summary> Step out of the stack frame </summary> /// <summary> Step out of the stack frame </summary>
public void StepOut() public void StepOut()
{ {
AsyncStepOut(); AsyncStepOut();
this.Process.WaitForPause(); process.WaitForPause();
} }
/// <summary> Step into next instruction </summary> /// <summary> Step into next instruction </summary>
@ -263,7 +266,7 @@ namespace Debugger
/// </summary> /// </summary>
public Value GetThisValue() public Value GetThisValue()
{ {
return new Value(process, new ThisReferenceExpression(), GetThisCorValue()); return new Value(thread.AppDomain, new ThisReferenceExpression(), GetThisCorValue());
} }
ICorDebugValue GetThisCorValue() ICorDebugValue GetThisCorValue()
@ -300,7 +303,7 @@ namespace Debugger
/// <param name="index"> Zero-based index </param> /// <param name="index"> Zero-based index </param>
public Value GetArgumentValue(int index) 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) ICorDebugValue GetArgumentCorValue(int index)
@ -359,7 +362,7 @@ namespace Debugger
/// <summary> Returns value of give local variable </summary> /// <summary> Returns value of give local variable </summary>
public Value GetLocalVariableValue(ISymUnmanagedVariable symVar) 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) ICorDebugValue GetLocalVariableCorValue(ISymUnmanagedVariable symVar)

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

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

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

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

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

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

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

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

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

@ -29,9 +29,7 @@ namespace Debugger
[Debugger.Tests.Ignore] [Debugger.Tests.Ignore]
public Process Process { public Process Process {
get { get { return process; }
return process;
}
} }
public bool IsInCallback { public bool IsInCallback {
@ -321,6 +319,7 @@ namespace Debugger
EnterCallback(PausedReason.Other, "CreateAppDomain", pAppDomain); EnterCallback(PausedReason.Other, "CreateAppDomain", pAppDomain);
pAppDomain.Attach(); pAppDomain.Attach();
process.AppDomains.Add(new AppDomain(process, pAppDomain));
ExitCallback(); ExitCallback();
} }
@ -336,7 +335,7 @@ namespace Debugger
{ {
EnterCallback(PausedReason.Other, "LoadModule " + pModule.Name, pAppDomain); EnterCallback(PausedReason.Other, "LoadModule " + pModule.Name, pAppDomain);
process.Modules.Add(new Module(process, pModule)); process.Modules.Add(new Module(process.AppDomains[pAppDomain], pModule));
ExitCallback(); ExitCallback();
} }
@ -368,7 +367,7 @@ namespace Debugger
// and we continue from this callback anyway // and we continue from this callback anyway
EnterCallback(PausedReason.Other, "CreateThread " + pThread.ID, pAppDomain); EnterCallback(PausedReason.Other, "CreateThread " + pThread.ID, pAppDomain);
process.Threads.Add(new Thread(process, pThread)); process.Threads.Add(new Thread(process.AppDomains[pAppDomain], pThread));
ExitCallback(); ExitCallback();
} }
@ -433,6 +432,8 @@ namespace Debugger
{ {
EnterCallback(PausedReason.Other, "ExitAppDomain", pAppDomain); EnterCallback(PausedReason.Other, "ExitAppDomain", pAppDomain);
process.AppDomains.Remove(process.AppDomains[pAppDomain]);
ExitCallback(); ExitCallback();
} }
@ -477,7 +478,7 @@ namespace Debugger
// Watch out for the zeros and null! // Watch out for the zeros and null!
// Exception -> Exception2(pAppDomain, pThread, null, 0, exceptionType, 0); // 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.CurrentException_DebuggeeState = process.DebuggeeState;
process.SelectedThread.CurrentExceptionType = (ExceptionType)exceptionType; process.SelectedThread.CurrentExceptionType = (ExceptionType)exceptionType;
process.SelectedThread.CurrentExceptionIsUnhandled = (ExceptionType)exceptionType == ExceptionType.Unhandled; 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
/// </remarks> /// </remarks>
public partial class DebugType: DebuggerObject public partial class DebugType: DebuggerObject
{ {
Process process; AppDomain appDomain;
Process process;
ICorDebugType corType; ICorDebugType corType;
CorElementType corElementType; CorElementType corElementType;
string name; string name;
@ -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] [Debugger.Tests.Ignore]
public Process Process { public Process Process {
get { get { return process; }
return process;
}
} }
internal ICorDebugType CorType { internal ICorDebugType CorType {
@ -310,29 +314,30 @@ namespace Debugger.MetaData
} }
// corType.Base does not work for arrays // corType.Base does not work for arrays
if (this.IsArray) { 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 // corType.Base does not work for primitive types
if (this.IsPrimitive) { if (this.IsPrimitive) {
return DebugType.Create(this.Process, AppDomainID, "System.Object"); return DebugType.Create(this.AppDomain, "System.Object");
} }
if (this.IsPointer || this.IsVoid) { if (this.IsPointer || this.IsVoid) {
return null; return null;
} }
ICorDebugType baseType = corType.Base; ICorDebugType baseType = corType.Base;
if (baseType != null) { if (baseType != null) {
return Create(process, baseType); return Create(this.AppDomain, baseType);
} else { } else {
return null; return null;
} }
} }
} }
DebugType(Process process, ICorDebugType corType) DebugType(AppDomain appDomain, ICorDebugType corType)
{ {
if (corType == null) throw new ArgumentNullException("corType"); if (corType == null) throw new ArgumentNullException("corType");
this.process = process; this.appDomain = appDomain;
this.process = appDomain.Process;
this.corType = corType; this.corType = corType;
this.corElementType = (CorElementType)corType.Type; this.corElementType = (CorElementType)corType.Type;
@ -343,7 +348,7 @@ namespace Debugger.MetaData
if (this.IsClass || this.IsValueType || this.IsArray || this.IsPointer) { if (this.IsClass || this.IsValueType || this.IsArray || this.IsPointer) {
foreach(ICorDebugType t in corType.EnumerateTypeParameters().Enumerator) { 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
{ {
CorTokenType tokenType = (CorTokenType)(token & 0xFF000000); CorTokenType tokenType = (CorTokenType)(token & 0xFF000000);
if (tokenType == CorTokenType.TypeDef || tokenType == CorTokenType.TypeRef) { 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) { } else if (tokenType == CorTokenType.TypeSpec) {
Blob typeSpecBlob = module.MetaData.GetTypeSpecFromToken(token); Blob typeSpecBlob = module.MetaData.GetTypeSpecFromToken(token);
return Create(module, typeSpecBlob.GetData(), declaringType); return Create(module, typeSpecBlob.GetData(), declaringType);
@ -388,21 +393,21 @@ namespace Debugger.MetaData
{ {
System.Type sysType = CorElementTypeToManagedType((CorElementType)(uint)sigType.ElementType); System.Type sysType = CorElementTypeToManagedType((CorElementType)(uint)sigType.ElementType);
if (sysType != null) { 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) { 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) { if (sigType is CLASS) {
ICorDebugClass corClass = GetCorClass(module, ((CLASS)sigType).Type.ToUInt()); ICorDebugClass corClass = GetCorClass(module, ((CLASS)sigType).Type.ToUInt());
return Create(module.Process, corClass); return Create(module.AppDomain, corClass);
} }
if (sigType is VALUETYPE) { if (sigType is VALUETYPE) {
ICorDebugClass corClass = GetCorClass(module, ((VALUETYPE)sigType).Type.ToUInt()); ICorDebugClass corClass = GetCorClass(module, ((VALUETYPE)sigType).Type.ToUInt());
return Create(module.Process, corClass); return Create(module.AppDomain, corClass);
} }
// Numbered generic reference // Numbered generic reference
@ -413,7 +418,7 @@ namespace Debugger.MetaData
// Numbered generic reference // Numbered generic reference
if (sigType is MVAR) { if (sigType is MVAR) {
return Create(module.Process, module.AppDomainID, "System.Object"); return Create(module.AppDomain, "System.Object");
} }
if (sigType is GENERICINST) { if (sigType is GENERICINST) {
@ -426,15 +431,15 @@ namespace Debugger.MetaData
} }
ICorDebugType genInstance = corClass.CastTo<ICorDebugClass2>().GetParameterizedType((uint)classOrValueType, genArgs); 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()); 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) static ICorDebugClass GetCorClass(Module module, uint token)
@ -452,17 +457,16 @@ namespace Debugger.MetaData
ICorDebugClass enclosingClass = GetCorClass(module, refProps.ResolutionScope); ICorDebugClass enclosingClass = GetCorClass(module, refProps.ResolutionScope);
enclosingClassTk = enclosingClass.Token; enclosingClassTk = enclosingClass.Token;
} }
return GetCorClass(module.Process, module.AppDomainID, fullName, enclosingClassTk); return GetCorClass(module.AppDomain, fullName, enclosingClassTk);
} else { } else {
throw new DebuggerException("TypeDef or TypeRef expected"); 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 appDomain.Process.Modules) {
foreach(Module module in process.Modules) { if (module.AppDomain == appDomain) {
if (!domainID.HasValue || domainID == module.CorModule.Assembly.AppDomain.ID) {
try { try {
uint token = module.MetaData.FindTypeDefPropsByName(fullTypeName, enclosingClass).Token; uint token = module.MetaData.FindTypeDefPropsByName(fullTypeName, enclosingClass).Token;
return module.CorModule.GetClassFromToken(token); return module.CorModule.GetClassFromToken(token);
@ -474,9 +478,9 @@ namespace Debugger.MetaData
throw new DebuggerException("Can not find type " + fullTypeName); 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; bool isValueType = false;
uint superClassToken = metaData.GetTypeDefProps(corClass.Token).SuperClassToken; uint superClassToken = metaData.GetTypeDefProps(corClass.Token).SuperClassToken;
@ -499,15 +503,15 @@ namespace Debugger.MetaData
typeArguments typeArguments
); );
return Create(process, corType); return Create(appDomain, corType);
} }
/// <summary> Obtains instance of DebugType. Same types will return identical instance. </summary> /// <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; DateTime startTime = Util.HighPrecisionTimer.Now;
DebugType type = new DebugType(process, corType); DebugType type = new DebugType(appDomain, corType);
// Get types with matching names from cache // Get types with matching names from cache
List<DebugType> typesWithMatchingName; List<DebugType> typesWithMatchingName;
@ -521,8 +525,8 @@ namespace Debugger.MetaData
foreach(DebugType loadedType in typesWithMatchingName) { foreach(DebugType loadedType in typesWithMatchingName) {
if (loadedType.Equals(type)) { if (loadedType.Equals(type)) {
TimeSpan totalTime = Util.HighPrecisionTimer.Now - startTime; TimeSpan totalTime = Util.HighPrecisionTimer.Now - startTime;
if (process.Options.Verbose) { if (appDomain.Process.Options.Verbose) {
process.TraceMessage("Type " + type.FullName + " was loaded already (" + totalTime.TotalMilliseconds + " ms)"); appDomain.Process.TraceMessage("Type " + type.FullName + " was loaded already (" + totalTime.TotalMilliseconds + " ms)");
} }
return loadedType; // Type was loaded before return loadedType; // Type was loaded before
} }
@ -535,14 +539,14 @@ namespace Debugger.MetaData
if (type.IsClass || type.IsValueType) { if (type.IsClass || type.IsValueType) {
type.LoadMemberInfo(); type.LoadMemberInfo();
} }
type.Process.Exited += delegate { typesWithMatchingName.Remove(type); }; type.AppDomain.Process.Exited += delegate { typesWithMatchingName.Remove(type); };
TimeSpan totalTime2 = Util.HighPrecisionTimer.Now - startTime; TimeSpan totalTime2 = Util.HighPrecisionTimer.Now - startTime;
string prefix = type.IsInterface ? "interface" : "type"; string prefix = type.IsInterface ? "interface" : "type";
if (process.Options.Verbose) { if (appDomain.Process.Options.Verbose) {
process.TraceMessage("Loaded {0} {1} ({2} ms)", prefix, type.FullName, totalTime2.TotalMilliseconds); appDomain.Process.TraceMessage("Loaded {0} {1} ({2} ms)", prefix, type.FullName, totalTime2.TotalMilliseconds);
foreach(DebugType inter in type.Interfaces) { 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
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
DebugType other = obj as DebugType; DebugType other = obj as DebugType;
if (other != null && this.Process == other.Process) { if (other != null && this.AppDomain == other.AppDomain) {
if (this.IsArray) { if (this.IsArray) {
return other.IsArray && return other.IsArray &&
other.GetArrayRank() == this.GetArrayRank() && other.GetArrayRank() == this.GetArrayRank() &&

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

@ -21,11 +21,14 @@ namespace Debugger.MetaData
DebugType declaringType; DebugType declaringType;
/// <summary> Gets the process in which the type was loaded </summary> /// <summary> Gets the process in which the type was loaded </summary>
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
get { return declaringType.AppDomain; }
}
[Debugger.Tests.Ignore] [Debugger.Tests.Ignore]
public Process Process { public Process Process {
get { get { return this.AppDomain.Process; }
return declaringType.Process;
}
} }
/// <summary> Gets the name of this member </summary> /// <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
foreach(byte b in code) { foreach(byte b in code) {
codeTxt += b.ToString("X2") + " "; codeTxt += b.ToString("X2") + " ";
} }
this.Process.TraceMessage("Code of " + Name + ": " + codeTxt); process.TraceMessage("Code of " + Name + ": " + codeTxt);
*/ */
uint token = 0; uint token = 0;
@ -241,7 +241,7 @@ namespace Debugger.MetaData
} }
if (token != 0) { if (token != 0) {
// this.Process.TraceMessage("Token: " + token.ToString("x")); // process.TraceMessage("Token: " + token.ToString("x"));
MemberInfo member = this.DeclaringType.GetMember(token); MemberInfo member = this.DeclaringType.GetMember(token);
@ -351,13 +351,13 @@ namespace Debugger.MetaData
/// <summary> /// <summary>
/// Get a method from a managed type, method name and argument count /// Get a method from a managed type, method name and argument count
/// </summary> /// </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.IsNested) throw new DebuggerException("Not implemented for nested types");
if (type.IsGenericType) throw new DebuggerException("Not implemented for generic types"); if (type.IsGenericType) throw new DebuggerException("Not implemented for generic types");
if (type.IsGenericParameter) throw new DebuggerException("Type can not be generic parameter"); 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) { if (debugType == null) {
throw new DebuggerException("Type " + type.FullName + " not found"); 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
{ {
int[] indices = (int[])elementIndices.Clone(); 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 // May be called later

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

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

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

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

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

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