Browse Source

Starting support for multiple AppDomains.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2920 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 18 years ago
parent
commit
ac21176214
  1. 4
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Eval.cs
  2. 35
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs
  3. 37
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs
  4. 23
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/MethodInfo.cs
  5. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.Object.cs
  6. 5
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs

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

@ -170,9 +170,9 @@ namespace Debugger @@ -170,9 +170,9 @@ namespace Debugger
#region Convenience methods
/// <summary> Synchronously calls a function and returns its return value </summary>
public static Value InvokeMethod(Process process, System.Type type, string name, Value thisValue, Value[] args)
public static Value InvokeMethod(Process process, uint? domainID, System.Type type, string name, Value thisValue, Value[] args)
{
return InvokeMethod(MethodInfo.GetFromName(process, type, name, args.Length), thisValue, args);
return InvokeMethod(MethodInfo.GetFromName(process, domainID, type, name, args.Length), thisValue, args);
}
#endregion

35
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType-Helpers.cs

@ -55,6 +55,11 @@ namespace Debugger.MetaData @@ -55,6 +55,11 @@ namespace Debugger.MetaData
return QueryMembers<T>(bindingFlags, null, null);
}
List<T> QueryMembers<T>(string name) where T:MemberInfo
{
return QueryMembers<T>(BindingFlags.All, name, null);
}
T QueryMember<T>(string name) where T:MemberInfo
{
List<T> result = QueryMembers<T>(BindingFlags.All, name, null);
@ -145,6 +150,18 @@ namespace Debugger.MetaData @@ -145,6 +150,18 @@ namespace Debugger.MetaData
return QueryMembers<MemberInfo>(BindingFlags.Public);
}
/// <summary> Return all members with the given name.</summary>
public IList<MemberInfo> GetMembers(string name)
{
return QueryMembers<MemberInfo>(name);
}
/// <summary> Return all members satisfing binding flags.</summary>
public IList<MemberInfo> GetMembers(string name, BindingFlags bindingFlags)
{
return QueryMembers<MemberInfo>(bindingFlags, name, null);
}
/// <summary> Return all members satisfing binding flags.</summary>
public IList<MemberInfo> GetMembers(BindingFlags bindingFlags)
{
@ -182,6 +199,12 @@ namespace Debugger.MetaData @@ -182,6 +199,12 @@ namespace Debugger.MetaData
return QueryMember<FieldInfo>(name);
}
/// <summary> Return fields with the given name</summary>
public IList<FieldInfo> GetFields(string name)
{
return QueryMembers<FieldInfo>(name);
}
/// <summary> Return first field with the given token</summary>
public FieldInfo GetField(uint token)
{
@ -207,6 +230,12 @@ namespace Debugger.MetaData @@ -207,6 +230,12 @@ namespace Debugger.MetaData
return QueryMember<MethodInfo>(name);
}
/// <summary> Return methods with the given name</summary>
public IList<MethodInfo> GetMethods(string name)
{
return QueryMembers<MethodInfo>(name);
}
/// <summary> Return first method with the given token</summary>
public MethodInfo GetMethod(uint token)
{
@ -232,6 +261,12 @@ namespace Debugger.MetaData @@ -232,6 +261,12 @@ namespace Debugger.MetaData
return QueryMember<PropertyInfo>(name);
}
/// <summary> Return propertyies with the given name</summary>
public IList<PropertyInfo> GetProperties(string name)
{
return QueryMembers<PropertyInfo>(name);
}
/// <summary> Return first property with the given token</summary>
public PropertyInfo GetProperty(uint token)
{

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

@ -16,7 +16,10 @@ namespace Debugger.MetaData @@ -16,7 +16,10 @@ namespace Debugger.MetaData
/// Represents a type in a debugee. That is, a class, array, value type or a primitive type.
/// This class mimics the <see cref="System.Type"/> class.
/// </summary>
/// <remarks> If two types are identical, the references to DebugType will also be identical </remarks>
/// <remarks>
/// If two types are identical, the references to DebugType will also be identical
/// Type will be loaded once per each appdomain.
/// </remarks>
public partial class DebugType: DebuggerObject
{
Process process;
@ -209,6 +212,16 @@ namespace Debugger.MetaData @@ -209,6 +212,16 @@ namespace Debugger.MetaData
}
}
internal uint? AppDomainID {
get {
if (IsClass || IsValueType) {
return this.Module.CorModule.Assembly.AppDomain.ID;
} else {
return null;
}
}
}
/// <summary>
/// Gets the type from which this type inherits.
/// <para>
@ -219,11 +232,11 @@ namespace Debugger.MetaData @@ -219,11 +232,11 @@ namespace Debugger.MetaData
get {
// corType.Base does not work for arrays
if (this.IsArray) {
return DebugType.GetType(this.Process, "System.Array");
return DebugType.GetType(this.Process, AppDomainID, "System.Array");
}
// corType.Base does not work for primitive types
if (this.IsPrimitive) {
return DebugType.GetType(this.Process, "System.Object");
return DebugType.GetType(this.Process, AppDomainID, "System.Object");
}
ICorDebugType baseType = corType.Base;
if (baseType != null) {
@ -429,9 +442,7 @@ namespace Debugger.MetaData @@ -429,9 +442,7 @@ namespace Debugger.MetaData
}
if (this.IsClass || this.IsValueType) {
return (other.IsClass || other.IsValueType) &&
// Test fullpath since module can be loaded multiple times to different appdomains
// eg during unit testing
other.Module.FullPath == this.Module.FullPath &&
other.Module == this.Module &&
other.MetadataToken == this.MetadataToken;
}
throw new DebuggerException("Unknown type");
@ -440,14 +451,16 @@ namespace Debugger.MetaData @@ -440,14 +451,16 @@ namespace Debugger.MetaData
}
}
public static DebugType GetType(Process process, string fullTypeName)
public static DebugType GetType(Process process, uint? domainID, string fullTypeName)
{
foreach(Module module in process.Modules) {
try {
uint token = module.MetaData.FindTypeDefByName(fullTypeName, 0).Token;
return Create(process, module.CorModule.GetClassFromToken(token));
} catch {
continue;
if (!domainID.HasValue || domainID == module.CorModule.Assembly.AppDomain.ID) {
try {
uint token = module.MetaData.FindTypeDefByName(fullTypeName, 0 /* enclosing class for nested */).Token;
return Create(process, module.CorModule.GetClassFromToken(token));
} catch {
continue;
}
}
}
return null;

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

@ -163,26 +163,23 @@ namespace Debugger.MetaData @@ -163,26 +163,23 @@ namespace Debugger.MetaData
/// <summary>
/// Get a method from a managed type, method name and argument count
/// </summary>
public static MethodInfo GetFromName(Process process, System.Type type, string name, int paramCount)
public static MethodInfo GetFromName(Process process, uint? domainID, 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");
foreach(Module module in process.Modules) {
TypeDefProps typeDefProps = module.MetaData.FindTypeDefByName(type.FullName, 0 /* enclosing class for nested */);
foreach(MethodProps methodProps in module.MetaData.EnumMethodsWithName(typeDefProps.Token, name)) {
if (module.MetaData.GetParamCount(methodProps.Token) == paramCount) {
ICorDebugFunction corFunction = module.CorModule.GetFunctionFromToken(methodProps.Token);
ICorDebugClass2 corClass = corFunction.Class.As<ICorDebugClass2>();
ICorDebugType corType = corClass.GetParameterizedType(type.IsValueType ? (uint)CorElementType.VALUETYPE : (uint)CorElementType.CLASS,
0,
new ICorDebugType[] {});
return DebugType.Create(process, corType).GetMethod(methodProps.Token);
}
DebugType debugType = DebugType.GetType(process, domainID, type.FullName);
if (debugType == null) {
throw new DebuggerException("Type " + type.FullName + " not found");
}
foreach(MethodInfo methodInfo in debugType.GetMethods(methodName)) {
if (methodInfo.ParameterCount == paramCount) {
return methodInfo;
}
}
throw new DebuggerException("Not found");
throw new DebuggerException("Method " + methodName + " not found");
}
internal ISymUnmanagedMethod SymMethod {

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

@ -238,7 +238,7 @@ namespace Debugger @@ -238,7 +238,7 @@ namespace Debugger
{
if (IsPrimitive) return AsString;
// if (!IsObject) // Can invoke on primitives
return Eval.InvokeMethod(Process, typeof(object), "ToString", this, new Value[] {}).AsString;
return Eval.InvokeMethod(Process, this.Type.AppDomainID, typeof(object), "ToString", this, new Value[] {}).AsString;
}
#region Convenience overload methods

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

@ -132,9 +132,10 @@ namespace Debugger @@ -132,9 +132,10 @@ namespace Debugger
this.rawCorValue_pauseSession = process.PauseSession;
if (this.CorValue == null) {
type = DebugType.GetType(this.Process, "System.Object");
type = DebugType.GetType(this.Process, null, "System.Object");
} else {
type = DebugType.Create(process, this.CorValue.CastTo<ICorDebugValue2>().ExactType);
ICorDebugType exactType = this.CorValue.CastTo<ICorDebugValue2>().ExactType;
type = DebugType.Create(this.Process, exactType);
}
}

Loading…
Cancel
Save