Skip to content

Commit f673203

Browse files
author
David Karlaš
committed
Bug 32315 - Inspecting a variable gives information from the incorrect symbol
1 parent 9fb59d3 commit f673203

File tree

5 files changed

+85
-7
lines changed

5 files changed

+85
-7
lines changed

Mono.Debugger.Soft/Mono.Debugger.Soft.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
<Compile Include="Mono.Debugger.Soft\AssemblyLoadEventRequest.cs" />
112112
<Compile Include="Locale.cs" />
113113
<Compile Include="Mono.Debugger.Soft\PointerValue.cs" />
114+
<Compile Include="Mono.Debugger.Soft\LocalScope.cs" />
114115
</ItemGroup>
115116
<ItemGroup>
116117
<None Include="Makefile.am" />

Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ struct LocalsInfo {
117117
public string[] names;
118118
public int[] live_range_start;
119119
public int[] live_range_end;
120+
public int[] scopes_start;
121+
public int[] scopes_end;
120122
}
121123

122124
struct PropInfo {
@@ -419,7 +421,7 @@ public abstract class Connection
419421
* with newer runtimes, and vice versa.
420422
*/
421423
internal const int MAJOR_VERSION = 2;
422-
internal const int MINOR_VERSION = 42;
424+
internal const int MINOR_VERSION = 43;
423425

424426
enum WPSuspendPolicy {
425427
NONE = 0,
@@ -1900,6 +1902,19 @@ internal LocalsInfo Method_GetLocalsInfo (long id) {
19001902
var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_LOCALS_INFO, new PacketWriter ().WriteId (id));
19011903

19021904
LocalsInfo info = new LocalsInfo ();
1905+
1906+
if (Version.AtLeast (2, 43)) {
1907+
int nscopes = res.ReadInt ();
1908+
info.scopes_start = new int [nscopes];
1909+
info.scopes_end = new int [nscopes];
1910+
int last_start = 0;
1911+
for (int i = 0; i < nscopes; ++i) {
1912+
info.scopes_start [i] = last_start + res.ReadInt ();
1913+
info.scopes_end [i] = info.scopes_start [i] + res.ReadInt ();
1914+
last_start = info.scopes_start [i];
1915+
}
1916+
}
1917+
19031918
int nlocals = res.ReadInt ();
19041919
info.types = new long [nlocals];
19051920
for (int i = 0; i < nlocals; ++i)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
3+
namespace Mono.Debugger.Soft
4+
{
5+
public class LocalScope : Mirror {
6+
7+
MethodMirror method;
8+
int live_range_start, live_range_end;
9+
10+
internal LocalScope (VirtualMachine vm, MethodMirror method, int live_range_start, int live_range_end) : base (vm, 0) {
11+
this.method = method;
12+
this.live_range_start = live_range_start;
13+
this.live_range_end = live_range_end;
14+
}
15+
16+
public MethodMirror Method {
17+
get {
18+
return method;
19+
}
20+
}
21+
22+
public int LiveRangeStart {
23+
get {
24+
return live_range_start;
25+
}
26+
}
27+
28+
public int LiveRangeEnd {
29+
get {
30+
return live_range_end;
31+
}
32+
}
33+
}
34+
}
35+

Mono.Debugger.Soft/Mono.Debugger.Soft/MethodMirror.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class MethodMirror : Mirror
1919
ParameterInfoMirror[] param_info;
2020
ParameterInfoMirror ret_param;
2121
LocalVariable[] locals;
22+
LocalScope[] scopes;
2223
IList<Location> locations;
2324
MethodBodyMirror body;
2425
MethodMirror gmd;
@@ -239,6 +240,13 @@ public ParameterInfoMirror ReturnParameter {
239240
}
240241
}
241242

243+
public LocalScope [] GetScopes () {
244+
if (!vm.Version.AtLeast (2, 43))
245+
throw new InvalidOperationException ("Scopes support was implemented in 2.43 version of protocol.");
246+
GetLocals ();
247+
return scopes;
248+
}
249+
242250
public LocalVariable[] GetLocals () {
243251
if (locals == null) {
244252
LocalsInfo li = new LocalsInfo ();
@@ -258,6 +266,12 @@ public LocalVariable[] GetLocals () {
258266

259267
for (int i = 0; i < li.names.Length; ++i)
260268
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);
269+
270+
if (vm.Version.AtLeast (2, 43)) {
271+
scopes = new LocalScope [li.scopes_start.Length];
272+
for (int i = 0; i < scopes.Length; ++i)
273+
scopes [i] = new LocalScope (vm, this, li.scopes_start [i], li.scopes_end [i]);
274+
}
261275
}
262276
return locals;
263277
}

Mono.Debugging.Soft/SoftDebuggerAdaptor.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -710,16 +710,29 @@ static bool IsGeneratedTemporaryLocal (LocalVariable local)
710710
return local.Name != null && (local.Name.StartsWith ("CS$", StringComparison.Ordinal) || local.Name.StartsWith ("<>t__", StringComparison.Ordinal));
711711
}
712712

713-
static string GetHoistedIteratorLocalName (FieldInfoMirror field)
713+
static string GetHoistedIteratorLocalName (FieldInfoMirror field, SoftEvaluationContext cx)
714714
{
715715
//mcs captured args, of form <$>name
716716
if (field.Name.StartsWith ("<$>", StringComparison.Ordinal)) {
717717
return field.Name.Substring (3);
718718
}
719-
720-
// csc, mcs locals of form <name>__0
721-
if (field.Name[0] == '<') {
722-
int i = field.Name.IndexOf ('>');
719+
720+
// csc, mcs locals of form <name>__#, where # represents index of scope
721+
if (field.Name [0] == '<') {
722+
var i = field.Name.IndexOf (">__", StringComparison.Ordinal);
723+
if (i != -1 && field.VirtualMachine.Version.AtLeast (2, 43)) {
724+
int scopeIndex;
725+
if (int.TryParse (field.Name.Substring (i + 3), out scopeIndex)) {
726+
scopeIndex--;//Scope index is 1 based(not zero)
727+
var scopes = cx.Frame.Method.GetScopes ();
728+
if (scopeIndex < scopes.Length) {
729+
var scope = scopes [scopeIndex];
730+
if (scope.LiveRangeStart > cx.Frame.Location.ILOffset || scope.LiveRangeEnd < cx.Frame.Location.ILOffset)
731+
return null;
732+
}
733+
}
734+
}
735+
i = field.Name.IndexOf ('>');
723736
if (i > 1) {
724737
return field.Name.Substring (1, i - 1);
725738
}
@@ -758,7 +771,7 @@ IEnumerable<ValueReference> GetHoistedLocalVariables (SoftEvaluationContext cx,
758771

759772
if (field.Name[0] == '<') {
760773
if (isIterator) {
761-
var name = GetHoistedIteratorLocalName (field);
774+
var name = GetHoistedIteratorLocalName (field, cx);
762775

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

0 commit comments

Comments
 (0)