Skip to content

Commit

Permalink
[Debugger] Fix crash when there is a generic struct with a field that…
Browse files Browse the repository at this point in the history
… is an enumerator. (mono#12368)

* [Debugger]  Debugger crashes when inside a class, there is an internal struct, with a field that is an enumerator.
files.myBucket.GetEnumerator().get_Current().Key
Fixes mono#10735
  • Loading branch information
thaystg authored and monojenkins committed Jan 16, 2019
1 parent 4922314 commit 5d33d02
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
32 changes: 32 additions & 0 deletions mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
Expand Up @@ -85,6 +85,31 @@ public class Tests2 {
}
}

public struct TestEnumeratorInsideGenericStruct<TKey, TValue>
{
private KeyValuePair<TKey, TValue> _bucket;
private Position _currentPosition;
internal TestEnumeratorInsideGenericStruct(KeyValuePair<TKey, TValue> bucket)
{
_bucket = bucket;
_currentPosition = Position.BeforeFirst;
}

public KeyValuePair<TKey, TValue> Current
{
get
{
if (_currentPosition == Position.BeforeFirst)
return _bucket;
return _bucket;
}
}
private enum Position
{
BeforeFirst
}
}

public struct AStruct : ITest2 {
public int i;
public string s;
Expand Down Expand Up @@ -389,6 +414,7 @@ public static void wait_one ()
new Tests ().invoke_abort ();
new Tests ().evaluate_method ();
Bug59649 ();
inspect_enumerator_in_generic_struct();
return 3;
}

Expand Down Expand Up @@ -594,6 +620,12 @@ public static void ss7_3 ()
}



[MethodImplAttribute (MethodImplOptions.NoInlining)]
public static void inspect_enumerator_in_generic_struct() {
TestEnumeratorInsideGenericStruct<String, String> generic_struct = new TestEnumeratorInsideGenericStruct<String, String>(new KeyValuePair<string, string>("0", "f1"));
}

[MethodImplAttribute (MethodImplOptions.NoInlining)]
public static int ss_nested_with_two_args (int a1, int a2) {
return a1 + a2;
Expand Down
19 changes: 19 additions & 0 deletions mcs/class/Mono.Debugger.Soft/Test/dtest.cs
Expand Up @@ -4583,6 +4583,25 @@ Event step_out_await (string method, Event e)
assert_location(e, "ss_nested_arg");
}

[Test]
public void InspectEnumeratorInGenericStruct() {
//files.myBucket.GetEnumerator().get_Current().Key watching this generates an exception in Debugger
Event e = run_until("inspect_enumerator_in_generic_struct");
var req = create_step(e);
req.Enable();
e = step_once();
e = step_over();
StackFrame frame = e.Thread.GetFrames () [0];
var ginst = frame.Method.GetLocal ("generic_struct");
Value variable = frame.GetValue (ginst);
StructMirror thisObj = (StructMirror)variable;
TypeMirror thisType = thisObj.Type;
variable = thisObj.InvokeMethod(e.Thread, thisType.GetMethod("get_Current"), null);
thisObj = (StructMirror)variable;
thisType = thisObj.Type;
AssertValue ("f1", thisObj["value"]);
}

[Test]
// Uses a fixed port
[Category("NotWorking")]
Expand Down
7 changes: 6 additions & 1 deletion mono/mini/debugger-agent.c
Expand Up @@ -5574,6 +5574,12 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr,
g_free (name);
return ERR_INVALID_ARGUMENT;
}
} else if ((t->type == MONO_TYPE_GENERICINST) &&
mono_metadata_generic_class_is_valuetype (t->data.generic_class) &&
m_class_is_enumtype (t->data.generic_class->container_class)){
err = decode_vtype (t, domain, addr, buf, &buf, limit);
if (err != ERR_NONE)
return err;
} else {
NOT_IMPLEMENTED;
}
Expand Down Expand Up @@ -6018,7 +6024,6 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8

mono_runtime_try_invoke (invoke->method, NULL, invoke->args, &exc, error);
mono_error_assert_ok (error);

g_assert_not_reached ();
}

Expand Down

0 comments on commit 5d33d02

Please sign in to comment.