diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs
index 54bc20da2e..b50689a10a 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs
@@ -5,13 +5,15 @@
// $Revision$
//
+using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
-using Debugger.MetaData;
using Debugger.Expressions;
+using Debugger.MetaData;
using Debugger.Wrappers.CorDebug;
using Debugger.Wrappers.CorSym;
+using Debugger.Wrappers.MetaData;
namespace Debugger
{
@@ -22,6 +24,7 @@ namespace Debugger
public class StackFrame: DebuggerObject
{
Thread thread;
+ AppDomain appDomain;
Process process;
ICorDebugILFrame corILFrame;
@@ -35,7 +38,7 @@ namespace Debugger
/// The process in which this stack frame is executed
[Debugger.Tests.Ignore]
public AppDomain AppDomain {
- get { return thread.AppDomain; }
+ get { return appDomain; }
}
[Debugger.Tests.Ignore]
@@ -91,16 +94,21 @@ namespace Debugger
{
this.process = thread.Process;
this.thread = thread;
+ this.appDomain = process.AppDomains[corILFrame.Function.Class.Module.Assembly.AppDomain];
this.corILFrame = corILFrame;
this.corILFramePauseSession = process.PauseSession;
this.corFunction = corILFrame.Function;
this.chainIndex = chainIndex;
this.frameIndex = frameIndex;
+ MetaDataImport metaData = thread.Process.Modules[corFunction.Class.Module].MetaData;
+ ICorDebugType[] genArgs = corILFrame.CastTo().EnumerateTypeParameters().ToList().ToArray();
+ Array.Resize(ref genArgs, metaData.GetGenericParamCount(corFunction.Class.Token));
+
DebugType debugType = DebugType.Create(
this.AppDomain,
corFunction.Class,
- corILFrame.CastTo().EnumerateTypeParameters().ToList().ToArray()
+ genArgs
);
this.methodInfo = debugType.GetMethod(corFunction.Token);
}
@@ -266,7 +274,7 @@ namespace Debugger
///
public Value GetThisValue()
{
- return new Value(thread.AppDomain, new ThisReferenceExpression(), GetThisCorValue());
+ return new Value(appDomain, new ThisReferenceExpression(), GetThisCorValue());
}
ICorDebugValue GetThisCorValue()
@@ -303,7 +311,7 @@ namespace Debugger
/// Zero-based index
public Value GetArgumentValue(int index)
{
- return new Value(thread.AppDomain, new ParameterIdentifierExpression(this.MethodInfo, index), GetArgumentCorValue(index));
+ return new Value(appDomain, new ParameterIdentifierExpression(this.MethodInfo, index), GetArgumentCorValue(index));
}
ICorDebugValue GetArgumentCorValue(int index)
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs
index d36cbdd328..50c91d4b21 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Thread.cs
@@ -17,7 +17,7 @@ namespace Debugger
{
public partial class Thread: DebuggerObject
{
- AppDomain appDomain;
+ // AppDomain for thread can be changing
Process process;
uint id;
@@ -37,11 +37,6 @@ namespace Debugger
public event EventHandler NameChanged;
public event EventHandler Exited;
- [Debugger.Tests.Ignore]
- public AppDomain AppDomain {
- get { return appDomain; }
- }
-
[Debugger.Tests.Ignore]
public Process Process {
get { return process; }
@@ -88,10 +83,9 @@ namespace Debugger
}
}
- internal Thread(AppDomain appDomain, ICorDebugThread corThread)
+ internal Thread(Process process, ICorDebugThread corThread)
{
- this.appDomain = appDomain;
- this.process = appDomain.Process;
+ this.process = process;
this.corThread = corThread;
this.id = CorThread.ID;
}
@@ -166,7 +160,7 @@ namespace Debugger
process.AssertPaused();
ICorDebugValue corValue = this.CorThread.Object;
- return new Value(appDomain, new EmptyExpression(), corValue);
+ return new Value(process.AppDomains[this.CorThread.AppDomain], new EmptyExpression(), corValue);
}
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs
index efcf06a60b..dff8f4655e 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Internal/ManagedCallback.cs
@@ -367,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.AppDomains[pAppDomain], pThread));
+ process.Threads.Add(new Thread(process, pThread));
ExitCallback();
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs
index 4c8f84389d..1c60dba421 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs
@@ -297,23 +297,23 @@ namespace Debugger.MetaData
#endregion
- private bool primitiveTypeCached = false;
- private System.Type primitiveTypeCache;
+ private bool primitiveTypeCached;
+ private System.Type primitiveType;
/// Returns simple managed type coresponding to the primitive type.
[Tests.Ignore]
public System.Type PrimitiveType {
get {
- if (!this.primitiveTypeCached) {
- this.primitiveTypeCache = getPrimitiveType();
- this.primitiveTypeCached = true;
+ if (!primitiveTypeCached) {
+ primitiveTypeCached = true;
+ primitiveType = GetPrimitiveType();
}
- return this.primitiveTypeCache;
+ return primitiveType;
}
}
/// Returns simple managed type coresponding to the primitive type.
- private System.Type getPrimitiveType()
+ private System.Type GetPrimitiveType()
{
if (corElementType == CorElementType.VALUETYPE) {
CorElementType corType;
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs
index 19cd887f84..9afb3cdb35 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs
@@ -45,7 +45,7 @@ namespace Debugger.MetaData
List members = new List();
// Stores all DebugType instances. FullName is the key
- static Dictionary> loadedTypes = new Dictionary>();
+ static Dictionary loadedTypes = new Dictionary();
void AssertClassOrValueType()
{
@@ -66,9 +66,7 @@ namespace Debugger.MetaData
}
internal ICorDebugType CorType {
- get {
- return corType;
- }
+ get { return corType; }
}
///
@@ -102,9 +100,7 @@ namespace Debugger.MetaData
/// Returns a string describing the type including the namespace
/// and generic arguments but excluding the assembly name.
public string FullName {
- get {
- return fullName;
- }
+ get { return fullName; }
}
/// Returns the number of dimensions of an array
@@ -118,9 +114,7 @@ namespace Debugger.MetaData
/// Gets a list of all interfaces that this type implements
public List Interfaces {
- get {
- return interfaces;
- }
+ get { return interfaces; }
}
/// Return an interface with the given name
@@ -290,16 +284,6 @@ namespace Debugger.MetaData
}
}
- internal uint? AppDomainID {
- get {
- if (IsClass || IsValueType) {
- return this.Module.AppDomainID;
- } else {
- return null;
- }
- }
- }
-
///
/// Gets the type from which this type inherits.
///
@@ -356,11 +340,6 @@ namespace Debugger.MetaData
this.name = GetName(false);
}
- public static DebugType Create(Module module, uint token)
- {
- return Create(module, token, null);
- }
-
public static DebugType Create(Module module, uint token, DebugType declaringType)
{
CorTokenType tokenType = (CorTokenType)(token & 0xFF000000);
@@ -374,11 +353,6 @@ namespace Debugger.MetaData
}
}
- public static DebugType Create(Module module, byte[] sig)
- {
- return Create(module, sig, null);
- }
-
/// Type definition to use to resolve numbered generic references
public static DebugType Create(Module module, byte[] sig, DebugType declaringType)
{
@@ -478,7 +452,7 @@ namespace Debugger.MetaData
throw new DebuggerException("Can not find type " + fullTypeName);
}
- static public DebugType Create(AppDomain appDomain, ICorDebugClass corClass, params ICorDebugType[] typeArguments)
+ static public DebugType Create(AppDomain appDomain, ICorDebugClass corClass, params ICorDebugType[] genericArguments)
{
MetaDataImport metaData = appDomain.Process.Modules[corClass.Module].MetaData;
@@ -495,12 +469,13 @@ namespace Debugger.MetaData
}
}
- int getArgsCount = metaData.GetGenericParamCount(corClass.Token);
+ if (genericArguments.Length != metaData.GetGenericParamCount(corClass.Token)) {
+ throw new DebuggerException("Incorrect number of generic arguments");
+ }
- Array.Resize(ref typeArguments, getArgsCount);
ICorDebugType corType = corClass.CastTo().GetParameterizedType(
isValueType ? (uint)CorElementType.VALUETYPE : (uint)CorElementType.CLASS,
- typeArguments
+ genericArguments
);
return Create(appDomain, corType);
@@ -509,41 +484,23 @@ namespace Debugger.MetaData
/// Obtains instance of DebugType. Same types will return identical instance.
static public DebugType Create(AppDomain appDomain, ICorDebugType corType)
{
+ if (loadedTypes.ContainsKey(corType)) return loadedTypes[corType];
+
DateTime startTime = Util.HighPrecisionTimer.Now;
DebugType type = new DebugType(appDomain, corType);
- // Get types with matching names from cache
- List typesWithMatchingName;
- if (!loadedTypes.TryGetValue(type.FullName, out typesWithMatchingName)) {
- // No types with such name - create a new list
- typesWithMatchingName = new List(1);
- loadedTypes.Add(type.FullName, typesWithMatchingName);
- }
+ // Loading of memebers might access the type again
+ loadedTypes[corType] = type;
- // Try to find the type
- foreach(DebugType loadedType in typesWithMatchingName) {
- if (loadedType.Equals(type)) {
- TimeSpan totalTime = Util.HighPrecisionTimer.Now - startTime;
- if (appDomain.Process.Options.Verbose) {
- appDomain.Process.TraceMessage("Type " + type.FullName + " was loaded already (" + totalTime.TotalMilliseconds + " ms)");
- }
- return loadedType; // Type was loaded before
- }
- }
-
- // This has to be done before LoadMemberInfo since it might use it
- typesWithMatchingName.Add(type);
-
- // The type is not in the cache, finish loading it and add it to the cache
if (type.IsClass || type.IsValueType) {
type.LoadMemberInfo();
}
- type.AppDomain.Process.Exited += delegate { typesWithMatchingName.Remove(type); };
+ type.AppDomain.Process.Exited += delegate { loadedTypes.Remove(corType); };
TimeSpan totalTime2 = Util.HighPrecisionTimer.Now - startTime;
- string prefix = type.IsInterface ? "interface" : "type";
if (appDomain.Process.Options.Verbose) {
+ string prefix = type.IsInterface ? "interface" : "type";
appDomain.Process.TraceMessage("Loaded {0} {1} ({2} ms)", prefix, type.FullName, totalTime2.TotalMilliseconds);
foreach(DebugType inter in type.Interfaces) {
appDomain.Process.TraceMessage(" - Implements {0}", inter.FullName);
@@ -554,13 +511,13 @@ namespace Debugger.MetaData
}
/// Returns all non-generic types defined in the given module
+ /// Generic types can not be returned, because we do not how to instanciate them
public static List GetDefinedTypesInModule(Module module)
{
- // TODO: Generic types
List types = new List();
foreach(TypeDefProps typeDef in module.MetaData.EnumTypeDefProps()) {
if (module.MetaData.GetGenericParamCount(typeDef.Token) == 0) {
- types.Add(DebugType.Create(module, typeDef.Token));
+ types.Add(DebugType.Create(module, typeDef.Token, null));
}
}
return types;
@@ -685,48 +642,9 @@ namespace Debugger.MetaData
return (GetMembers(bindingFlags).Count > 0);
}
- /// Compares two types
- public override bool Equals(object obj)
- {
- DebugType other = obj as DebugType;
- if (other != null && this.AppDomain == other.AppDomain) {
- if (this.IsArray) {
- return other.IsArray &&
- other.GetArrayRank() == this.GetArrayRank() &&
- other.ElementType.Equals(this.ElementType);
- }
- if (this.IsPrimitive) {
- return other.IsPrimitive &&
- other.PrimitiveType == this.PrimitiveType &&
- other.IsValueType == this.IsValueType;
- }
- if (this.IsClass || this.IsValueType) {
- return (other.IsClass || other.IsValueType) &&
- other.Module == this.Module &&
- other.Token == this.Token;
- }
- if (this.IsPointer) {
- return other.IsPointer &&
- other.ElementType.Equals(this.ElementType);
- }
- if (this.IsVoid) {
- return other.IsVoid;
- }
- throw new DebuggerException("Unknown type");
- } else {
- return false;
- }
- }
-
- /// Get hash code of the object
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
-
public override string ToString()
{
- return string.Format("{0}", this.fullName);
+ return string.Format("{0}", this.FullName);
}
}
}
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugType.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugType.cs
index 4a20c5e7e8..ae460f9156 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugType.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugType.cs
@@ -1,4 +1,4 @@
-//
+//
//
//
//
@@ -85,7 +85,7 @@ namespace Debugger.Wrappers.CorDebug
public override int GetHashCode()
{
- return base.GetHashCode();
+ return wrappedObject.GetHashCode();
}
public override bool Equals(object o)
diff --git a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj
index 5e06bf0d3e..02fe5d4243 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj
+++ b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj
@@ -42,6 +42,7 @@
+
@@ -99,4 +100,4 @@
-
+
\ No newline at end of file
diff --git a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/AppDomains.cs b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/AppDomains.cs
new file mode 100644
index 0000000000..a4858251d6
--- /dev/null
+++ b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/AppDomains.cs
@@ -0,0 +1,82 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+
+namespace Debugger.Tests.TestPrograms
+{
+ public class AppDomains
+ {
+ public static void Main()
+ {
+ int one = 1;
+ System.Diagnostics.Debugger.Break();
+ System.AppDomain appDomain = System.AppDomain.CreateDomain("myDomain");
+ RemoteObj printer = (RemoteObj)appDomain.CreateInstanceAndUnwrap(typeof(RemoteObj).Assembly.FullName, typeof(RemoteObj).FullName);
+ printer.Foo();
+ }
+ }
+
+ public class RemoteObj: MarshalByRefObject
+ {
+ public void Foo()
+ {
+ int two = 2;
+ string appDomainName = System.AppDomain.CurrentDomain.FriendlyName + " Id=" + System.AppDomain.CurrentDomain.Id;
+ System.Diagnostics.Debugger.Break();
+ }
+ }
+}
+
+#if TEST_CODE
+namespace Debugger.Tests {
+ using Debugger.MetaData;
+
+ public partial class DebuggerTests
+ {
+ [NUnit.Framework.Test]
+ public void AppDomains()
+ {
+ StartTest("AppDomains.cs");
+
+ DebugType type1 = process.SelectedStackFrame.GetLocalVariableValue("one").Type;
+ DebugType type1b = process.SelectedStackFrame.GetLocalVariableValue("one").Type;
+ ObjectDump("SameDomainEqual", type1 == type1b);
+ process.Continue();
+ ObjectDump("AppDomainName", process.SelectedStackFrame.GetLocalVariableValue("appDomainName").AsString);
+ DebugType type2 = process.SelectedStackFrame.GetLocalVariableValue("two").Type;
+ ObjectDump("OtherDomainEqual", type1 == type2);
+ ObjectDump("AppDomainsEqual", type1.AppDomain == type2.AppDomain);
+ ObjectDump("AppDomainIDsEqual", type1.AppDomain.ID == type2.AppDomain.ID);
+
+ EndTest();
+ }
+ }
+}
+#endif
+
+#if EXPECTED_OUTPUT
+
+
+
+
+ mscorlib.dll (No symbols)
+ AppDomains.exe (Has symbols)
+ Break AppDomains.cs:17,4-17,40
+ True
+ mscorlib.dll (No symbols)
+ AppDomains.exe (Has symbols)
+ Break AppDomains.cs:30,4-30,40
+ myDomain Id=2
+ False
+ False
+ False
+
+
+
+#endif // EXPECTED_OUTPUT
\ No newline at end of file