Browse Source

Reverted expression caching

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4758 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 16 years ago
parent
commit
3cfb2f81a5
  1. 474
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/ExpressionEvaluator.cs
  2. 1
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/AstEval.cs
  3. 1
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Breakpoint.cs
  4. 2
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/MemoryReadWrite.cs
  5. 2
      src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/StackOverflow.cs

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

@ -121,12 +121,16 @@ namespace Debugger
return false; return false;
} }
Value EvalAndPermRef(INode expression) Value EvalAndCache(INode expression, bool permRef)
{ {
Stopwatch watch = new Stopwatch();
watch.Start();
Value val = (Value)expression.AcceptVisitor(this, null); Value val = (Value)expression.AcceptVisitor(this, null);
if (val != null) if (val != null && permRef)
val = val.GetPermanentReference(); val = val.GetPermanentReference();
AddToCache(expression, val); AddToCache(expression, val);
watch.Stop();
context.Process.TraceMessage("Evaluated: {0} in {1} ms total", expression.PrettyPrint(), watch.ElapsedMilliseconds);
return val; return val;
} }
@ -141,344 +145,256 @@ namespace Debugger
this.context = context; this.context = context;
} }
IDisposable LogEval(INode expression) public override object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data)
{
Stopwatch watch = new Stopwatch();
watch.Start();
return new CallbackOnDispose(delegate {
if (!context.Process.CachedExpressions.ContainsKey(expression))
throw new DebuggerException("Result not added to cache");
watch.Stop();
context.Process.TraceMessage("Evaluated: {0} in {1} ms total", expression.PrettyPrint(), watch.ElapsedMilliseconds);
});
}
public override object VisitEmptyStatement(EmptyStatement emptyStatement, object data)
{ {
using(LogEval(emptyStatement)) { BinaryOperatorType op;
return null; switch (assignmentExpression.Op) {
case AssignmentOperatorType.Assign: op = BinaryOperatorType.None; break;
case AssignmentOperatorType.Add: op = BinaryOperatorType.Add; break;
case AssignmentOperatorType.ConcatString: op = BinaryOperatorType.Concat; break;
case AssignmentOperatorType.Subtract: op = BinaryOperatorType.Subtract; break;
case AssignmentOperatorType.Multiply: op = BinaryOperatorType.Multiply; break;
case AssignmentOperatorType.Divide: op = BinaryOperatorType.Divide; break;
case AssignmentOperatorType.DivideInteger: op = BinaryOperatorType.DivideInteger; break;
case AssignmentOperatorType.ShiftLeft: op = BinaryOperatorType.ShiftLeft; break;
case AssignmentOperatorType.ShiftRight: op = BinaryOperatorType.ShiftRight; break;
case AssignmentOperatorType.ExclusiveOr: op = BinaryOperatorType.ExclusiveOr; break;
case AssignmentOperatorType.Modulus: op = BinaryOperatorType.Modulus; break;
case AssignmentOperatorType.BitwiseAnd: op = BinaryOperatorType.BitwiseAnd; break;
case AssignmentOperatorType.BitwiseOr: op = BinaryOperatorType.BitwiseOr; break;
case AssignmentOperatorType.Power: op = BinaryOperatorType.Power; break;
default: throw new GetValueException("Unknown operator " + assignmentExpression.Op);
} }
}
Value right;
public override object VisitExpressionStatement(ExpressionStatement expressionStatement, object data) if (op == BinaryOperatorType.None) {
{ right = (Value)assignmentExpression.Right.AcceptVisitor(this, null);
using(LogEval(expressionStatement)) { } else {
EvalAndPermRef(expressionStatement.Expression); BinaryOperatorExpression binOpExpr = new BinaryOperatorExpression();
return null; binOpExpr.Left = assignmentExpression.Left;
binOpExpr.Op = op;
binOpExpr.Right = assignmentExpression.Right;
right = (Value)VisitBinaryOperatorExpression(binOpExpr, null);
} }
right = right.GetPermanentReference();
Value left = ((Value)assignmentExpression.Left.AcceptVisitor(this, null));
if (!left.IsReference && left.Type.FullName != right.Type.FullName) {
throw new GetValueException(string.Format("Type {0} expected, {1} seen", left.Type.FullName, right.Type.FullName));
}
left.SetValue(right);
return right;
} }
public override object VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, object data) public override object VisitBlockStatement(BlockStatement blockStatement, object data)
{ {
Value cached; foreach(INode statement in blockStatement.Children) {
if (TryGetCached(parenthesizedExpression, out cached)) return cached; statement.AcceptVisitor(this, null);
using(LogEval(parenthesizedExpression)) {
Value res = EvalAndPermRef(parenthesizedExpression.Expression);
AddToCache(parenthesizedExpression, res);
return res;
} }
return null;
} }
public override object VisitBlockStatement(BlockStatement blockStatement, object data) public override object VisitEmptyStatement(EmptyStatement emptyStatement, object data)
{ {
using(LogEval(blockStatement)) { return null;
foreach(INode statement in blockStatement.Children) {
EvalAndPermRef(statement);
}
return null;
}
} }
/// <remarks> We have to put that in cache as well otherwise expaning (a = b).Prop will reevalute </remarks> public override object VisitExpressionStatement(ExpressionStatement expressionStatement, object data)
public override object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data)
{ {
Value cached; expressionStatement.Expression.AcceptVisitor(this, null);
if (TryGetCached(assignmentExpression, out cached)) return cached; return null;
using(LogEval(assignmentExpression)) {
BinaryOperatorType op;
switch (assignmentExpression.Op) {
case AssignmentOperatorType.Assign: op = BinaryOperatorType.None; break;
case AssignmentOperatorType.Add: op = BinaryOperatorType.Add; break;
case AssignmentOperatorType.ConcatString: op = BinaryOperatorType.Concat; break;
case AssignmentOperatorType.Subtract: op = BinaryOperatorType.Subtract; break;
case AssignmentOperatorType.Multiply: op = BinaryOperatorType.Multiply; break;
case AssignmentOperatorType.Divide: op = BinaryOperatorType.Divide; break;
case AssignmentOperatorType.DivideInteger: op = BinaryOperatorType.DivideInteger; break;
case AssignmentOperatorType.ShiftLeft: op = BinaryOperatorType.ShiftLeft; break;
case AssignmentOperatorType.ShiftRight: op = BinaryOperatorType.ShiftRight; break;
case AssignmentOperatorType.ExclusiveOr: op = BinaryOperatorType.ExclusiveOr; break;
case AssignmentOperatorType.Modulus: op = BinaryOperatorType.Modulus; break;
case AssignmentOperatorType.BitwiseAnd: op = BinaryOperatorType.BitwiseAnd; break;
case AssignmentOperatorType.BitwiseOr: op = BinaryOperatorType.BitwiseOr; break;
case AssignmentOperatorType.Power: op = BinaryOperatorType.Power; break;
default: throw new GetValueException("Unknown operator " + assignmentExpression.Op);
}
Value right;
if (op == BinaryOperatorType.None) {
right = EvalAndPermRef(assignmentExpression.Right);
} else {
BinaryOperatorExpression binOpExpr = new BinaryOperatorExpression();
binOpExpr.Left = assignmentExpression.Left;
binOpExpr.Op = op;
binOpExpr.Right = assignmentExpression.Right;
right = (Value)VisitBinaryOperatorExpression(binOpExpr, null);
}
right = right.GetPermanentReference();
Value left = EvalAndPermRef(assignmentExpression.Left);
if (!left.IsReference && left.Type.FullName != right.Type.FullName) {
throw new GetValueException(string.Format("Type {0} expected, {1} seen", left.Type.FullName, right.Type.FullName));
}
left.SetValue(right);
AddToCache(assignmentExpression, right);
return right;
}
} }
public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data) public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
{ {
Value cached; string identifier = identifierExpression.Identifier;
if (TryGetCached(identifierExpression, out cached)) return cached;
using(LogEval(identifierExpression)) { if (identifier == "__exception") {
string identifier = identifierExpression.Identifier; if (context.Thread.CurrentException != null) {
return context.Thread.CurrentException.Value;
Value result = null; } else {
throw new GetValueException("No current exception");
if (identifier == "__exception") {
if (context.Thread.CurrentException != null) {
result = context.Thread.CurrentException.Value;
} else {
throw new GetValueException("No current exception");
}
} }
}
result = result ?? context.GetArgumentValue(identifier);
Value arg = context.GetArgumentValue(identifier);
result = result ?? context.GetLocalVariableValue(identifier); if (arg != null) return arg;
if (result == null) { Value local = context.GetLocalVariableValue(identifier);
if (!context.MethodInfo.IsStatic) { if (local != null) return local;
// Can be null
result = context.GetThisValue().GetMemberValue(identifier); if (!context.MethodInfo.IsStatic) {
} else { Value member = context.GetThisValue().GetMemberValue(identifier);
MemberInfo memberInfo = context.MethodInfo.DeclaringType.GetMember(identifier); if (member != null) return member;
if (memberInfo != null && memberInfo.IsStatic) { } else {
result = Value.GetMemberValue(null, memberInfo, null); MemberInfo memberInfo = context.MethodInfo.DeclaringType.GetMember(identifier);
} if (memberInfo != null && memberInfo.IsStatic) {
} return Value.GetMemberValue(null, memberInfo, null);
} }
if (result == null)
throw new GetValueException("Identifier \"" + identifier + "\" not found in this context");
AddToCache(identifierExpression, result);
return result;
} }
throw new GetValueException("Identifier \"" + identifier + "\" not found in this context");
} }
public override object VisitIndexerExpression(IndexerExpression indexerExpression, object data) public override object VisitIndexerExpression(IndexerExpression indexerExpression, object data)
{ {
Value cached; List<Value> indexes = new List<Value>();
if (TryGetCached(indexerExpression, out cached)) return cached; foreach(Expression indexExpr in indexerExpression.Indexes) {
using(LogEval(indexerExpression)) { Value indexValue = ((Value)indexExpr.AcceptVisitor(this, null)).GetPermanentReference();
List<Value> indexes = new List<Value>(); indexes.Add(indexValue);
foreach(Expression indexExpr in indexerExpression.Indexes) { }
Value indexValue = EvalAndPermRef(indexExpr);
indexes.Add(indexValue); Value target = (Value)indexerExpression.TargetObject.AcceptVisitor(this, null);
}
if (target.Type.IsArray) {
Value target = EvalAndPermRef(indexerExpression.TargetObject); List<int> intIndexes = new List<int>();
foreach(Value index in indexes) {
if (target.Type.IsArray) { if (!index.Type.IsInteger) throw new GetValueException("Integer expected for indexer");
List<int> intIndexes = new List<int>(); intIndexes.Add((int)index.PrimitiveValue);
foreach(Value index in indexes) {
if (!index.Type.IsInteger) throw new GetValueException("Integer expected for indexer");
intIndexes.Add((int)index.PrimitiveValue);
}
return target.GetArrayElement(intIndexes.ToArray());
} }
return target.GetArrayElement(intIndexes.ToArray());
if (target.Type.IsPrimitive && target.PrimitiveValue is string) { }
if (indexes.Count == 1 && indexes[0].Type.IsInteger) {
int index = (int)indexes[0].PrimitiveValue; if (target.Type.IsPrimitive && target.PrimitiveValue is string) {
return Eval.CreateValue(context.AppDomain, ((string)target.PrimitiveValue)[index]); if (indexes.Count == 1 && indexes[0].Type.IsInteger) {
} else { int index = (int)indexes[0].PrimitiveValue;
throw new GetValueException("Expected single integer index"); return Eval.CreateValue(context.AppDomain, ((string)target.PrimitiveValue)[index]);
} } else {
throw new GetValueException("Expected single integer index");
} }
PropertyInfo pi = target.Type.GetProperty("Item");
if (pi == null) throw new GetValueException("The object does not have an indexer property");
Value result = target.GetPropertyValue(pi, indexes.ToArray());
AddToCache(indexerExpression, result);
return result;
} }
PropertyInfo pi = target.Type.GetProperty("Item");
if (pi == null) throw new GetValueException("The object does not have an indexer property");
return target.GetPropertyValue(pi, indexes.ToArray());
} }
public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data) public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
{ {
Value cached; Value target;
if (TryGetCached(invocationExpression, out cached)) return cached; string methodName;
using(LogEval(invocationExpression)) { MemberReferenceExpression memberRef = invocationExpression.TargetObject as MemberReferenceExpression;
Value target; if (memberRef != null) {
string methodName; target = ((Value)memberRef.TargetObject.AcceptVisitor(this, null)).GetPermanentReference();
MemberReferenceExpression memberRef = invocationExpression.TargetObject as MemberReferenceExpression; methodName = memberRef.MemberName;
if (memberRef != null) { } else {
target = EvalAndPermRef(memberRef.TargetObject); IdentifierExpression ident = invocationExpression.TargetObject as IdentifierExpression;
methodName = memberRef.MemberName; if (ident != null) {
target = context.GetThisValue();
methodName = ident.Identifier;
} else { } else {
IdentifierExpression ident = invocationExpression.TargetObject as IdentifierExpression; throw new GetValueException("Member reference expected for method invocation");
if (ident != null) {
target = context.GetThisValue();
methodName = ident.Identifier;
} else {
throw new GetValueException("Member reference expected for method invocation");
}
}
List<Value> args = new List<Value>();
foreach(Expression expr in invocationExpression.Arguments) {
args.Add(EvalAndPermRef(expr));
} }
MethodInfo method = target.Type.GetMember(methodName, BindingFlags.Method | BindingFlags.IncludeSuperType) as MethodInfo;
if (method == null) {
throw new GetValueException("Method " + methodName + " not found");
}
Value result = target.InvokeMethod(method, args.ToArray());
AddToCache(invocationExpression, result);
return result;
} }
List<Value> args = new List<Value>();
foreach(Expression expr in invocationExpression.Arguments) {
args.Add(((Value)expr.AcceptVisitor(this, null)).GetPermanentReference());
}
MethodInfo method = target.Type.GetMember(methodName, BindingFlags.Method | BindingFlags.IncludeSuperType) as MethodInfo;
if (method == null) {
throw new GetValueException("Method " + methodName + " not found");
}
return target.InvokeMethod(method, args.ToArray());
} }
public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data) public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
{ {
Value cached; Value target = (Value)memberReferenceExpression.TargetObject.AcceptVisitor(this, null);
if (TryGetCached(memberReferenceExpression, out cached)) return cached; Value member = target.GetMemberValue(memberReferenceExpression.MemberName);
using(LogEval(memberReferenceExpression)) { if (member != null) {
Value target = EvalAndPermRef(memberReferenceExpression.TargetObject);
Value member = target.GetMemberValue(memberReferenceExpression.MemberName);
if (member == null)
throw new GetValueException("Member \"" + memberReferenceExpression.MemberName + "\" not found");
AddToCache(memberReferenceExpression, member);
return member; return member;
} else {
throw new GetValueException("Member \"" + memberReferenceExpression.MemberName + "\" not found");
} }
} }
public override object VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, object data)
{
return parenthesizedExpression.Expression.AcceptVisitor(this, null);
}
public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data) public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
{ {
Value cached; return Eval.CreateValue(context.AppDomain, primitiveExpression.Value);
if (TryGetCached(primitiveExpression, out cached)) return cached;
using(LogEval(primitiveExpression)){
Value result = Eval.CreateValue(context.AppDomain, primitiveExpression.Value);
AddToCache(primitiveExpression, result);
return result;
}
} }
public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data) public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)
{ {
Value cached; return context.GetThisValue();
if (TryGetCached(thisReferenceExpression, out cached)) return cached;
using(LogEval(thisReferenceExpression)) {
Value result = context.GetThisValue();
AddToCache(thisReferenceExpression, result);
return result;
}
} }
public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data) public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data)
{ {
Value cached; Value value = ((Value)unaryOperatorExpression.Expression.AcceptVisitor(this, null));
if (TryGetCached(unaryOperatorExpression, out cached)) return cached; UnaryOperatorType op = unaryOperatorExpression.Op;
using(LogEval(unaryOperatorExpression)) {
Value value = EvalAndPermRef(unaryOperatorExpression.Expression); if (op == UnaryOperatorType.Dereference) {
UnaryOperatorType op = unaryOperatorExpression.Op; if (!value.Type.IsPointer) throw new GetValueException("Target object is not a pointer");
return value.Dereference();
if (op == UnaryOperatorType.Dereference) { }
if (!value.Type.IsPointer) throw new GetValueException("Target object is not a pointer");
return value.Dereference(); if (!value.Type.IsPrimitive) throw new GetValueException("Primitive value expected");
object val = value.PrimitiveValue;
object result = null;
// Bool operation
if (val is bool) {
bool a = Convert.ToBoolean(val);
switch (op) {
case UnaryOperatorType.Not: result = !a; break;
} }
}
if (!value.Type.IsPrimitive) throw new GetValueException("Primitive value expected");
// Float operation
object val = value.PrimitiveValue; if (val is double || val is float) {
double a = Convert.ToDouble(val);
object result = null; switch (op) {
case UnaryOperatorType.Minus: result = -a; break;
// Bool operation case UnaryOperatorType.Plus: result = +a; break;
if (val is bool) {
bool a = Convert.ToBoolean(val);
switch (op) {
case UnaryOperatorType.Not: result = !a; break;
}
} }
}
// Float operation
if (val is double || val is float) { // Integer operation
double a = Convert.ToDouble(val); if (val is byte || val is sbyte || val is int || val is uint || val is long || val is ulong) {
switch (op) { long a = Convert.ToInt64(val);
case UnaryOperatorType.Minus: result = -a; break; switch (op) {
case UnaryOperatorType.Plus: result = +a; break; case UnaryOperatorType.Decrement: result = a - 1; break;
} case UnaryOperatorType.Increment: result = a + 1; break;
case UnaryOperatorType.PostDecrement: result = a; break;
case UnaryOperatorType.PostIncrement: result = a; break;
case UnaryOperatorType.Minus: result = -a; break;
case UnaryOperatorType.Plus: result = a; break;
case UnaryOperatorType.BitNot: result = ~a; break;
} }
switch (op) {
// Integer operation case UnaryOperatorType.Decrement:
if (val is byte || val is sbyte || val is int || val is uint || val is long || val is ulong) { case UnaryOperatorType.PostDecrement:
long a = Convert.ToInt64(val); VisitAssignmentExpression(new AssignmentExpression(unaryOperatorExpression.Expression, AssignmentOperatorType.Subtract, new PrimitiveExpression(1)), null);
switch (op) { break;
case UnaryOperatorType.Decrement: result = a - 1; break; case UnaryOperatorType.Increment:
case UnaryOperatorType.Increment: result = a + 1; break; case UnaryOperatorType.PostIncrement:
case UnaryOperatorType.PostDecrement: result = a; break; VisitAssignmentExpression(new AssignmentExpression(unaryOperatorExpression.Expression, AssignmentOperatorType.Add, new PrimitiveExpression(1)), null);
case UnaryOperatorType.PostIncrement: result = a; break; break;
case UnaryOperatorType.Minus: result = -a; break;
case UnaryOperatorType.Plus: result = a; break;
case UnaryOperatorType.BitNot: result = ~a; break;
}
switch (op) {
case UnaryOperatorType.Decrement:
case UnaryOperatorType.PostDecrement:
VisitAssignmentExpression(new AssignmentExpression(unaryOperatorExpression.Expression, AssignmentOperatorType.Subtract, new PrimitiveExpression(1)), null);
break;
case UnaryOperatorType.Increment:
case UnaryOperatorType.PostIncrement:
VisitAssignmentExpression(new AssignmentExpression(unaryOperatorExpression.Expression, AssignmentOperatorType.Add, new PrimitiveExpression(1)), null);
break;
}
} }
if (result == null) throw new GetValueException("Unsuppored unary expression " + op);
Value res = Eval.CreateValue(context.AppDomain, result);
AddToCache(unaryOperatorExpression, res);
return res;
} }
if (result == null) throw new GetValueException("Unsuppored unary expression " + op);
return Eval.CreateValue(context.AppDomain, result);
} }
public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
{ {
Value cached; Value left = ((Value)binaryOperatorExpression.Left.AcceptVisitor(this, null)).GetPermanentReference();
if (TryGetCached(binaryOperatorExpression, out cached)) return cached; Value right = ((Value)binaryOperatorExpression.Right.AcceptVisitor(this, null)).GetPermanentReference();
using(LogEval(binaryOperatorExpression)) {
Value left = EvalAndPermRef(binaryOperatorExpression.Left); object result = VisitBinaryOperatorExpressionInternal(left, right, binaryOperatorExpression.Op);
Value right = EvalAndPermRef(binaryOperatorExpression.Right); // Conver long to int if possible
if (result is long && int.MinValue <= (long)result && (long)result <= int.MaxValue) result = (int)(long)result;
object result = VisitBinaryOperatorExpressionInternal(left, right, binaryOperatorExpression.Op); return Eval.CreateValue(context.AppDomain, result);
// Conver long to int if possible
if (result is long && int.MinValue <= (long)result && (long)result <= int.MaxValue) result = (int)(long)result;
Value res = Eval.CreateValue(context.AppDomain, result);
AddToCache(binaryOperatorExpression, res);
return res;
}
} }
public object VisitBinaryOperatorExpressionInternal(Value leftValue, Value rightValue, BinaryOperatorType op) public object VisitBinaryOperatorExpressionInternal(Value leftValue, Value rightValue, BinaryOperatorType op)

1
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/AstEval.cs

@ -38,7 +38,6 @@ namespace Debugger.Tests {
public partial class DebuggerTests public partial class DebuggerTests
{ {
[NUnit.Framework.Test] [NUnit.Framework.Test]
[NUnit.Framework.Ignore]
public void AstEval() public void AstEval()
{ {
StartTest("AstEval.cs"); StartTest("AstEval.cs");

1
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/Breakpoint.cs

@ -30,7 +30,6 @@ namespace Debugger.Tests {
public partial class DebuggerTests public partial class DebuggerTests
{ {
[NUnit.Framework.Test] [NUnit.Framework.Test]
[NUnit.Framework.Ignore]
public void Breakpoint() public void Breakpoint()
{ {
Breakpoint breakpoint1 = debugger.Breakpoints.Add(@"Breakpoint.cs", 18); Breakpoint breakpoint1 = debugger.Breakpoints.Add(@"Breakpoint.cs", 18);

2
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/MemoryReadWrite.cs

@ -26,7 +26,7 @@ namespace Debugger.Tests {
public partial class DebuggerTests public partial class DebuggerTests
{ {
[NUnit.Framework.Test] [NUnit.Framework.Test]
[NUnit.Framework.Ignore] [NUnit.Framework.Ignore("Different tokens in .NET 4")]
public void MemoryReadWrite() public void MemoryReadWrite()
{ {
StartTest("MemoryReadWrite.cs"); StartTest("MemoryReadWrite.cs");

2
src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/StackOverflow.cs

@ -29,7 +29,7 @@ namespace Debugger.Tests {
public partial class DebuggerTests public partial class DebuggerTests
{ {
[NUnit.Framework.Test] [NUnit.Framework.Test]
[NUnit.Framework.Ignore] [NUnit.Framework.Ignore("Different behaviour in .NET 4")]
public void StackOverflow() public void StackOverflow()
{ {
StartTest("StackOverflow.cs"); StartTest("StackOverflow.cs");

Loading…
Cancel
Save