Browse Source

Added more error checking for objects. Better support for getting values of static members.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2826 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 18 years ago
parent
commit
b743ec5656
  1. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs
  2. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/StackFrame.cs
  3. 4
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs
  4. 3
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value.Array.cs
  5. 111
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value.Object.cs
  6. 8
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/DebuggerTests.cs

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs

@ -37,7 +37,7 @@ namespace Debugger @@ -37,7 +37,7 @@ namespace Debugger
corValue = thread.CorThread.CurrentException;
exceptionType = thread.CurrentExceptionType;
Value runtimeValue = new Value(process, corValue);
message = runtimeValue.GetMember("_message").AsString;
message = runtimeValue.GetMemberValue("_message").AsString;
if (thread.LastStackFrameWithLoadedSymbols != null) {
location = thread.LastStackFrameWithLoadedSymbols.NextStatement;

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/StackFrame.cs

@ -370,7 +370,7 @@ namespace Debugger @@ -370,7 +370,7 @@ namespace Debugger
get {
// TODO: Should work for static
if (!this.MethodInfo.IsStatic) {
return ThisValue.GetMembers();
return ThisValue.GetMemberValues();
} else {
return ValueCollection.Empty;
}

4
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs

@ -153,7 +153,7 @@ namespace Debugger @@ -153,7 +153,7 @@ namespace Debugger
Value runTimeValue = RuntimeValue;
if (runTimeValue.IsNull) return ThreadPriority.Normal;
lastPriority = (ThreadPriority)(int)runTimeValue.GetMember("m_Priority").PrimitiveValue;
lastPriority = (ThreadPriority)(int)runTimeValue.GetMemberValue("m_Priority").PrimitiveValue;
return lastPriority;
}
}
@ -173,7 +173,7 @@ namespace Debugger @@ -173,7 +173,7 @@ namespace Debugger
if (process.IsRunning) return lastName;
Value runtimeValue = RuntimeValue;
if (runtimeValue.IsNull) return lastName;
Value runtimeName = runtimeValue.GetMember("m_Name");
Value runtimeName = runtimeValue.GetMemberValue("m_Name");
if (runtimeName.IsNull) return string.Empty;
lastName = runtimeName.AsString.ToString();
return lastName;

3
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Values/Value.Array.cs

@ -103,6 +103,9 @@ namespace Debugger @@ -103,6 +103,9 @@ namespace Debugger
// May be called later
ICorDebugValue GetCorValueOfArrayElement(int[] indices)
{
if (IsNull) {
throw new GetValueException("Null reference");
}
if (!IsArray) {
throw new GetValueException("The value is not an array");
}

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

@ -31,42 +31,72 @@ namespace Debugger @@ -31,42 +31,72 @@ namespace Debugger
}
}
/// <summary>
/// Get the value of given member.
/// </summary>
static void CheckObject(Value objectInstance, MemberInfo memberInfo)
{
if (!memberInfo.IsStatic) {
if (objectInstance == null) {
throw new DebuggerException("No target object specified");
}
if (objectInstance.IsNull) {
throw new GetValueException("Null reference");
}
if (!objectInstance.IsObject) {
throw new GetValueException("Target object is not class or value type");
}
if (!memberInfo.DeclaringType.IsInstanceOfType(objectInstance)) {
throw new GetValueException("Object is not of type " + memberInfo.DeclaringType.FullName);
}
}
}
#region Convenience overload methods
/// <summary> Get the value of given member. </summary>
public Value GetMemberValue(MemberInfo memberInfo)
{
return GetMemberValue(this, memberInfo, null);
}
/// <summary> Get the value of given member. </summary>
public Value GetMemberValue(MemberInfo memberInfo, Value[] arguments)
{
return GetMemberValue(this, memberInfo, arguments);
}
#endregion
/// <summary> Get the value of given member. </summary>
/// <param name="objectInstance">null if member is static</param>
public static Value GetMemberValue(Value objectInstance, MemberInfo memberInfo, Value[] arguments)
{
arguments = arguments ?? new Value[0];
if (memberInfo is FieldInfo) {
if (arguments.Length > 0) throw new GetValueException("Arguments can not be used for a field");
return GetFieldValue(objectInstance, (FieldInfo)memberInfo);
} else if (memberInfo is PropertyInfo) {
return GetPropertyValue(objectInstance, (PropertyInfo)memberInfo);
return GetPropertyValue(objectInstance, (PropertyInfo)memberInfo, arguments);
} else if (memberInfo is MethodInfo) {
return InvokeMethod(objectInstance, (MethodInfo)memberInfo, arguments);
}
throw new DebuggerException("Bad member type: " + memberInfo.GetType());
throw new DebuggerException("Unknown member type: " + memberInfo.GetType());
}
/// <summary>
/// Get the value of given field.
/// Field may be static
/// </summary>
#region Convenience overload methods
/// <summary> Get the value of given field. </summary>
public Value GetFieldValue(FieldInfo fieldInfo)
{
return Value.GetFieldValue(this, fieldInfo);
}
/// <summary>
/// Get the value of given field.
/// objectInstance must not be null.
/// Field may be static
/// </summary>
#endregion
/// <summary> Get the value of given field. </summary>
/// <param name="objectInstance">null if field is static</param>
public static Value GetFieldValue(Value objectInstance, FieldInfo fieldInfo)
{
return new Value(
objectInstance.Process,
fieldInfo.Process,
fieldInfo.Name,
GetFieldCorValue(objectInstance, fieldInfo)
);
@ -74,16 +104,14 @@ namespace Debugger @@ -74,16 +104,14 @@ namespace Debugger
static ICorDebugValue GetFieldCorValue(Value objectInstance, FieldInfo fieldInfo)
{
if (!fieldInfo.DeclaringType.IsInstanceOfType(objectInstance)) {
throw new GetValueException("Object is not of type " + fieldInfo.DeclaringType.FullName);
}
CheckObject(objectInstance, fieldInfo);
// Current frame is used to resolve context specific static values (eg. ThreadStatic)
ICorDebugFrame curFrame = null;
if (objectInstance.Process.IsPaused &&
objectInstance.Process.SelectedThread != null &&
objectInstance.Process.SelectedThread.LastStackFrame != null &&
objectInstance.Process.SelectedThread.LastStackFrame.CorILFrame != null) {
if (fieldInfo.Process.IsPaused &&
fieldInfo.Process.SelectedThread != null &&
fieldInfo.Process.SelectedThread.LastStackFrame != null &&
fieldInfo.Process.SelectedThread.LastStackFrame.CorILFrame != null) {
curFrame = objectInstance.Process.SelectedThread.LastStackFrame.CorILFrame.CastTo<ICorDebugFrame>();
}
@ -99,6 +127,8 @@ namespace Debugger @@ -99,6 +127,8 @@ namespace Debugger
}
}
#region Convenience overload methods
/// <summary> Get the value of the property using the get accessor </summary>
public Value GetPropertyValue(PropertyInfo propertyInfo)
{
@ -117,23 +147,25 @@ namespace Debugger @@ -117,23 +147,25 @@ namespace Debugger
return GetPropertyValue(objectInstance, propertyInfo, null);
}
#endregion
/// <summary> Get the value of the property using the get accessor </summary>
public static Value GetPropertyValue(Value objectInstance, PropertyInfo propertyInfo, Value[] arguments)
{
CheckObject(objectInstance, propertyInfo);
if (propertyInfo.GetMethod == null) throw new GetValueException("Property does not have a get method");
arguments = arguments ?? new Value[0];
List<Value> dependencies = new List<Value>();
dependencies.Add(objectInstance);
dependencies.AddRange(arguments);
return new Value(
objectInstance.Process,
propertyInfo.Process,
propertyInfo.Name,
Value.InvokeMethod(objectInstance, propertyInfo.GetMethod, arguments).RawCorValue
);
}
#region Convenience overload methods
/// <summary> Set the value of the property using the set accessor </summary>
public Value SetPropertyValue(PropertyInfo propertyInfo, Value newValue)
{
@ -152,12 +184,17 @@ namespace Debugger @@ -152,12 +184,17 @@ namespace Debugger
return SetPropertyValue(objectInstance, propertyInfo, null, newValue);
}
#endregion
/// <summary> Set the value of the property using the set accessor </summary>
public static Value SetPropertyValue(Value objectInstance, PropertyInfo propertyInfo, Value[] arguments, Value newValue)
{
CheckObject(objectInstance, propertyInfo);
if (propertyInfo.SetMethod == null) throw new GetValueException("Property does not have a set method");
arguments = arguments ?? new Value[0];
Value[] allParams = new Value[1 + arguments.Length];
allParams[0] = newValue;
arguments.CopyTo(allParams, 1);
@ -165,15 +202,21 @@ namespace Debugger @@ -165,15 +202,21 @@ namespace Debugger
return Value.InvokeMethod(objectInstance, propertyInfo.SetMethod, allParams);
}
#region Convenience overload methods
/// <summary> Synchronously invoke the method </summary>
public Value InvokeMethod(MethodInfo methodInfo, params Value[] arguments)
{
return InvokeMethod(this, methodInfo, arguments);
}
#endregion
/// <summary> Synchronously invoke the method </summary>
public static Value InvokeMethod(Value objectInstance, MethodInfo methodInfo, params Value[] arguments)
{
CheckObject(objectInstance, methodInfo);
return Eval.InvokeMethod(
methodInfo,
methodInfo.IsStatic ? null : objectInstance,
@ -181,15 +224,21 @@ namespace Debugger @@ -181,15 +224,21 @@ namespace Debugger
);
}
#region Convenience overload methods
/// <summary> Asynchronously invoke the method </summary>
public Eval AsyncInvokeMethod(MethodInfo methodInfo, params Value[] arguments)
{
return AsyncInvokeMethod(this, methodInfo, arguments);
}
#endregion
/// <summary> Asynchronously invoke the method </summary>
public static Eval AsyncInvokeMethod(Value objectInstance, MethodInfo methodInfo, params Value[] arguments)
{
CheckObject(objectInstance, methodInfo);
return Eval.AsyncInvokeMethod(
methodInfo,
methodInfo.IsStatic ? null : objectInstance,
@ -200,7 +249,7 @@ namespace Debugger @@ -200,7 +249,7 @@ namespace Debugger
/// <summary>
/// Get a field or property of an object with a given name.
/// </summary>
public Value GetMember(string name)
public Value GetMemberValue(string name)
{
DebugType currentType = this.Type;
while (currentType != null) {
@ -220,9 +269,9 @@ namespace Debugger @@ -220,9 +269,9 @@ namespace Debugger
/// <summary>
/// Get all fields and properties of an object.
/// </summary>
public ValueCollection GetMembers()
public ValueCollection GetMemberValues()
{
return GetMembers(null, BindingFlags.All);
return GetMemberValues(null, BindingFlags.All);
}
/// <summary>
@ -230,7 +279,7 @@ namespace Debugger @@ -230,7 +279,7 @@ namespace Debugger
/// </summary>
/// <param name="type"> Limit to type, null for all types </param>
/// <param name="bindingFlags"> Get only members with certain flags </param>
public ValueCollection GetMembers(DebugType type, BindingFlags bindingFlags)
public ValueCollection GetMemberValues(DebugType type, BindingFlags bindingFlags)
{
if (IsObject) {
return new ValueCollection(GetObjectMembersEnum(type, bindingFlags));

8
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/DebuggerTests.cs

@ -289,13 +289,13 @@ namespace Debugger.Tests @@ -289,13 +289,13 @@ namespace Debugger.Tests
WaitForPause();
val = process.SelectedStackFrame.LocalVariables["val"];
ObjectDump("val", val);
ObjectDump("val members", val.GetMembers(null, Debugger.BindingFlags.All));
ObjectDump("val members", val.GetMemberValues(null, Debugger.BindingFlags.All));
//ObjectDump("typeof(val)", val.Type);
process.Continue();
WaitForPause();
ObjectDump("val", val);
ObjectDump("val members", val.GetMembers(null, Debugger.BindingFlags.All));
ObjectDump("val members", val.GetMemberValues(null, Debugger.BindingFlags.All));
process.Continue();
process.WaitForExit();
@ -399,7 +399,7 @@ namespace Debugger.Tests @@ -399,7 +399,7 @@ namespace Debugger.Tests
StartTest("GenericDictionary");
WaitForPause();
ObjectDump("dict", process.SelectedStackFrame.LocalVariables["dict"]);
ObjectDump("dict members", process.SelectedStackFrame.LocalVariables["dict"].GetMembers(null, BindingFlags.All));
ObjectDump("dict members", process.SelectedStackFrame.LocalVariables["dict"].GetMemberValues(null, BindingFlags.All));
process.Continue();
process.WaitForExit();
@ -435,7 +435,7 @@ namespace Debugger.Tests @@ -435,7 +435,7 @@ namespace Debugger.Tests
ObjectDump("Variables", process.SelectedStackFrame.Variables);
ObjectDump("array", process.SelectedStackFrame.Variables["array"].GetArrayElements());
ObjectDump("array2", process.SelectedStackFrame.Variables["array2"].GetArrayElements());
ObjectDump("this", process.SelectedStackFrame.ThisValue.GetMembers());
ObjectDump("this", process.SelectedStackFrame.ThisValue.GetMemberValues());
process.Continue();
process.WaitForExit();

Loading…
Cancel
Save