diff options
author | Thays Grazia <thaystg@gmail.com> | 2019-01-15 20:23:01 +0300 |
---|---|---|
committer | Bernhard Urban <bernhard.urban@xamarin.com> | 2019-01-15 20:23:01 +0300 |
commit | 5266e6a8f107d9b91a6073e4fd1ef4eb1ac7ac6d (patch) | |
tree | 137a550e01471ba84bd2f5155f84736c15fe521e | |
parent | 0d988bc696e9716d0241328b552ce2dab8ad2ac9 (diff) |
[2018-08][debugger][backport] Fix crash when there is a generic struct with a field that is an enumerator (#12410)mono-5.18.0.240
* [Debugger] Fix crash when there is a generic struct with a field that is an enumerator. (#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 #10735
* [Debugger] Debugger crashes when there is a generic struct with a field that is an enumerator.
Example: files.get_Current().Key
A unit test that reproduces this crash was added too.
Fixes #10735
* Removing the extra space.
* Merging changes from dtest-app.cs
* Adding extra line.
-rw-r--r-- | mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs | 31 | ||||
-rw-r--r-- | mcs/class/Mono.Debugger.Soft/Test/dtest.cs | 19 | ||||
-rw-r--r-- | mono/mini/debugger-agent.c | 6 |
3 files changed, 56 insertions, 0 deletions
diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs index f0a9ce8dbe6..6da9419e93d 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs +++ b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs @@ -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; @@ -384,6 +409,7 @@ public class Tests : TestsBase, ITest2 new Tests ().invoke_abort (); new Tests ().evaluate_method (); Bug59649 (); + inspect_enumerator_in_generic_struct(); return 3; } @@ -577,6 +603,11 @@ public class Tests : TestsBase, ITest2 } [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; } diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs index 7de7a22a0ef..a57e5956798 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs +++ b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs @@ -4462,6 +4462,25 @@ public class DebuggerTests } [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")] public void Attach () { diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index c595475b79f..ab6ba342095 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -5510,6 +5510,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; } |