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ý 16 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 @@ -376,31 +376,15 @@ namespace Debugger
#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
/// <summary> Get local variable with given name </summary>
/// <returns> Null if not found </returns>
public Value GetLocalVariableValue(string name)
{
foreach(ISymUnmanagedVariable symVar in this.MethodInfo.LocalVariables) {
if (symVar.Name == name) {
return GetLocalVariableValue(symVar);
foreach(LocalVariableInfo locVar in this.MethodInfo.LocalVariables) {
if (locVar.Name == name) {
return locVar.GetValue(this);
}
}
return null;
@ -410,8 +394,8 @@ namespace Debugger @@ -410,8 +394,8 @@ namespace Debugger
public List<Value> GetLocalVariableValues()
{
List<Value> values = new List<Value>();
foreach(ISymUnmanagedVariable symVar in this.MethodInfo.LocalVariables) {
values.Add(GetLocalVariableValue(symVar));
foreach(LocalVariableInfo locVar in this.MethodInfo.LocalVariables) {
values.Add(locVar.GetValue(this));
}
return values;
}

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

@ -115,7 +115,8 @@ namespace Debugger @@ -115,7 +115,8 @@ namespace Debugger
val = (Value)expression.AcceptVisitor(this, null);
if (val != null && permRef)
val = val.GetPermanentReference();
} catch (GetValueException) {
} catch (GetValueException e) {
e.Expression = expression;
throw;
} catch (NotImplementedException e) {
throw new GetValueException(expression, "Language feature not implemented: " + e.Message);
@ -125,7 +126,7 @@ namespace Debugger @@ -125,7 +126,7 @@ namespace Debugger
}
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
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 @@ -17,11 +17,11 @@ namespace Debugger.Interop.CorSym
public interface ISymUnmanagedVariable
{
[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)]
uint GetAttributes();
[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)]
uint GetAddressKind();
[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 @@ -721,6 +721,22 @@ namespace Debugger.MetaData
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()
{
return string.Format("{0}", this.FullName);

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

@ -5,13 +5,14 @@ @@ -5,13 +5,14 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.NRefactory.Ast;
using System;
using System.Collections.Generic;
using Debugger.Wrappers.CorDebug;
using Debugger.Wrappers.CorSym;
using Debugger.Wrappers.MetaData;
using ICSharpCode.NRefactory.Ast;
using Mono.Cecil.Signatures;
using System.Runtime.InteropServices;
namespace Debugger.MetaData
{
@ -311,32 +312,42 @@ namespace Debugger.MetaData @@ -311,32 +312,42 @@ namespace Debugger.MetaData
get {
if (hasDebuggerAttributeCache.HasValue) return hasDebuggerAttributeCache.Value;
MetaDataImport metaData = this.Module.MetaData;
hasDebuggerAttributeCache = false;
// Look on the method
foreach(CustomAttributeProps ca in metaData.EnumCustomAttributeProps(methodProps.Token, 0)) {
hasDebuggerAttributeCache =
// Look on the method
HasAnyAttribute(this.Module.MetaData, methodProps.Token,
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);
TypeRefProps attributeType = metaData.GetTypeRefProps(constructorMethod.DeclaringType);
if (attributeType.Name == "System.Diagnostics.DebuggerStepThroughAttribute" ||
attributeType.Name == "System.Diagnostics.DebuggerNonUserCodeAttribute" ||
attributeType.Name == "System.Diagnostics.DebuggerHiddenAttribute")
{
hasDebuggerAttributeCache = true;
}
attributeName = metaData.GetTypeRefProps(constructorMethod.DeclaringType).Name;
} else if (tkType == CorTokenType.MethodDef) {
MethodProps constructorMethod = metaData.GetMethodProps(ca.Type);
attributeName = metaData.GetTypeDefProps(constructorMethod.ClassToken).Name;
} else {
throw new DebuggerException("Not expected: " + tkType);
}
// Look on the type
foreach(CustomAttributeProps ca in metaData.EnumCustomAttributeProps(this.DeclaringType.Token, 0)) {
MemberRefProps constructorMethod = metaData.GetMemberRefProps(ca.Type);
TypeRefProps attributeType = metaData.GetTypeRefProps(constructorMethod.DeclaringType);
if (attributeType.Name == "System.Diagnostics.DebuggerStepThroughAttribute" ||
attributeType.Name == "System.Diagnostics.DebuggerNonUserCodeAttribute" ||
attributeType.Name == "System.Diagnostics.DebuggerHiddenAttribute")
{
hasDebuggerAttributeCache = true;
}
foreach(Type wantedAttrType in wantedAttrTypes) {
if (attributeName == wantedAttrType.FullName)
return true;
}
return hasDebuggerAttributeCache.Value;
}
return false;
}
internal void MarkAsNonUserCode()
@ -413,19 +424,19 @@ namespace Debugger.MetaData @@ -413,19 +424,19 @@ namespace Debugger.MetaData
}
[Debugger.Tests.Ignore]
public List<ISymUnmanagedVariable> LocalVariables {
public List<LocalVariableInfo> LocalVariables {
get {
if (this.SymMethod != null) { // TODO: Is this needed?
return GetLocalVariablesInScope(this.SymMethod.RootScope);
} else {
return new List<ISymUnmanagedVariable>();
return new List<LocalVariableInfo>();
}
}
}
public string[] LocalVariableNames {
get {
List<ISymUnmanagedVariable> vars = LocalVariables;
List<LocalVariableInfo> vars = this.LocalVariables;
List<string> names = new List<string>();
for(int i = 0; i < vars.Count; i++) {
names.Add(vars[i].Name);
@ -435,12 +446,29 @@ namespace Debugger.MetaData @@ -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) {
if (!symVar.Name.StartsWith("CS$")) { // TODO: Generalize
vars.Add(symVar);
int start;
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) {
@ -448,5 +476,51 @@ namespace Debugger.MetaData @@ -448,5 +476,51 @@ namespace Debugger.MetaData
}
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 { @@ -41,6 +41,12 @@ namespace Mono.Cecil.Signatures {
byte [] m_blobData;
IDictionary m_signatures;
public byte[] Blob {
get {
return m_blobData;
}
}
public SignatureReader (byte [] blobData)
{
m_blobData = blobData;
@ -325,7 +331,7 @@ namespace Mono.Cecil.Signatures { @@ -325,7 +331,7 @@ namespace Mono.Cecil.Signatures {
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;
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 @@ -16,6 +16,7 @@ namespace Debugger.Wrappers.CorDebug
{
public unsafe Byte[] RawValue {
get {
// TODO: Unset fixing insead
Byte[] retValue = new Byte[(int)Size];
IntPtr pValue = Marshal.AllocHGlobal(retValue.Length);
GetValue(pValue);

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

@ -18,6 +18,22 @@ namespace Debugger.Wrappers.CorSym @@ -18,6 +18,22 @@ namespace Debugger.Wrappers.CorSym
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