Browse Source

fix SD-1912 - Debugger displays wrong values for captured parameters

pull/59/merge
Siegfried Pammer 12 years ago
parent
commit
973ca64615
  1. 18
      src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs
  2. 2
      src/AddIns/Debugger/Debugger.Core/LocalVariable.cs
  3. 14
      src/AddIns/Debugger/Debugger.Core/StackFrame.cs

18
src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs

@ -255,13 +255,25 @@ namespace Debugger.AddIn.TreeModel
public static IEnumerable<TreeNode> GetLocalVariables() public static IEnumerable<TreeNode> GetLocalVariables()
{ {
var stackFrame = GetCurrentStackFrame(); var stackFrame = GetCurrentStackFrame();
var localVars = stackFrame.GetLocalVariables(stackFrame.IP).ToList();
foreach(var par in stackFrame.MethodInfo.Parameters.Select((p, i) => new { Param = p, Index = i})) { foreach(var par in stackFrame.MethodInfo.Parameters.Select((p, i) => new { Param = p, Index = i})) {
var parCopy = par; var parCopy = par;
yield return new ValueNode(ClassBrowserIconService.Parameter, par.Param.Name, () => GetCurrentStackFrame().GetArgumentValue(par.Index)); // do not display parameters that have been copied to captured variables twice. (see SD-1912)
// display only the value of the captured instance (the value of the parameter still has the original value)
var localVar = localVars.FirstOrDefault(v => string.Equals(v.Name, parCopy.Param.Name, StringComparison.Ordinal));
if (localVar == null)
yield return new ValueNode(ClassBrowserIconService.Parameter, par.Param.Name,
() => stackFrame.GetArgumentValue(par.Index));
else {
yield return new ValueNode(ClassBrowserIconService.Parameter, localVar.Name,
() => localVar.GetValue(stackFrame));
localVars.Remove(localVar);
}
} }
foreach(LocalVariable locVar in stackFrame.GetLocalVariables(stackFrame.IP)) { foreach(LocalVariable locVar in localVars) {
var locVarCopy = locVar; var locVarCopy = locVar;
yield return new ValueNode(ClassBrowserIconService.LocalVariable, locVar.Name, () => locVarCopy.GetValue(GetCurrentStackFrame())); yield return new ValueNode(ClassBrowserIconService.LocalVariable, locVar.Name,
() => locVarCopy.GetValue(stackFrame));
} }
} }

2
src/AddIns/Debugger/Debugger.Core/LocalVariable.cs

@ -89,7 +89,7 @@ namespace Debugger.MetaData
context => context.GetThisValue(false), context => context.GetThisValue(false),
method.DeclaringType method.DeclaringType
); );
// Get dispaly classes from fields // Get display classes from fields
foreach(IField fieldInfo in method.DeclaringType.GetFields(f => f.Name.StartsWith("CS$"), GetMemberOptions.None)) { foreach(IField fieldInfo in method.DeclaringType.GetFields(f => f.Name.StartsWith("CS$"), GetMemberOptions.None)) {
IField fieldInfoCopy = fieldInfo; IField fieldInfoCopy = fieldInfo;
AddCapturedLocalVariables( AddCapturedLocalVariables(

14
src/AddIns/Debugger/Debugger.Core/StackFrame.cs

@ -270,6 +270,9 @@ namespace Debugger
{ {
for (int i = 0; i < this.MethodInfo.Parameters.Count; i++) { for (int i = 0; i < this.MethodInfo.Parameters.Count; i++) {
if (this.MethodInfo.Parameters[i].Name == name) { if (this.MethodInfo.Parameters[i].Name == name) {
LocalVariable capturedVar;
if (HasCapturedVariable(name, out capturedVar))
return capturedVar.GetValue(this);
return GetArgumentValue(i); return GetArgumentValue(i);
} }
} }
@ -280,6 +283,10 @@ namespace Debugger
/// <param name="index"> Zero-based index </param> /// <param name="index"> Zero-based index </param>
public Value GetArgumentValue(int index) public Value GetArgumentValue(int index)
{ {
var param = this.MethodInfo.Parameters[index];
LocalVariable capturedVariable;
if (HasCapturedVariable(param.Name, out capturedVariable))
return capturedVariable.GetValue(this);
return new Value(this.AppDomain, GetArgumentCorValue(index)); return new Value(this.AppDomain, GetArgumentCorValue(index));
} }
@ -312,6 +319,13 @@ namespace Debugger
return corValue; return corValue;
} }
/// <summary> Gets whether a captured variable with the <paramref name="name"/> exists. </summary>
public bool HasCapturedVariable(string name, out LocalVariable variable)
{
variable = GetLocalVariables(this.IP).FirstOrDefault(v => v.IsCaptured && v.Name == name);
return variable != null;
}
/// <summary> Get all local variables </summary> /// <summary> Get all local variables </summary>
public IEnumerable<LocalVariable> GetLocalVariables() public IEnumerable<LocalVariable> GetLocalVariables()
{ {

Loading…
Cancel
Save