Skip to content

Commit

Permalink
Bug 32315 - Inspecting a variable gives information from the incorrec…
Browse files Browse the repository at this point in the history
…t symbol
  • Loading branch information
David Karlaš committed Sep 12, 2016
1 parent 9fb59d3 commit f673203
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 7 deletions.
1 change: 1 addition & 0 deletions Mono.Debugger.Soft/Mono.Debugger.Soft.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
<Compile Include="Mono.Debugger.Soft\AssemblyLoadEventRequest.cs" />
<Compile Include="Locale.cs" />
<Compile Include="Mono.Debugger.Soft\PointerValue.cs" />
<Compile Include="Mono.Debugger.Soft\LocalScope.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Makefile.am" />
Expand Down
17 changes: 16 additions & 1 deletion Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ struct LocalsInfo {
public string[] names;
public int[] live_range_start;
public int[] live_range_end;
public int[] scopes_start;
public int[] scopes_end;
}

struct PropInfo {
Expand Down Expand Up @@ -419,7 +421,7 @@ public abstract class Connection
* with newer runtimes, and vice versa.
*/
internal const int MAJOR_VERSION = 2;
internal const int MINOR_VERSION = 42;
internal const int MINOR_VERSION = 43;

enum WPSuspendPolicy {
NONE = 0,
Expand Down Expand Up @@ -1900,6 +1902,19 @@ internal void SetSocketTimeouts (int send_timeout, int receive_timeout, int keep
var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_LOCALS_INFO, new PacketWriter ().WriteId (id));

LocalsInfo info = new LocalsInfo ();

if (Version.AtLeast (2, 43)) {
int nscopes = res.ReadInt ();
info.scopes_start = new int [nscopes];
info.scopes_end = new int [nscopes];
int last_start = 0;
for (int i = 0; i < nscopes; ++i) {
info.scopes_start [i] = last_start + res.ReadInt ();
info.scopes_end [i] = info.scopes_start [i] + res.ReadInt ();
last_start = info.scopes_start [i];
}
}

int nlocals = res.ReadInt ();
info.types = new long [nlocals];
for (int i = 0; i < nlocals; ++i)
Expand Down
35 changes: 35 additions & 0 deletions Mono.Debugger.Soft/Mono.Debugger.Soft/LocalScope.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;

namespace Mono.Debugger.Soft
{
public class LocalScope : Mirror {

MethodMirror method;
int live_range_start, live_range_end;

internal LocalScope (VirtualMachine vm, MethodMirror method, int live_range_start, int live_range_end) : base (vm, 0) {
this.method = method;
this.live_range_start = live_range_start;
this.live_range_end = live_range_end;
}

public MethodMirror Method {
get {
return method;
}
}

public int LiveRangeStart {
get {
return live_range_start;
}
}

public int LiveRangeEnd {
get {
return live_range_end;
}
}
}
}

14 changes: 14 additions & 0 deletions Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class MethodMirror : Mirror
ParameterInfoMirror[] param_info;
ParameterInfoMirror ret_param;
LocalVariable[] locals;
LocalScope[] scopes;
IList<Location> locations;
MethodBodyMirror body;
MethodMirror gmd;
Expand Down Expand Up @@ -239,6 +240,13 @@ public class MethodMirror : Mirror
}
}

public LocalScope [] GetScopes () {
if (!vm.Version.AtLeast (2, 43))
throw new InvalidOperationException ("Scopes support was implemented in 2.43 version of protocol.");
GetLocals ();
return scopes;
}

public LocalVariable[] GetLocals () {
if (locals == null) {
LocalsInfo li = new LocalsInfo ();
Expand All @@ -258,6 +266,12 @@ public class MethodMirror : Mirror

for (int i = 0; i < li.names.Length; ++i)
locals [i + pi.Length] = new LocalVariable (vm, this, i, li.types [i], li.names [i], li.live_range_start [i], li.live_range_end [i], false);

if (vm.Version.AtLeast (2, 43)) {
scopes = new LocalScope [li.scopes_start.Length];
for (int i = 0; i < scopes.Length; ++i)
scopes [i] = new LocalScope (vm, this, li.scopes_start [i], li.scopes_end [i]);
}
}
return locals;
}
Expand Down
25 changes: 19 additions & 6 deletions Mono.Debugging.Soft/SoftDebuggerAdaptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -710,16 +710,29 @@ static bool IsGeneratedTemporaryLocal (LocalVariable local)
return local.Name != null && (local.Name.StartsWith ("CS$", StringComparison.Ordinal) || local.Name.StartsWith ("<>t__", StringComparison.Ordinal));
}

static string GetHoistedIteratorLocalName (FieldInfoMirror field)
static string GetHoistedIteratorLocalName (FieldInfoMirror field, SoftEvaluationContext cx)
{
//mcs captured args, of form <$>name
if (field.Name.StartsWith ("<$>", StringComparison.Ordinal)) {
return field.Name.Substring (3);
}

// csc, mcs locals of form <name>__0
if (field.Name[0] == '<') {
int i = field.Name.IndexOf ('>');

// csc, mcs locals of form <name>__#, where # represents index of scope
if (field.Name [0] == '<') {
var i = field.Name.IndexOf (">__", StringComparison.Ordinal);
if (i != -1 && field.VirtualMachine.Version.AtLeast (2, 43)) {
int scopeIndex;
if (int.TryParse (field.Name.Substring (i + 3), out scopeIndex)) {
scopeIndex--;//Scope index is 1 based(not zero)
var scopes = cx.Frame.Method.GetScopes ();
if (scopeIndex < scopes.Length) {
var scope = scopes [scopeIndex];
if (scope.LiveRangeStart > cx.Frame.Location.ILOffset || scope.LiveRangeEnd < cx.Frame.Location.ILOffset)
return null;
}
}
}
i = field.Name.IndexOf ('>');
if (i > 1) {
return field.Name.Substring (1, i - 1);
}
Expand Down Expand Up @@ -758,7 +771,7 @@ IEnumerable<ValueReference> GetHoistedLocalVariables (SoftEvaluationContext cx,

if (field.Name[0] == '<') {
if (isIterator) {
var name = GetHoistedIteratorLocalName (field);
var name = GetHoistedIteratorLocalName (field, cx);

if (!string.IsNullOrEmpty (name))
list.Add (new FieldValueReference (cx, field, val, type, name, ObjectValueFlags.Variable));
Expand Down

0 comments on commit f673203

Please sign in to comment.