Browse Source

More flexible API for local variables;

Get type of local variable;  
Generalized getting of type/method attributes

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4825 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 17 years ago
parent
commit
1f4dd33f53
  1. 26
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/StackFrame.cs
  2. 5
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs
  3. 4
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorSym/ISymUnmanagedVariable.cs
  4. 16
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/DebugType.cs
  5. 134
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Metadata/MethodInfo.cs
  6. 8
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Mono.Cecil/Mono.Cecil.Signatures/SignatureReader.cs
  7. 1
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugGenericValue.cs
  8. 16
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorSym/ISymUnmanagedVariable.cs

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

@ -376,31 +376,15 @@ namespace Debugger
#endregion #endregion
/// <summary> Returns value of give local variable </summary>
public Value GetLocalVariableValue(ISymUnmanagedVariable symVar)
{
return new Value(this.AppDomain, new IdentifierExpression(symVar.Name), GetLocalVariableCorValue(symVar));
}
ICorDebugValue GetLocalVariableCorValue(ISymUnmanagedVariable symVar)
{
try {
return CorILFrame.GetLocalVariable((uint)symVar.AddressField1);
} catch (COMException e) {
if ((uint)e.ErrorCode == 0x80131304) throw new GetValueException("Unavailable in optimized code");
throw;
}
}
#region Convenience methods #region Convenience methods
/// <summary> Get local variable with given name </summary> /// <summary> Get local variable with given name </summary>
/// <returns> Null if not found </returns> /// <returns> Null if not found </returns>
public Value GetLocalVariableValue(string name) public Value GetLocalVariableValue(string name)
{ {
foreach(ISymUnmanagedVariable symVar in this.MethodInfo.LocalVariables) { foreach(LocalVariableInfo locVar in this.MethodInfo.LocalVariables) {
if (symVar.Name == name) { if (locVar.Name == name) {
return GetLocalVariableValue(symVar); return locVar.GetValue(this);
} }
} }
return null; return null;
@ -410,8 +394,8 @@ namespace Debugger
public List<Value> GetLocalVariableValues() public List<Value> GetLocalVariableValues()
{ {
List<Value> values = new List<Value>(); List<Value> values = new List<Value>();
foreach(ISymUnmanagedVariable symVar in this.MethodInfo.LocalVariables) { foreach(LocalVariableInfo locVar in this.MethodInfo.LocalVariables) {
values.Add(GetLocalVariableValue(symVar)); values.Add(locVar.GetValue(this));
} }
return values; return values;
} }

5
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs

@ -115,7 +115,8 @@ namespace Debugger
val = (Value)expression.AcceptVisitor(this, null); val = (Value)expression.AcceptVisitor(this, null);
if (val != null && permRef) if (val != null && permRef)
val = val.GetPermanentReference(); val = val.GetPermanentReference();
} catch (GetValueException) { } catch (GetValueException e) {
e.Expression = expression;
throw; throw;
} catch (NotImplementedException e) { } catch (NotImplementedException e) {
throw new GetValueException(expression, "Language feature not implemented: " + e.Message); throw new GetValueException(expression, "Language feature not implemented: " + e.Message);
@ -125,7 +126,7 @@ namespace Debugger
} }
if (val != null && val.IsInvalid) if (val != null && val.IsInvalid)
throw new DebuggerException("Expression is invalid right after evaluation"); throw new DebuggerException("Expression \"" + expression.PrettyPrint() + "\" is invalid right after evaluation");
// Add the result to cache // Add the result to cache
context.Process.CachedExpressions[expression] = val; context.Process.CachedExpressions[expression] = val;

4
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorSym/ISymUnmanagedVariable.cs

@ -17,11 +17,11 @@ namespace Debugger.Interop.CorSym
public interface ISymUnmanagedVariable public interface ISymUnmanagedVariable
{ {
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
void GetName([In] uint cchName, out uint pcchName, [Out] IntPtr szName); void GetName([In] uint cchName, out uint pcchName, [In] IntPtr szName);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
uint GetAttributes(); uint GetAttributes();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
void GetSignature([In] uint cSig, out uint pcSig, [Out] IntPtr sig); void GetSignature([In] uint cSig, out uint pcSig, [In] IntPtr sig);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
uint GetAddressKind(); uint GetAddressKind();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]

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

@ -721,6 +721,22 @@ namespace Debugger.MetaData
return (GetMembers(bindingFlags).Count > 0); return (GetMembers(bindingFlags).Count > 0);
} }
public bool IsCompilerGenerated {
get {
if (this.IsClass || this.IsValueType) {
return MethodInfo.HasAnyAttribute(this.Module.MetaData, this.Token, typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute));
} else {
return false;
}
}
}
public bool IsDisplayClass {
get {
return this.IsCompilerGenerated && this.Name.Contains("DisplayClass");
}
}
public override string ToString() public override string ToString()
{ {
return string.Format("{0}", this.FullName); return string.Format("{0}", this.FullName);

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

@ -5,13 +5,14 @@
// <version>$Revision$</version> // <version>$Revision$</version>
// </file> // </file>
using ICSharpCode.NRefactory.Ast;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Debugger.Wrappers.CorDebug; using Debugger.Wrappers.CorDebug;
using Debugger.Wrappers.CorSym; using Debugger.Wrappers.CorSym;
using Debugger.Wrappers.MetaData; using Debugger.Wrappers.MetaData;
using ICSharpCode.NRefactory.Ast;
using Mono.Cecil.Signatures; using Mono.Cecil.Signatures;
using System.Runtime.InteropServices;
namespace Debugger.MetaData namespace Debugger.MetaData
{ {
@ -311,32 +312,42 @@ namespace Debugger.MetaData
get { get {
if (hasDebuggerAttributeCache.HasValue) return hasDebuggerAttributeCache.Value; if (hasDebuggerAttributeCache.HasValue) return hasDebuggerAttributeCache.Value;
MetaDataImport metaData = this.Module.MetaData; hasDebuggerAttributeCache =
hasDebuggerAttributeCache = false; // Look on the method
// Look on the method HasAnyAttribute(this.Module.MetaData, methodProps.Token,
foreach(CustomAttributeProps ca in metaData.EnumCustomAttributeProps(methodProps.Token, 0)) { typeof(System.Diagnostics.DebuggerStepThroughAttribute),
typeof(System.Diagnostics.DebuggerNonUserCodeAttribute),
typeof(System.Diagnostics.DebuggerHiddenAttribute))
||
// Look on the type
HasAnyAttribute(this.Module.MetaData, this.DeclaringType.Token,
typeof(System.Diagnostics.DebuggerStepThroughAttribute),
typeof(System.Diagnostics.DebuggerNonUserCodeAttribute),
typeof(System.Diagnostics.DebuggerHiddenAttribute));
return hasDebuggerAttributeCache.Value;
}
}
internal static bool HasAnyAttribute(MetaDataImport metaData, uint token, params Type[] wantedAttrTypes)
{
foreach(CustomAttributeProps ca in metaData.EnumCustomAttributeProps(token, 0)) {
CorTokenType tkType = (CorTokenType)(ca.Type & 0xFF000000);
string attributeName;
if (tkType == CorTokenType.MemberRef) {
MemberRefProps constructorMethod = metaData.GetMemberRefProps(ca.Type); MemberRefProps constructorMethod = metaData.GetMemberRefProps(ca.Type);
TypeRefProps attributeType = metaData.GetTypeRefProps(constructorMethod.DeclaringType); attributeName = metaData.GetTypeRefProps(constructorMethod.DeclaringType).Name;
if (attributeType.Name == "System.Diagnostics.DebuggerStepThroughAttribute" || } else if (tkType == CorTokenType.MethodDef) {
attributeType.Name == "System.Diagnostics.DebuggerNonUserCodeAttribute" || MethodProps constructorMethod = metaData.GetMethodProps(ca.Type);
attributeType.Name == "System.Diagnostics.DebuggerHiddenAttribute") attributeName = metaData.GetTypeDefProps(constructorMethod.ClassToken).Name;
{ } else {
hasDebuggerAttributeCache = true; throw new DebuggerException("Not expected: " + tkType);
}
} }
// Look on the type foreach(Type wantedAttrType in wantedAttrTypes) {
foreach(CustomAttributeProps ca in metaData.EnumCustomAttributeProps(this.DeclaringType.Token, 0)) { if (attributeName == wantedAttrType.FullName)
MemberRefProps constructorMethod = metaData.GetMemberRefProps(ca.Type); return true;
TypeRefProps attributeType = metaData.GetTypeRefProps(constructorMethod.DeclaringType);
if (attributeType.Name == "System.Diagnostics.DebuggerStepThroughAttribute" ||
attributeType.Name == "System.Diagnostics.DebuggerNonUserCodeAttribute" ||
attributeType.Name == "System.Diagnostics.DebuggerHiddenAttribute")
{
hasDebuggerAttributeCache = true;
}
} }
return hasDebuggerAttributeCache.Value;
} }
return false;
} }
internal void MarkAsNonUserCode() internal void MarkAsNonUserCode()
@ -413,19 +424,19 @@ namespace Debugger.MetaData
} }
[Debugger.Tests.Ignore] [Debugger.Tests.Ignore]
public List<ISymUnmanagedVariable> LocalVariables { public List<LocalVariableInfo> LocalVariables {
get { get {
if (this.SymMethod != null) { // TODO: Is this needed? if (this.SymMethod != null) { // TODO: Is this needed?
return GetLocalVariablesInScope(this.SymMethod.RootScope); return GetLocalVariablesInScope(this.SymMethod.RootScope);
} else { } else {
return new List<ISymUnmanagedVariable>(); return new List<LocalVariableInfo>();
} }
} }
} }
public string[] LocalVariableNames { public string[] LocalVariableNames {
get { get {
List<ISymUnmanagedVariable> vars = LocalVariables; List<LocalVariableInfo> vars = this.LocalVariables;
List<string> names = new List<string>(); List<string> names = new List<string>();
for(int i = 0; i < vars.Count; i++) { for(int i = 0; i < vars.Count; i++) {
names.Add(vars[i].Name); names.Add(vars[i].Name);
@ -435,12 +446,29 @@ namespace Debugger.MetaData
} }
} }
List<ISymUnmanagedVariable> GetLocalVariablesInScope(ISymUnmanagedScope symScope) List<LocalVariableInfo> GetLocalVariablesInScope(ISymUnmanagedScope symScope)
{ {
List<ISymUnmanagedVariable> vars = new List<ISymUnmanagedVariable>(); List<LocalVariableInfo> vars = new List<LocalVariableInfo>();
foreach (ISymUnmanagedVariable symVar in symScope.Locals) { foreach (ISymUnmanagedVariable symVar in symScope.Locals) {
if (!symVar.Name.StartsWith("CS$")) { // TODO: Generalize int start;
vars.Add(symVar); SignatureReader sigReader = new SignatureReader(symVar.Signature);
LocalVarSig.LocalVariable locVarSig = sigReader.ReadLocalVariable(sigReader.Blob, 0, out start);
DebugType type = DebugType.CreateFromSignature(this.Module, locVarSig.Type, this.DeclaringType);
// Compiler generated?
if ((symVar.Attributes & 1) == 1) {
if (type.IsDisplayClass) {
}
} else {
ISymUnmanagedVariable symVarCopy = symVar;
LocalVariableInfo locVar = new LocalVariableInfo(
symVar.Name,
type,
delegate(StackFrame context) {
return GetLocalVariableValue(context, symVarCopy);
}
);
vars.Add(locVar);
} }
} }
foreach(ISymUnmanagedScope childScope in symScope.Children) { foreach(ISymUnmanagedScope childScope in symScope.Children) {
@ -448,5 +476,51 @@ namespace Debugger.MetaData
} }
return vars; return vars;
} }
static Value GetLocalVariableValue(StackFrame context, ISymUnmanagedVariable symVar)
{
ICorDebugValue corVal;
try {
corVal = context.CorILFrame.GetLocalVariable((uint)symVar.AddressField1);
} catch (COMException e) {
if ((uint)e.ErrorCode == 0x80131304) throw new GetValueException("Unavailable in optimized code");
throw;
}
return new Value(context.AppDomain, new IdentifierExpression(symVar.Name), corVal);
}
}
public class LocalVariableInfo
{
public delegate Value LocalVariableValueGetter(StackFrame context);
string name;
DebugType type;
LocalVariableValueGetter getter;
public string Name {
get { return name; }
}
public DebugType Type {
get { return type; }
}
public LocalVariableInfo(string name, DebugType type, LocalVariableValueGetter getter)
{
this.name = name;
this.type = type;
this.getter = getter;
}
public Value GetValue(StackFrame context)
{
return getter(context);
}
public override string ToString()
{
return this.Type.ToString() + " " + this.Name;
}
} }
} }

8
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Mono.Cecil/Mono.Cecil.Signatures/SignatureReader.cs

@ -41,6 +41,12 @@ namespace Mono.Cecil.Signatures {
byte [] m_blobData; byte [] m_blobData;
IDictionary m_signatures; IDictionary m_signatures;
public byte[] Blob {
get {
return m_blobData;
}
}
public SignatureReader (byte [] blobData) public SignatureReader (byte [] blobData)
{ {
m_blobData = blobData; m_blobData = blobData;
@ -325,7 +331,7 @@ namespace Mono.Cecil.Signatures {
return types; return types;
} }
LocalVarSig.LocalVariable ReadLocalVariable (byte [] data, int pos, out int start) public LocalVarSig.LocalVariable ReadLocalVariable (byte [] data, int pos, out int start)
{ {
start = pos; start = pos;
LocalVarSig.LocalVariable lv = new LocalVarSig.LocalVariable (); LocalVarSig.LocalVariable lv = new LocalVarSig.LocalVariable ();

1
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/ICorDebugGenericValue.cs

@ -16,6 +16,7 @@ namespace Debugger.Wrappers.CorDebug
{ {
public unsafe Byte[] RawValue { public unsafe Byte[] RawValue {
get { get {
// TODO: Unset fixing insead
Byte[] retValue = new Byte[(int)Size]; Byte[] retValue = new Byte[(int)Size];
IntPtr pValue = Marshal.AllocHGlobal(retValue.Length); IntPtr pValue = Marshal.AllocHGlobal(retValue.Length);
GetValue(pValue); GetValue(pValue);

16
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorSym/ISymUnmanagedVariable.cs

@ -18,6 +18,22 @@ namespace Debugger.Wrappers.CorSym
return Util.GetString(GetName); return Util.GetString(GetName);
} }
} }
const int defaultSigSize = 8;
public unsafe byte[] Signature {
get {
byte[] sig = new byte[defaultSigSize];
uint acualSize;
fixed(byte* pSig = sig)
this.GetSignature((uint)sig.Length, out acualSize, new IntPtr(pSig));
Array.Resize(ref sig, (int)acualSize);
if (acualSize > defaultSigSize)
fixed(byte* pSig = sig)
this.GetSignature((uint)sig.Length, out acualSize, new IntPtr(pSig));
return sig;
}
}
} }
} }

Loading…
Cancel
Save