Merge pull request #3040 from xmcclure/debugger-step-recursive
[mono.git] / mcs / class / Mono.Debugger.Soft / Test / dtest.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Threading;
4 using System.Net;
5 using System.Reflection;
6 using System.Text;
7 using Mono.Cecil.Cil;
8 using Mono.Debugger.Soft;
9 using Diag = System.Diagnostics;
10 using System.Linq;
11 using System.IO;
12 using System.Security.Cryptography;
13
14 using NUnit.Framework;
15
16 #pragma warning disable 0219
17
18 namespace MonoTests
19 {
20
21 [TestFixture]
22 public class DebuggerTests
23 {
24         VirtualMachine vm;
25         MethodMirror entry_point;
26         StepEventRequest step_req;
27         bool forceExit;
28
29         void AssertThrows<ExType> (Action del) where ExType : Exception {
30                 bool thrown = false;
31
32                 try {
33                         del ();
34                 } catch (ExType) {
35                         thrown = true;
36                 }
37                 Assert.IsTrue (thrown);
38         }
39
40         // No other way to pass arguments to the tests ?
41         public static bool listening = Environment.GetEnvironmentVariable ("DBG_SUSPEND") != null;
42         public static string runtime = Environment.GetEnvironmentVariable ("DBG_RUNTIME");
43         public static string agent_args = Environment.GetEnvironmentVariable ("DBG_AGENT_ARGS");
44
45         // Not currently used, but can be useful when debugging individual tests.
46         void StackTraceDump (Event e)
47         {
48                 int i = 0;
49                 foreach (var frame in e.Thread.GetFrames ())
50                 {
51                         i++;
52                         Console.WriteLine ("Frame " + i + ", " + frame.Method.Name);
53                 }
54         }
55
56         Event GetNextEvent () {
57                 var es = vm.GetNextEventSet ();
58                 Assert.AreEqual (1, es.Events.Length);
59                 return es [0];
60         }
61
62         void Start (params string[] args) {
63                 Start (false, args);
64         }
65
66         void Start (bool forceExit, params string[] args) {
67                 this.forceExit = forceExit;
68
69                 if (!listening) {
70                         var pi = new Diag.ProcessStartInfo ();
71
72                         if (runtime != null)
73                                 pi.FileName = runtime;
74                         else
75                                 pi.FileName = "mono";
76                         pi.Arguments = String.Join (" ", args);
77                         vm = VirtualMachineManager.Launch (pi, new LaunchOptions { AgentArgs = agent_args });
78                 } else {
79                         var ep = new IPEndPoint (IPAddress.Any, 10000);
80                         Console.WriteLine ("Listening on " + ep + "...");
81                         vm = VirtualMachineManager.Listen (ep);
82                 }
83
84                 var load_req = vm.CreateAssemblyLoadRequest ();
85                 load_req.Enable ();
86
87                 Event vmstart = GetNextEvent ();
88                 Assert.AreEqual (EventType.VMStart, vmstart.EventType);
89
90                 vm.Resume ();
91
92                 entry_point = null;
93                 step_req = null;
94
95                 Event e;
96
97                 /* Find out the entry point */
98                 while (true) {
99                         e = GetNextEvent ();
100
101                         if (e is AssemblyLoadEvent) {
102                                 AssemblyLoadEvent ae = (AssemblyLoadEvent)e;
103                                 entry_point = ae.Assembly.EntryPoint;
104                                 if (entry_point != null)
105                                         break;
106                         }
107
108                         vm.Resume ();
109                 }
110
111                 load_req.Disable ();
112         }
113
114         BreakpointEvent run_until (string name) {
115                 // String
116                 MethodMirror m = entry_point.DeclaringType.GetMethod (name);
117                 Assert.IsNotNull (m);
118                 //Console.WriteLine ("X: " + name + " " + m.ILOffsets.Count + " " + m.Locations.Count);
119                 var req = vm.SetBreakpoint (m, m.ILOffsets [0]);
120
121                 Event e = null;
122
123                 while (true) {
124                         vm.Resume ();
125                         e = GetNextEvent ();
126                         if (e is BreakpointEvent)
127                                 break;
128                 }
129
130                 req.Disable ();
131
132                 Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
133                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
134
135                 return (e as BreakpointEvent);
136         }
137
138         class ReusableBreakpoint {
139                 DebuggerTests owner;
140                 public string method_name;
141                 public BreakpointEventRequest req;
142                 public BreakpointEvent lastEvent = null;
143                 public ReusableBreakpoint (DebuggerTests owner, string method_name)
144                 {
145                         this.owner = owner;
146                         this.method_name = method_name;
147                         MethodMirror m = owner.entry_point.DeclaringType.GetMethod (method_name);
148                         Assert.IsNotNull (m);
149                         req = owner.vm.SetBreakpoint (m, m.ILOffsets [0]);
150                 }
151
152                 public void Continue ()
153                 {
154                         bool survived = false;
155
156                         try {
157                                 Event e = null;
158
159                                 while (true) {
160                                         owner.vm.Resume ();
161                                         e = owner.GetNextEvent ();
162                                         if (e is BreakpointEvent)
163                                                 break;
164                                 }
165
166                                 Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
167                                 Assert.AreEqual (method_name, (e as BreakpointEvent).Method.Name);
168
169                                 lastEvent = e as BreakpointEvent;
170
171                                 survived = true;
172                         } finally {
173                                 if (!survived) { // Ensure cleanup if we triggered an assert
174                                         Disable ();
175                                 }
176                         }
177                 }
178
179                 public void Disable ()
180                 {
181                         req.Disable ();
182                 }
183         }
184
185         /* One of the tests executes a complex tree of recursive functions.
186            The only good way to specify how its behavior should appear from this side
187            is to just run the function tree once over here and record what it does. */
188         public struct RecursiveChaoticPoint
189         {
190                 public bool breakpoint;
191                 public string name;
192                 public int depth;
193
194                 public RecursiveChaoticPoint (bool breakpoint, string name, int depth)
195                 {
196                         this.breakpoint = breakpoint;
197                         this.name = name;
198                         this.depth = depth;
199                 }
200         }
201
202         // The breakpoint is placed here in dtest-app.cs
203         public static void ss_recursive_chaotic_trap (int n, List<RecursiveChaoticPoint> trace, ref bool didLast, ref bool didAny)
204         {
205                 // Depth is calculated as:
206                 // Main + single_stepping + ss_recursive_chaotic + (n is 5 at outermost frame and 0 at innermost frame) + ss_recursive_chaotic_trap
207                 trace.Add (new RecursiveChaoticPoint (true, "ss_recursive_chaotic_trap", 5 - n + 5));
208                 didLast = true;
209         }
210
211         public static void ss_recursive_chaotic_at (string at, int n, List<RecursiveChaoticPoint> trace, ref bool didLast, ref bool didAny)
212         {
213                 // This will be called after every return from a function. The other function will return whether "step out" is currently active, and it will be passed in here as didLast.
214                 if (didLast) {
215                         // Depth is calculated as:
216                         // Main + single_stepping + ss_recursive_chaotic + (n is 5 at outermost frame and 0 at innermost frame)
217                         trace.Add (new RecursiveChaoticPoint (false, "ss_recursive_chaotic_" + at, 5 - n + 4));
218                         didAny = true;
219                         didLast = false;
220                 }
221         }
222
223         public static bool ss_recursive_chaotic_fizz (int n, List<RecursiveChaoticPoint> trace)
224         {
225                 bool didLast = false, didAny = false;
226                 if (n > 0) {
227                         int next = n - 1;
228                         didLast = ss_recursive_chaotic_buzz (next, trace);
229                         ss_recursive_chaotic_at ("fizz", n, trace, ref didLast, ref didAny);
230                         didLast = ss_recursive_chaotic_fizzbuzz (next, trace);
231                         ss_recursive_chaotic_at ("fizz", n, trace, ref didLast, ref didAny);
232                 } else {
233                         ss_recursive_chaotic_trap (n, trace, ref didLast, ref didAny);
234                         ss_recursive_chaotic_at ("fizz", n, trace, ref didLast, ref didAny);
235                 }
236                 return didAny;
237         }
238
239         public static bool ss_recursive_chaotic_buzz (int n, List<RecursiveChaoticPoint> trace)
240         {
241                 bool didLast = false, didAny = false;
242                 if (n > 0) {
243                         int next = n - 1;
244                         didLast = ss_recursive_chaotic_fizz (next, trace);
245                         ss_recursive_chaotic_at ("buzz", n, trace, ref didLast, ref didAny);
246                         didLast = ss_recursive_chaotic_fizzbuzz (next, trace);
247                         ss_recursive_chaotic_at ("buzz", n, trace, ref didLast, ref didAny);
248                 }
249                 return didAny;
250         }
251
252         public static bool ss_recursive_chaotic_fizzbuzz (int n, List<RecursiveChaoticPoint> trace)
253         {
254                 bool didLast = false, didAny = false;
255                 if (n > 0) {
256                         int next = n - 1;
257                         didLast = ss_recursive_chaotic_fizz (next, trace);
258                         ss_recursive_chaotic_at ("fizzbuzz", n, trace, ref didLast, ref didAny);
259                         didLast = ss_recursive_chaotic_buzz (next, trace);
260                         ss_recursive_chaotic_at ("fizzbuzz", n, trace, ref didLast, ref didAny);
261                         didLast = ss_recursive_chaotic_fizzbuzz (next, trace);
262                         ss_recursive_chaotic_at ("fizzbuzz", n, trace, ref didLast, ref didAny);
263                 }
264                 return didAny;
265         }
266
267         public static void trace_ss_recursive_chaotic (List<RecursiveChaoticPoint> trace)
268         {
269                 ss_recursive_chaotic_fizz (5, trace);
270         }
271
272         Event single_step (ThreadMirror t) {
273                 var req = vm.CreateStepRequest (t);
274                 req.Enable ();
275
276                 vm.Resume ();
277                 Event e = GetNextEvent ();
278                 Assert.IsTrue (e is StepEvent);
279
280                 req.Disable ();
281
282                 return e;
283         }
284
285         Event step_until (ThreadMirror t, string method_name) {
286                 Event e;
287                 while (true) {
288                         e = single_step (t);
289                         if ((e as StepEvent).Method.Name == method_name)
290                                 break;
291                 }
292                 return e;
293         }
294
295         void check_arg_val (StackFrame frame, int pos, Type type, object eval) {
296                 object val = frame.GetArgument (pos);
297                 Assert.IsTrue (val is PrimitiveValue);
298                 object v = (val as PrimitiveValue).Value;
299                 Assert.AreEqual (type, v.GetType ());
300                 if (eval is float)
301                         Assert.IsTrue (Math.Abs ((float)eval - (float)v) < 0.0001);
302                 else if (eval is double)
303                         Assert.IsTrue (Math.Abs ((double)eval - (double)v) < 0.0001);
304                 else
305                         Assert.AreEqual (eval, v);
306         }
307
308         void AssertValue (object expected, object val) {
309                 if (expected is string) {
310                         Assert.IsTrue (val is StringMirror);
311                         Assert.AreEqual (expected, (val as StringMirror).Value);
312                 } else if (val is StructMirror && (val as StructMirror).Type.Name == "IntPtr") {
313                         AssertValue (expected, (val as StructMirror).Fields [0]);
314                 } else {
315                         Assert.IsTrue (val is PrimitiveValue);
316                         Assert.AreEqual (expected, (val as PrimitiveValue).Value);
317                 }
318         }
319
320         [SetUp]
321         public void SetUp () {
322                 ThreadMirror.NativeTransitions = false;
323                 Start (new string [] { "dtest-app.exe" });
324         }
325
326         [TearDown]
327         public void TearDown () {
328                 if (vm == null)
329                         return;
330
331                 if (step_req != null)
332                         step_req.Disable ();
333
334                 vm.Resume ();
335                 if (forceExit)
336                         vm.Exit (0);
337
338                 while (true) {
339                         Event e = GetNextEvent ();
340
341                         if (e is VMDeathEvent)
342                                 break;
343
344                         vm.Resume ();
345                 }
346                 vm = null;
347         }
348
349         [Test]
350         public void SimpleBreakpoint () {
351                 Event e;
352
353                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp1");
354                 Assert.IsNotNull (m);
355
356                 vm.SetBreakpoint (m, 0);
357
358                 vm.Resume ();
359
360                 e = GetNextEvent ();
361                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
362                 Assert.IsTrue (e is BreakpointEvent);
363                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
364
365                 // Argument checking
366                 AssertThrows<ArgumentException> (delegate {
367                                 // Invalid IL offset
368                                 vm.SetBreakpoint (m, 2);
369                         });
370         }
371
372         [Test]
373         public void BreakpointsSameLocation () {
374                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp2");
375                 Assert.IsNotNull (m);
376
377                 vm.SetBreakpoint (m, 0);
378                 vm.SetBreakpoint (m, 0);
379
380                 vm.Resume ();
381
382                 var es = vm.GetNextEventSet ();
383                 Assert.AreEqual (2, es.Events.Length);
384                 Assert.IsTrue (es [0] is BreakpointEvent);
385                 Assert.AreEqual (m, (es [0] as BreakpointEvent).Method);
386
387                 Assert.IsTrue (es [1] is BreakpointEvent);
388                 Assert.AreEqual (m.Name, (es [1] as BreakpointEvent).Method.Name);
389         }
390
391         [Test]
392         public void BreakpointAlreadyJITted () {
393                 Event e = run_until ("bp1");
394
395                 /* Place a breakpoint on bp3 */
396                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp3");
397                 Assert.IsNotNull (m);
398                 vm.SetBreakpoint (m, 0);
399
400                 /* Same with generic instances */
401                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp7");
402                 Assert.IsNotNull (m2);
403                 vm.SetBreakpoint (m2, 0);
404
405                 vm.Resume ();
406
407                 e = GetNextEvent ();
408                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
409                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
410
411                 vm.Resume ();
412
413                 /* Non-shared instance */
414                 e = GetNextEvent ();
415                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
416                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
417
418                 vm.Resume ();
419
420                 /* Shared instance */
421                 e = GetNextEvent ();
422                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
423                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
424         }
425
426         [Test]
427         public void ClearBreakpoint () {
428                 Event e;
429
430                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
431                 Assert.IsNotNull (m);
432                 EventRequest req1 = vm.SetBreakpoint (m, 0);
433                 EventRequest req2 = vm.SetBreakpoint (m, 0);
434
435                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
436                 Assert.IsNotNull (m2);
437                 vm.SetBreakpoint (m2, 0);
438
439                 /* Run until bp4 */
440                 vm.Resume ();
441
442                 var es = vm.GetNextEventSet ();
443                 Assert.AreEqual (2, es.Events.Length);
444                 Assert.AreEqual (EventType.Breakpoint, es [0].EventType);
445                 Assert.AreEqual (m.Name, (es [0] as BreakpointEvent).Method.Name);
446                 Assert.AreEqual (EventType.Breakpoint, es [1].EventType);
447                 Assert.AreEqual (m.Name, (es [1] as BreakpointEvent).Method.Name);
448
449                 /* Clear one of them */
450                 req1.Disable ();
451
452                 vm.Resume ();
453
454                 e = GetNextEvent ();
455                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
456                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
457
458                 /* Clear the other */
459                 req2.Disable ();
460
461                 vm.Resume ();
462
463                 e = GetNextEvent ();
464                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
465                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
466         }
467
468         [Test]
469         public void ClearAllBreakpoints () {
470                 Event e;
471
472                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
473                 Assert.IsNotNull (m);
474                 vm.SetBreakpoint (m, 0);
475
476                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
477                 Assert.IsNotNull (m2);
478                 vm.SetBreakpoint (m2, 0);
479
480                 vm.ClearAllBreakpoints ();
481
482                 vm.Resume ();
483
484                 e = GetNextEvent ();
485                 Assert.IsTrue (!(e is BreakpointEvent));
486                 if (e is VMDeathEvent)
487                         vm = null;
488         }
489
490         [Test]
491         public void BreakpointOnGShared () {
492                 Event e;
493
494                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp6");
495                 Assert.IsNotNull (m);
496
497                 vm.SetBreakpoint (m, 0);
498
499                 vm.Resume ();
500
501                 e = GetNextEvent ();
502                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
503                 Assert.IsTrue (e is BreakpointEvent);
504                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
505
506                 // Breakpoint on an open generic method of a closed generic class (#3422)
507                 var frame = e.Thread.GetFrames ()[0];
508                 var ginst = frame.GetValue (frame.Method.GetLocal ("gc"));
509                 var m2 = (ginst as ObjectMirror).Type.GetMethod ("bp");
510                 vm.SetBreakpoint (m2, 0);
511
512                 vm.Resume ();
513
514                 e = GetNextEvent ();
515                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
516                 Assert.IsTrue (e is BreakpointEvent);
517                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
518         }
519
520         // Assert we have stepped to a location
521         void assert_location (Event e, string method) {
522                 Assert.IsTrue (e is StepEvent);
523                 Assert.AreEqual (method, (e as StepEvent).Method.Name);
524         }
525
526         // Assert we have breakpointed at a location
527         void assert_location_at_breakpoint (Event e, string method) {
528                 Assert.IsTrue (e is BreakpointEvent);
529                 Assert.AreEqual (method, (e as BreakpointEvent).Method.Name);
530         }
531
532         // Assert we have stepped to or breakpointed at a location
533         void assert_location_allow_breakpoint (Event e, string method) {
534                 if (e is StepEvent)
535                         Assert.AreEqual (method, (e as StepEvent).Method.Name);
536                 else if (e is BreakpointEvent)
537                         Assert.AreEqual (method, (e as BreakpointEvent).Method.Name);
538                 else
539                         Assert.Fail ("Neither step nor breakpoint event");
540         }
541
542         StepEventRequest create_step (Event e) {
543                 var req = vm.CreateStepRequest (e.Thread);
544                 step_req = req;
545                 return req;
546         }
547
548         [Test]
549         public void ClassLocalReflection () {
550                 MethodMirror m = entry_point.DeclaringType.Assembly.GetType ("LocalReflectClass").GetMethod ("RunMe");
551
552                 Assert.IsNotNull (m);
553                 //Console.WriteLine ("X: " + name + " " + m.ILOffsets.Count + " " + m.Locations.Count);
554                 var offset = -1;
555                 int method_base_linum = m.Locations [0].LineNumber;
556                 foreach (var location in m.Locations)
557                         if (location.LineNumber == method_base_linum + 2) {
558                                 offset = location.ILOffset;
559                                 break;
560                         }
561
562                 var req = vm.SetBreakpoint (m, offset);
563
564                 Event e = null;
565
566                 while (true) {
567                         vm.Resume ();
568                         e = GetNextEvent ();
569                         if (e is BreakpointEvent)
570                                 break;
571                 }
572
573                 req.Disable ();
574
575                 Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
576                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
577
578                 e = single_step (e.Thread);
579
580                 var frame = e.Thread.GetFrames ()[0];
581                 Value variable = frame.GetValue (frame.Method.GetLocal ("reflectMe"));
582
583                 ObjectMirror thisObj = (ObjectMirror)variable;
584                 TypeMirror thisType = thisObj.Type;
585                 FieldInfoMirror thisFi = null;
586                 foreach (var fi in thisType.GetFields ())
587                         if (fi.Name == "someField")
588                                 thisFi = fi;
589
590                 var gotVal = thisObj.GetValue (thisFi);
591                 // If we got this far, we're good.
592         }
593
594         [Test]
595         public void SingleStepping () {
596                 Event e = run_until ("single_stepping");
597
598                 var req = create_step (e);
599                 req.Enable ();
600
601                 // Step over 'bool b = true'
602                 e = step_once ();
603                 assert_location (e, "single_stepping");
604
605                 // Skip nop
606                 step_once ();
607
608                 // Step into ss1
609                 e = step_once ();
610                 assert_location (e, "ss1");
611
612                 // Skip }
613                 e = step_once ();
614
615                 // Step out of ss1
616                 e = step_once ();
617                 assert_location (e, "single_stepping");
618
619                 // Step over ss2
620                 e = step_over ();
621                 assert_location (e, "single_stepping");
622
623                 // Step into ss3
624                 e = step_into ();
625                 assert_location (e, "ss3");
626
627                 // Step back into single_stepping
628                 e = step_out ();
629                 assert_location (e, "single_stepping");
630
631                 // Step into next line
632                 e = step_into ();
633                 assert_location (e, "single_stepping");
634
635                 // Step into ss3_2 ()
636                 e = step_into ();
637                 assert_location (e, "ss3_2");
638
639                 // Step over ss3_2_2 ()
640                 e = step_over ();
641                 assert_location (e, "ss3_2");
642
643                 // Recreate the request
644                 req.Disable ();
645                 req.Enable ();
646
647                 // Skip }
648                 e = step_once ();
649
650                 // Step back into single_stepping () with the new request
651                 e = step_once ();
652                 assert_location (e, "single_stepping");
653
654                 // Step into ss4 ()
655                 e = step_into ();
656                 assert_location (e, "ss4");
657
658                 // Skip nop
659                 e = step_once ();
660
661                 // Change to StepSize.Line
662                 req.Disable ();
663                 req.Depth = StepDepth.Over;
664                 req.Size = StepSize.Line;
665                 req.Enable ();
666
667                 // Step over ss1 (); ss1 ();
668                 e = step_once ();
669
670                 // Step into ss2 ()
671                 req.Disable ();
672                 req.Depth = StepDepth.Into;
673                 req.Enable ();
674
675                 e = step_once ();
676                 assert_location (e, "ss2");
677
678                 req.Disable ();
679
680                 // Run until ss5
681                 e = run_until ("ss5");
682
683                 // Add an assembly filter
684                 req.AssemblyFilter = new AssemblyMirror [] { (e as BreakpointEvent).Method.DeclaringType.Assembly };
685                 req.Enable ();
686
687                 // Skip nop
688                 e = step_once ();
689
690                 // Step into is_even, skipping the linq stuff
691                 e = step_once ();
692                 assert_location (e, "is_even");
693
694                 // FIXME: Check that single stepping works with lock (obj)
695                 req.Disable ();
696
697                 // Run until ss6
698                 e = run_until ("ss6");
699
700                 req = create_step (e);
701                 req.Depth = StepDepth.Over;
702                 req.Enable ();
703
704                 // Check that single stepping works in out-of-line bblocks
705                 e = step_once ();
706                 e = step_once ();
707                 assert_location (e, "ss6");
708                 req.Disable ();
709
710                 // Check that a step over stops at an EH clause
711                 e = run_until ("ss7_2");
712                 req = create_step (e);
713                 req.Depth = StepDepth.Out;
714                 req.Enable ();
715                 e = step_once ();
716                 assert_location (e, "ss7");
717                 req.Disable ();
718                 req = create_step (e);
719                 req.Depth = StepDepth.Over;
720                 req.Enable ();
721                 e = step_once ();
722                 assert_location (e, "ss7");
723                 req.Disable ();
724
725                 // Check that stepping stops between nested calls
726                 e = run_until ("ss_nested_2");
727                 e = step_out ();
728                 assert_location (e, "ss_nested");
729                 e = step_into ();
730                 assert_location (e, "ss_nested_1");
731                 e = step_out ();
732                 assert_location (e, "ss_nested");
733                 // Check that step over steps over nested calls
734                 e = step_over ();
735                 assert_location (e, "ss_nested");
736                 e = step_into ();
737                 assert_location (e, "ss_nested_1");
738                 e = step_into ();
739                 assert_location (e, "ss_nested_1");
740                 e = step_into ();
741                 assert_location (e, "ss_nested");
742                 req.Disable ();
743
744                 // Check DebuggerStepThrough support
745                 e = run_until ("ss_step_through");
746                 req = create_step (e);
747                 req.Filter = StepFilter.DebuggerStepThrough;
748                 e = step_into ();
749                 // Step through step_through_1 ()
750                 e = step_into ();
751                 assert_location (e, "ss_step_through");
752                 // Step through StepThroughClass.step_through_2 ()
753                 e = step_into ();
754                 assert_location (e, "ss_step_through");
755                 req.Disable ();
756                 req.Filter = StepFilter.None;
757                 e = step_into ();
758                 assert_location (e, "step_through_3");
759                 req.Disable ();
760
761                 // Check DebuggerNonUserCode support
762                 e = run_until ("ss_non_user_code");
763                 req = create_step (e);
764                 req.Filter = StepFilter.DebuggerNonUserCode;
765                 e = step_into ();
766                 // Step through non_user_code_1 ()
767                 e = step_into ();
768                 assert_location (e, "ss_non_user_code");
769                 // Step through StepThroughClass.non_user_code_2 ()
770                 e = step_into ();
771                 assert_location (e, "ss_non_user_code");
772                 req.Disable ();
773                 req.Filter = StepFilter.None;
774                 e = step_into ();
775                 assert_location (e, "non_user_code_3");
776                 req.Disable ();
777
778                 // Check that step-over doesn't stop at inner frames with recursive functions
779                 e = run_until ("ss_recursive");
780                 req = create_step (e);
781                 e = step_over ();
782                 e = step_over ();
783                 e = step_over ();
784                 var f = e.Thread.GetFrames () [0];
785                 assert_location (e, "ss_recursive");
786                 AssertValue (1, f.GetValue (f.Method.GetLocal ("n")));
787                 req.Disable ();
788
789                 // Check that step-over stops correctly when inner frames with recursive functions contain breakpoints
790                 e = run_until ("ss_recursive2");
791                 ReusableBreakpoint breakpoint = new ReusableBreakpoint (this, "ss_recursive2_trap");
792                 try {
793                         breakpoint.Continue ();
794                         e = breakpoint.lastEvent;
795                         req = create_step (e);
796                         for (int c = 1; c <= 4; c++) {
797                                 // The first five times we try to step over this function, the breakpoint will stop us
798                                 assert_location_at_breakpoint (e, "ss_recursive2_trap");
799
800                                 req.Disable ();
801                                 req = create_step (e);
802                                 req.Size = StepSize.Line;
803
804                                 e = step_out ();
805                                 assert_location (e, "ss_recursive2");
806
807                                 // Stack should consist of Main + single_stepping + (1 ss_recursive2 frame per loop iteration)
808                                 Assert.AreEqual (c+2, e.Thread.GetFrames ().Length);
809                                 e = step_over_or_breakpoint ();
810                         }
811                         // At this point we should have escaped the breakpoints and this will be a normal step stop
812                         assert_location (e, "ss_recursive2");
813                         Assert.AreEqual (6, e.Thread.GetFrames ().Length);
814                 } finally {
815                         req.Disable ();
816                         breakpoint.Disable ();
817                 }
818
819                 // Check that step-out stops correctly when inner frames with recursive functions contain breakpoints
820                 e = run_until ("ss_recursive2");
821                 breakpoint = new ReusableBreakpoint (this, "ss_recursive2_trap");
822                 try {
823                         breakpoint.Continue ();
824                         e = breakpoint.lastEvent;
825                         req = create_step (e);
826                         for (int c = 1; c <= 4; c++) {
827                                 // The first five times we try to step over this function, the breakpoint will stop us
828                                 assert_location_at_breakpoint (e, "ss_recursive2_trap");
829
830                                 req.Disable ();
831                                 req = create_step (e);
832                                 req.Size = StepSize.Line;
833
834                                 e = step_out ();
835                                 assert_location (e, "ss_recursive2");
836
837                                 // Stack should consist of Main + single_stepping + (1 ss_recursive2 frame per loop iteration)
838                                 Assert.AreEqual (c+2, e.Thread.GetFrames ().Length);
839                                 e = step_out_or_breakpoint ();
840                         }
841                         for (int c = 3; c >= 1; c--) {
842                                 assert_location (e, "ss_recursive2");
843                                 Assert.AreEqual (c + 2, e.Thread.GetFrames ().Length);
844
845                                 e = step_out ();
846                         }
847                 } finally {
848                         req.Disable ();
849                         breakpoint.Disable ();
850                 }
851
852                 // Test step out with a really complicated call tree
853                 List<RecursiveChaoticPoint> trace = new List<RecursiveChaoticPoint>();
854                 trace_ss_recursive_chaotic (trace);
855                 e = run_until ("ss_recursive_chaotic");
856                 try {
857                         breakpoint = new ReusableBreakpoint (this, "ss_recursive_chaotic_trap");
858                         breakpoint.Continue ();
859                         e = breakpoint.lastEvent;
860                         foreach (RecursiveChaoticPoint point in trace)
861                         {
862                                 if (point.breakpoint)
863                                         assert_location_at_breakpoint (e, point.name);
864                                 else
865                                         assert_location (e, point.name);
866                                 Assert.AreEqual (point.depth, e.Thread.GetFrames ().Length);
867
868                                 req.Disable ();
869                                 req = create_step (e);
870                                 req.Size = StepSize.Line;
871                                 e = step_out_or_breakpoint ();
872                         }
873                 } finally {
874                         req.Disable ();
875                         breakpoint.Disable ();
876                 }
877
878                 // Check that single stepping doesn't clobber fp values
879                 e = run_until ("ss_fp_clobber");
880                 req = create_step (e);
881                 while (true) {
882                         f = e.Thread.GetFrames ()[0];
883                         e = step_into ();
884                         if ((e as StepEvent).Method.Name == "ss_fp_clobber_2")
885                                 break;
886                         e = step_into ();
887                 }
888                 f = e.Thread.GetFrames ()[0];
889                 AssertValue (7.0, f.GetValue (f.Method.GetParameters ()[0]));
890                 req.Disable ();
891         }
892
893         [Test]
894         public void MethodEntryExit () {
895                 run_until ("single_stepping");
896
897                 var req1 = vm.CreateMethodEntryRequest ();
898                 var req2 = vm.CreateMethodExitRequest ();
899
900                 req1.Enable ();
901                 req2.Enable ();
902
903                 vm.Resume ();
904                 Event e = GetNextEvent ();
905                 Assert.IsTrue (e is MethodEntryEvent);
906                 Assert.AreEqual ("ss1", (e as MethodEntryEvent).Method.Name);
907
908                 vm.Resume ();
909                 e = GetNextEvent ();
910                 Assert.IsTrue (e is MethodExitEvent);
911                 Assert.AreEqual ("ss1", (e as MethodExitEvent).Method.Name);
912
913                 req1.Disable ();
914                 req2.Disable ();
915         }
916
917         [Test]
918         public void CountFilter () {
919                 run_until ("single_stepping");
920
921                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("ss3");
922                 Assert.IsNotNull (m2);
923                 vm.SetBreakpoint (m2, 0);
924
925                 var req1 = vm.CreateMethodEntryRequest ();
926                 req1.Count = 2;
927                 req1.Enable ();
928
929                 // Enter ss2, ss1 is skipped
930                 vm.Resume ();
931                 Event e = GetNextEvent ();
932                 Assert.IsTrue (e is MethodEntryEvent);
933                 Assert.AreEqual ("ss2", (e as MethodEntryEvent).Method.Name);
934
935                 // Breakpoint on ss3, the entry event is no longer reported
936                 vm.Resume ();
937                 e = GetNextEvent ();
938                 Assert.IsTrue (e is BreakpointEvent);
939
940                 req1.Disable ();
941         }
942
943         [Test]
944         public void Arguments () {
945                 object val;
946
947                 var e = run_until ("arg1");
948
949                 StackFrame frame = e.Thread.GetFrames () [0];
950
951                 check_arg_val (frame, 0, typeof (sbyte), SByte.MaxValue - 5);
952                 check_arg_val (frame, 1, typeof (byte), Byte.MaxValue - 5);
953                 check_arg_val (frame, 2, typeof (bool), true);
954                 check_arg_val (frame, 3, typeof (short), Int16.MaxValue - 5);
955                 check_arg_val (frame, 4, typeof (ushort), UInt16.MaxValue - 5);
956                 check_arg_val (frame, 5, typeof (char), 'F');
957                 check_arg_val (frame, 6, typeof (int), Int32.MaxValue - 5);
958                 check_arg_val (frame, 7, typeof (uint), UInt32.MaxValue - 5);
959                 check_arg_val (frame, 8, typeof (long), Int64.MaxValue - 5);
960                 check_arg_val (frame, 9, typeof (ulong), UInt64.MaxValue - 5);
961                 check_arg_val (frame, 10, typeof (float), 1.2345f);
962                 check_arg_val (frame, 11, typeof (double), 6.78910);
963
964                 e = run_until ("arg2");
965
966                 frame = e.Thread.GetFrames () [0];
967
968                 // String
969                 val = frame.GetArgument (0);
970                 AssertValue ("FOO", val);
971                 Assert.AreEqual ("String", (val as ObjectMirror).Type.Name);
972
973                 // null
974                 val = frame.GetArgument (1);
975                 AssertValue (null, val);
976
977                 // object
978                 val = frame.GetArgument (2);
979                 AssertValue ("BLA", val);
980
981                 // byref
982                 val = frame.GetArgument (3);
983                 AssertValue (42, val);
984
985                 // generic instance
986                 val = frame.GetArgument (4);
987                 Assert.IsTrue (val is ObjectMirror);
988                 Assert.AreEqual ("GClass`1", (val as ObjectMirror).Type.Name);
989
990                 // System.Object
991                 val = frame.GetArgument (5);
992                 Assert.IsTrue (val is ObjectMirror);
993                 Assert.AreEqual ("Object", (val as ObjectMirror).Type.Name);
994
995                 // this on static methods
996                 val = frame.GetThis ();
997                 AssertValue (null, val);
998
999                 e = run_until ("arg3");
1000
1001                 frame = e.Thread.GetFrames () [0];
1002
1003                 // this
1004                 val = frame.GetThis ();
1005                 Assert.IsTrue (val is ObjectMirror);
1006                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
1007
1008                 // objref in register
1009                 val = frame.GetArgument (0);
1010                 AssertValue ("BLA", val);
1011         }
1012
1013         [Test]
1014         public void Arrays () {
1015                 object val;
1016
1017                 var e = run_until ("o2");
1018
1019                 StackFrame frame = e.Thread.GetFrames () [0];
1020
1021                 // String[]
1022                 val = frame.GetArgument (0);
1023                 Assert.IsTrue (val is ArrayMirror);
1024                 ArrayMirror arr = val as ArrayMirror;
1025                 Assert.AreEqual (2, arr.Length);
1026                 AssertValue ("BAR", arr [0]);
1027                 AssertValue ("BAZ", arr [1]);
1028
1029                 var vals = arr.GetValues (0, 2);
1030                 Assert.AreEqual (2, vals.Count);
1031                 AssertValue ("BAR", vals [0]);
1032                 AssertValue ("BAZ", vals [1]);
1033
1034                 arr [0] = vm.RootDomain.CreateString ("ABC");
1035                 AssertValue ("ABC", arr [0]);
1036
1037                 arr [0] = vm.CreateValue (null);
1038                 AssertValue (null, arr [0]);
1039
1040                 arr.SetValues (0, new Value [] { vm.RootDomain.CreateString ("D1"), vm.RootDomain.CreateString ("D2") });
1041                 AssertValue ("D1", arr [0]);
1042                 AssertValue ("D2", arr [1]);
1043
1044                 // int
1045                 val = frame.GetArgument (1);
1046                 Assert.IsTrue (val is ArrayMirror);
1047                 arr = val as ArrayMirror;
1048                 Assert.AreEqual (2, arr.Length);
1049                 AssertValue (42, arr [0]);
1050                 AssertValue (43, arr [1]);
1051
1052                 // Argument checking
1053                 AssertThrows<IndexOutOfRangeException> (delegate () {
1054                                 val = arr [2];
1055                         });
1056
1057                 AssertThrows<IndexOutOfRangeException> (delegate () {
1058                                 val = arr [Int32.MinValue];
1059                         });
1060
1061                 AssertThrows<IndexOutOfRangeException> (delegate () {
1062                                 vals = arr.GetValues (0, 3);
1063                         });
1064
1065                 AssertThrows<IndexOutOfRangeException> (delegate () {
1066                                 arr [2] = vm.CreateValue (null);
1067                         });
1068
1069                 AssertThrows<IndexOutOfRangeException> (delegate () {
1070                                 arr [Int32.MinValue] = vm.CreateValue (null);
1071                         });
1072
1073                 AssertThrows<IndexOutOfRangeException> (delegate () {
1074                                 arr.SetValues (0, new Value [] { null, null, null });
1075                         });
1076
1077                 // Multidim arrays
1078                 val = frame.GetArgument (2);
1079                 Assert.IsTrue (val is ArrayMirror);
1080                 arr = val as ArrayMirror;
1081                 Assert.AreEqual (2, arr.Rank);
1082                 Assert.AreEqual (4, arr.Length);
1083                 Assert.AreEqual (2, arr.GetLength (0));
1084                 Assert.AreEqual (2, arr.GetLength (1));
1085                 Assert.AreEqual (0, arr.GetLowerBound (0));
1086                 Assert.AreEqual (0, arr.GetLowerBound (1));
1087                 vals = arr.GetValues (0, 4);
1088                 AssertValue (1, vals [0]);
1089                 AssertValue (2, vals [1]);
1090                 AssertValue (3, vals [2]);
1091                 AssertValue (4, vals [3]);
1092
1093                 val = frame.GetArgument (3);
1094                 Assert.IsTrue (val is ArrayMirror);
1095                 arr = val as ArrayMirror;
1096                 Assert.AreEqual (2, arr.Rank);
1097                 Assert.AreEqual (4, arr.Length);
1098                 Assert.AreEqual (2, arr.GetLength (0));
1099                 Assert.AreEqual (2, arr.GetLength (1));
1100                 Assert.AreEqual (1, arr.GetLowerBound (0));
1101                 Assert.AreEqual (3, arr.GetLowerBound (1));
1102
1103                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
1104                                 arr.GetLength (-1);
1105                         });
1106                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
1107                                 arr.GetLength (2);
1108                         });
1109
1110                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
1111                                 arr.GetLowerBound (-1);
1112                         });
1113                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
1114                                 arr.GetLowerBound (2);
1115                         });
1116
1117                 // arrays treated as generic collections
1118                 val = frame.GetArgument (4);
1119                 Assert.IsTrue (val is ArrayMirror);
1120                 arr = val as ArrayMirror;
1121         }
1122
1123         [Test]
1124         public void Object_GetValue () {
1125                 var e = run_until ("o1");
1126                 var frame = e.Thread.GetFrames () [0];
1127
1128                 object val = frame.GetThis ();
1129                 Assert.IsTrue (val is ObjectMirror);
1130                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
1131                 ObjectMirror o = (val as ObjectMirror);
1132
1133                 TypeMirror t = o.Type;
1134
1135                 // object fields
1136                 object f = o.GetValue (t.GetField ("field_i"));
1137                 AssertValue (42, f);
1138                 f = o.GetValue (t.GetField ("field_s"));
1139                 AssertValue ("S", f);
1140                 f = o.GetValue (t.GetField ("field_enum"));
1141                 Assert.IsTrue (f is EnumMirror);
1142                 Assert.AreEqual (1, (f as EnumMirror).Value);
1143                 Assert.AreEqual ("B", (f as EnumMirror).StringValue);
1144
1145                 // Inherited object fields
1146                 TypeMirror parent = t.BaseType;
1147                 f = o.GetValue (parent.GetField ("base_field_i"));
1148                 AssertValue (43, f);
1149                 f = o.GetValue (parent.GetField ("base_field_s"));
1150                 AssertValue ("T", f);
1151
1152                 // Static fields
1153                 f = o.GetValue (o.Type.GetField ("static_i"));
1154                 AssertValue (55, f);
1155
1156                 // generic instances
1157                 ObjectMirror o2 = frame.GetValue (frame.Method.GetParameters ()[1]) as ObjectMirror;
1158                 Assert.AreEqual ("GClass`1", o2.Type.Name);
1159                 TypeMirror t2 = o2.Type;
1160                 f = o2.GetValue (t2.GetField ("field"));
1161                 AssertValue (42, f);
1162
1163                 ObjectMirror o3 = frame.GetValue (frame.Method.GetParameters ()[2]) as ObjectMirror;
1164                 Assert.AreEqual ("GClass`1", o3.Type.Name);
1165                 TypeMirror t3 = o3.Type;
1166                 f = o3.GetValue (t3.GetField ("field"));
1167                 AssertValue ("FOO", f);
1168
1169                 // Argument checking
1170                 AssertThrows<ArgumentNullException> (delegate () {
1171                         o.GetValue (null);
1172                         });
1173         }
1174
1175         [Test]
1176         public void Object_GetValues () {
1177                 var e = run_until ("o1");
1178                 var frame = e.Thread.GetFrames () [0];
1179
1180                 object val = frame.GetThis ();
1181                 Assert.IsTrue (val is ObjectMirror);
1182                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
1183                 ObjectMirror o = (val as ObjectMirror);
1184
1185                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1186
1187                 TypeMirror t = o.Type;
1188
1189                 object[] vals = o.GetValues (new FieldInfoMirror [] { t.GetField ("field_i"), t.GetField ("field_s") });
1190                 object f = vals [0];
1191                 AssertValue (42, f);
1192                 f = vals [1];
1193                 AssertValue ("S", f);
1194
1195                 // Argument checking
1196                 AssertThrows<ArgumentNullException> (delegate () {
1197                         o.GetValues (null);
1198                         });
1199
1200                 AssertThrows<ArgumentNullException> (delegate () {
1201                         o.GetValues (new FieldInfoMirror [] { null });
1202                         });
1203
1204                 // field of another class
1205                 AssertThrows<ArgumentException> (delegate () {
1206                                 o.GetValue (val2.Type.GetField ("field_j"));
1207                         });
1208         }
1209
1210         void TestSetValue (ObjectMirror o, string field_name, object val) {
1211                 if (val is string)
1212                         o.SetValue (o.Type.GetField (field_name), vm.RootDomain.CreateString ((string)val));
1213                 else
1214                         o.SetValue (o.Type.GetField (field_name), vm.CreateValue (val));
1215                 Value f = o.GetValue (o.Type.GetField (field_name));
1216                 AssertValue (val, f);
1217         }
1218
1219         [Test]
1220         public void Object_SetValues () {
1221                 var e = run_until ("o1");
1222                 var frame = e.Thread.GetFrames () [0];
1223
1224                 object val = frame.GetThis ();
1225                 Assert.IsTrue (val is ObjectMirror);
1226                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
1227                 ObjectMirror o = (val as ObjectMirror);
1228
1229                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1230
1231                 TestSetValue (o, "field_i", 22);
1232                 TestSetValue (o, "field_bool1", false);
1233                 TestSetValue (o, "field_bool2", true);
1234                 TestSetValue (o, "field_char", 'B');
1235                 TestSetValue (o, "field_byte", (byte)129);
1236                 TestSetValue (o, "field_sbyte", (sbyte)-33);
1237                 TestSetValue (o, "field_short", (short)(Int16.MaxValue - 5));
1238                 TestSetValue (o, "field_ushort", (ushort)(UInt16.MaxValue - 5));
1239                 TestSetValue (o, "field_long", Int64.MaxValue - 5);
1240                 TestSetValue (o, "field_ulong", (ulong)(UInt64.MaxValue - 5));
1241                 TestSetValue (o, "field_float", 6.28f);
1242                 TestSetValue (o, "field_double", 6.28);
1243                 TestSetValue (o, "static_i", 23);
1244                 TestSetValue (o, "field_s", "CDEF");
1245
1246                 Value f;
1247
1248                 // intptrs
1249                 f = o.GetValue (o.Type.GetField ("field_intptr"));
1250                 Assert.IsInstanceOfType (typeof (StructMirror), f);
1251                 AssertValue (Int32.MaxValue - 5, (f as StructMirror).Fields [0]);
1252
1253                 // enums
1254                 FieldInfoMirror field = o.Type.GetField ("field_enum");
1255                 f = o.GetValue (field);
1256                 (f as EnumMirror).Value = 5;
1257                 o.SetValue (field, f);
1258                 f = o.GetValue (field);
1259                 Assert.AreEqual (5, (f as EnumMirror).Value);
1260
1261                 // null
1262                 o.SetValue (o.Type.GetField ("field_s"), vm.CreateValue (null));
1263                 f = o.GetValue (o.Type.GetField ("field_s"));
1264                 AssertValue (null, f);
1265
1266                 // vtype instances
1267                 field = o.Type.GetField ("generic_field_struct");
1268                 f = o.GetValue (field);
1269                 o.SetValue (field, f);
1270
1271                 // nullables
1272                 field = o.Type.GetField ("field_nullable");
1273                 f = o.GetValue (field);
1274                 AssertValue (0, (f as StructMirror).Fields [0]);
1275                 AssertValue (false, (f as StructMirror).Fields [1]);
1276                 o.SetValue (field, vm.CreateValue (6));
1277                 f = o.GetValue (field);
1278                 AssertValue (6, (f as StructMirror).Fields [0]);
1279                 AssertValue (true, (f as StructMirror).Fields [1]);
1280                 o.SetValue (field, vm.CreateValue (null));
1281                 f = o.GetValue (field);
1282                 AssertValue (0, (f as StructMirror).Fields [0]);
1283                 AssertValue (false, (f as StructMirror).Fields [1]);
1284
1285                 // Argument checking
1286                 AssertThrows<ArgumentNullException> (delegate () {
1287                                 o.SetValues (null, new Value [0]);
1288                         });
1289
1290                 AssertThrows<ArgumentNullException> (delegate () {
1291                                 o.SetValues (new FieldInfoMirror [0], null);
1292                         });
1293
1294                 AssertThrows<ArgumentNullException> (delegate () {
1295                                 o.SetValues (new FieldInfoMirror [] { null }, new Value [1] { null });
1296                         });
1297
1298                 // vtype with a wrong type
1299                 AssertThrows<ArgumentException> (delegate () {
1300                                 o.SetValue (o.Type.GetField ("field_struct"), o.GetValue (o.Type.GetField ("field_enum")));
1301                         });
1302
1303                 // reference type not assignment compatible
1304                 AssertThrows<ArgumentException> (delegate () {
1305                                 o.SetValue (o.Type.GetField ("field_class"), o);
1306                         });
1307
1308                 // field of another class
1309                 AssertThrows<ArgumentException> (delegate () {
1310                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
1311                         });
1312         }
1313
1314         [Test]
1315         public void Type_SetValue () {
1316                 var e = run_until ("o1");
1317                 var frame = e.Thread.GetFrames () [0];
1318                 Value f;
1319
1320                 object val = frame.GetThis ();
1321                 Assert.IsTrue (val is ObjectMirror);
1322                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
1323                 ObjectMirror o = (val as ObjectMirror);
1324
1325                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1326
1327                 o.Type.SetValue (o.Type.GetField ("static_i"), vm.CreateValue (55));
1328                 f = o.Type.GetValue (o.Type.GetField ("static_i"));
1329                 AssertValue (55, f);
1330
1331                 o.Type.SetValue (o.Type.GetField ("static_s"), vm.RootDomain.CreateString ("B"));
1332                 f = o.Type.GetValue (o.Type.GetField ("static_s"));
1333                 AssertValue ("B", f);
1334
1335                 // Argument checking
1336                 AssertThrows<ArgumentNullException> (delegate () {
1337                                 o.Type.SetValue (null, vm.CreateValue (0));
1338                         });
1339
1340                 AssertThrows<ArgumentNullException> (delegate () {
1341                                 o.Type.SetValue (o.Type.GetField ("static_i"), null);
1342                         });
1343
1344                 // field of another class
1345                 AssertThrows<ArgumentException> (delegate () {
1346                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
1347                         });
1348         }
1349
1350         [Test]
1351         public void TypeInfo () {
1352                 Event e = run_until ("ti2");
1353                 StackFrame frame = e.Thread.GetFrames () [0];
1354
1355                 TypeMirror t;
1356
1357                 // Array types
1358                 t = frame.Method.GetParameters ()[0].ParameterType;
1359
1360                 Assert.AreEqual ("String[]", t.Name);
1361                 Assert.AreEqual ("string[]", t.CSharpName);
1362                 Assert.AreEqual ("Array", t.BaseType.Name);
1363                 Assert.AreEqual (true, t.HasElementType);
1364                 Assert.AreEqual (true, t.IsArray);
1365                 Assert.AreEqual (1, t.GetArrayRank ());
1366                 Assert.AreEqual ("String", t.GetElementType ().Name);
1367
1368                 t = frame.Method.GetParameters ()[2].ParameterType;
1369
1370                 Assert.AreEqual ("Int32[,]", t.Name);
1371                 // FIXME:
1372                 //Assert.AreEqual ("int[,]", t.CSharpName);
1373                 Assert.AreEqual ("Array", t.BaseType.Name);
1374                 Assert.AreEqual (true, t.HasElementType);
1375                 Assert.AreEqual (true, t.IsArray);
1376                 Assert.AreEqual (2, t.GetArrayRank ());
1377                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
1378
1379                 // Byref types
1380                 t = frame.Method.GetParameters ()[3].ParameterType;
1381                 // FIXME:
1382                 //Assert.AreEqual ("Int32&", t.Name);
1383                 //Assert.AreEqual (true, t.IsByRef);
1384                 //Assert.AreEqual (true, t.HasElementType);
1385
1386                 // Pointer types
1387                 t = frame.Method.GetParameters ()[4].ParameterType;
1388                 // FIXME:
1389                 //Assert.AreEqual ("Int32*", t.Name);
1390                 Assert.AreEqual (true, t.IsPointer);
1391                 Assert.AreEqual (true, t.HasElementType);
1392                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
1393                 Assert.AreEqual (false, t.IsPrimitive);
1394
1395                 // primitive types 
1396                 t = frame.Method.GetParameters ()[5].ParameterType;
1397                 Assert.AreEqual (true, t.IsPrimitive);
1398
1399                 // value types
1400                 t = frame.Method.GetParameters ()[6].ParameterType;
1401                 Assert.AreEqual ("AStruct", t.Name);
1402                 Assert.AreEqual (false, t.IsPrimitive);
1403                 Assert.AreEqual (true, t.IsValueType);
1404                 Assert.AreEqual (false, t.IsClass);
1405
1406                 // reference types
1407                 t = frame.Method.GetParameters ()[7].ParameterType;
1408                 Assert.AreEqual ("Tests", t.Name);
1409                 var nested = (from nt in t.GetNestedTypes () where nt.IsNestedPublic select nt).ToArray ();
1410                 Assert.AreEqual (1, nested.Length);
1411                 Assert.AreEqual ("NestedClass", nested [0].Name);
1412                 Assert.IsTrue (t.BaseType.IsAssignableFrom (t));
1413                 Assert.IsTrue (!t.IsAssignableFrom (t.BaseType));
1414
1415                 // generic instances
1416                 t = frame.Method.GetParameters ()[9].ParameterType;
1417                 Assert.AreEqual ("GClass`1", t.Name);
1418                 Assert.IsTrue (t.IsGenericType);
1419                 Assert.IsFalse (t.IsGenericTypeDefinition);
1420
1421                 var args = t.GetGenericArguments ();
1422                 Assert.AreEqual (1, args.Length);
1423                 Assert.AreEqual ("Int32", args [0].Name);
1424
1425                 // generic type definitions
1426                 var gtd = t.GetGenericTypeDefinition ();
1427                 Assert.AreEqual ("GClass`1", gtd.Name);
1428                 Assert.IsTrue (gtd.IsGenericType);
1429                 Assert.IsTrue (gtd.IsGenericTypeDefinition);
1430                 Assert.AreEqual (gtd, gtd.GetGenericTypeDefinition ());
1431
1432                 args = gtd.GetGenericArguments ();
1433                 Assert.AreEqual (1, args.Length);
1434                 Assert.AreEqual ("T", args [0].Name);
1435
1436                 // enums
1437                 t = frame.Method.GetParameters ()[10].ParameterType;
1438                 Assert.AreEqual ("AnEnum", t.Name);
1439                 Assert.IsTrue (t.IsEnum);
1440                 Assert.AreEqual ("Int32", t.EnumUnderlyingType.Name);
1441
1442                 // TypedReferences
1443                 t = frame.Method.GetParameters ()[11].ParameterType;
1444                 Assert.AreEqual ("TypedReference", t.Name);
1445
1446                 // properties
1447                 t = frame.Method.GetParameters ()[7].ParameterType;
1448
1449                 var props = t.GetProperties ();
1450                 Assert.AreEqual (3, props.Length);
1451                 foreach (PropertyInfoMirror prop in props) {
1452                         ParameterInfoMirror[] indexes = prop.GetIndexParameters ();
1453
1454                         if (prop.Name == "IntProperty") {
1455                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1456                                 Assert.AreEqual ("get_IntProperty", prop.GetGetMethod ().Name);
1457                                 Assert.AreEqual ("set_IntProperty", prop.GetSetMethod ().Name);
1458                                 Assert.AreEqual (0, indexes.Length);
1459                         } else if (prop.Name == "ReadOnlyProperty") {
1460                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1461                                 Assert.AreEqual ("get_ReadOnlyProperty", prop.GetGetMethod ().Name);
1462                                 Assert.AreEqual (null, prop.GetSetMethod ());
1463                                 Assert.AreEqual (0, indexes.Length);
1464                         } else if (prop.Name == "IndexedProperty") {
1465                                 Assert.AreEqual (1, indexes.Length);
1466                                 Assert.AreEqual ("Int32", indexes [0].ParameterType.Name);
1467                         }
1468                 }
1469
1470                 // custom attributes
1471                 t = frame.Method.GetParameters ()[8].ParameterType;
1472                 Assert.AreEqual ("Tests2", t.Name);
1473                 var attrs = t.GetCustomAttributes (true);
1474                 Assert.AreEqual (5, attrs.Length);
1475                 foreach (var attr in attrs) {
1476                         if (attr.Constructor.DeclaringType.Name == "DebuggerDisplayAttribute") {
1477                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1478                                 Assert.AreEqual ("Tests", attr.ConstructorArguments [0].Value);
1479                                 Assert.AreEqual (2, attr.NamedArguments.Count);
1480                                 Assert.AreEqual ("Name", attr.NamedArguments [0].Property.Name);
1481                                 Assert.AreEqual ("FOO", attr.NamedArguments [0].TypedValue.Value);
1482                                 Assert.AreEqual ("Target", attr.NamedArguments [1].Property.Name);
1483                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.NamedArguments [1].TypedValue.Value);
1484                                 Assert.AreEqual ("Int32", (attr.NamedArguments [1].TypedValue.Value as TypeMirror).Name);
1485                         } else if (attr.Constructor.DeclaringType.Name == "DebuggerTypeProxyAttribute") {
1486                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1487                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.ConstructorArguments [0].Value);
1488                                 Assert.AreEqual ("Tests", (attr.ConstructorArguments [0].Value as TypeMirror).Name);
1489                         } else if (attr.Constructor.DeclaringType.Name == "BAttribute") {
1490                                 Assert.AreEqual (2, attr.NamedArguments.Count);
1491                                 Assert.AreEqual ("afield", attr.NamedArguments [0].Field.Name);
1492                                 Assert.AreEqual ("bfield", attr.NamedArguments [1].Field.Name);
1493                         } else if (attr.Constructor.DeclaringType.Name == "ClassInterfaceAttribute") {
1494                                 // inherited from System.Object
1495                                 //} else if (attr.Constructor.DeclaringType.Name == "Serializable") {
1496                                 // inherited from System.Object
1497                         } else if (attr.Constructor.DeclaringType.Name == "ComVisibleAttribute") {
1498                                 // inherited from System.Object
1499                         } else {
1500                                 Assert.Fail (attr.Constructor.DeclaringType.Name);
1501                         }
1502                 }
1503
1504                 var assembly = entry_point.DeclaringType.Assembly;
1505                 var type = assembly.GetType ("Tests4");
1506                 Assert.IsFalse (type.IsInitialized);
1507         }
1508
1509         [Test]
1510         public void FieldInfo () {
1511                 Event e = run_until ("ti2");
1512                 StackFrame frame = e.Thread.GetFrames () [0];
1513
1514                 TypeMirror t;
1515
1516                 t = frame.Method.GetParameters ()[8].ParameterType;
1517                 Assert.AreEqual ("Tests2", t.Name);
1518
1519                 var fi = t.GetField ("field_j");
1520                 var attrs = fi.GetCustomAttributes (true);
1521                 Assert.AreEqual (1, attrs.Length);
1522                 var attr = attrs [0];
1523                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1524                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1525                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1526                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1527         }
1528
1529         [Test]
1530         public void PropertyInfo () {
1531                 Event e = run_until ("ti2");
1532                 StackFrame frame = e.Thread.GetFrames () [0];
1533
1534                 TypeMirror t;
1535
1536                 t = frame.Method.GetParameters ()[8].ParameterType;
1537                 Assert.AreEqual ("Tests2", t.Name);
1538
1539                 var pi = t.GetProperty ("AProperty");
1540                 var attrs = pi.GetCustomAttributes (true);
1541                 Assert.AreEqual (1, attrs.Length);
1542                 var attr = attrs [0];
1543                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1544                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1545                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1546                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1547         }
1548
1549         [Test]
1550         [Category ("only5")]
1551         public void Type_GetValue () {
1552                 Event e = run_until ("o1");
1553                 StackFrame frame = e.Thread.GetFrames () [0];
1554
1555                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1556
1557                 TypeMirror t = o.Type;
1558
1559                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1560
1561                 // static fields
1562                 object f = t.GetValue (o.Type.GetField ("static_i"));
1563                 AssertValue (55, f);
1564
1565                 f = t.GetValue (o.Type.GetField ("static_s"));
1566                 AssertValue ("A", f);
1567
1568                 // literal static fields
1569                 f = t.GetValue (o.Type.GetField ("literal_i"));
1570                 AssertValue (56, f);
1571
1572                 f = t.GetValue (o.Type.GetField ("literal_s"));
1573                 AssertValue ("B", f);
1574
1575                 // Inherited static fields
1576                 TypeMirror parent = t.BaseType;
1577                 f = t.GetValue (parent.GetField ("base_static_i"));
1578                 AssertValue (57, f);
1579
1580                 f = t.GetValue (parent.GetField ("base_static_s"));
1581                 AssertValue ("C", f);
1582
1583                 // thread static field
1584                 f = t.GetValue (t.GetField ("tls_i"), e.Thread);
1585                 AssertValue (42, f);
1586
1587                 // Argument checking
1588                 AssertThrows<ArgumentNullException> (delegate () {
1589                         t.GetValue (null);
1590                         });
1591
1592                 // instance fields
1593                 AssertThrows<ArgumentException> (delegate () {
1594                         t.GetValue (o.Type.GetField ("field_i"));
1595                         });
1596
1597                 // field on another type
1598                 AssertThrows<ArgumentException> (delegate () {
1599                                 t.GetValue (val2.Type.GetField ("static_field_j"));
1600                         });
1601
1602                 // special static field
1603                 AssertThrows<ArgumentException> (delegate () {
1604                                 t.GetValue (t.GetField ("tls_i"));
1605                         });
1606         }
1607
1608         [Test]
1609         public void Type_GetValues () {
1610                 Event e = run_until ("o1");
1611                 StackFrame frame = e.Thread.GetFrames () [0];
1612
1613                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1614
1615                 TypeMirror t = o.Type;
1616
1617                 // static fields
1618                 object[] vals = t.GetValues (new FieldInfoMirror [] { t.GetField ("static_i"), t.GetField ("static_s") });
1619                 object f = vals [0];
1620                 AssertValue (55, f);
1621
1622                 f = vals [1];
1623                 AssertValue ("A", f);
1624
1625                 // Argument checking
1626                 AssertThrows<ArgumentNullException> (delegate () {
1627                         t.GetValues (null);
1628                         });
1629
1630                 AssertThrows<ArgumentNullException> (delegate () {
1631                         t.GetValues (new FieldInfoMirror [] { null });
1632                         });
1633         }
1634
1635         [Test]
1636         public void ObjRefs () {
1637                 Event e = run_until ("objrefs1");
1638                 StackFrame frame = e.Thread.GetFrames () [0];
1639
1640                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1641                 ObjectMirror child = o.GetValue (o.Type.GetField ("child")) as ObjectMirror;
1642
1643                 Assert.IsTrue (child.Address != 0);
1644
1645                 // Check that object references are internalized correctly
1646                 Assert.AreEqual (o, frame.GetThis ());
1647
1648                 run_until ("objrefs2");
1649
1650                 // child should be gc'd now
1651                 // This is not deterministic
1652                 //Assert.IsTrue (child.IsCollected);
1653
1654                 /*
1655                  * No longer works since Type is read eagerly
1656                  */
1657                 /*
1658                 AssertThrows<ObjectCollectedException> (delegate () {
1659                         TypeMirror t = child.Type;
1660                         });
1661                 */
1662                 /*
1663                 AssertThrows<ObjectCollectedException> (delegate () {
1664                                 long addr = child.Address;
1665                         });
1666                 */
1667         }
1668
1669         [Test]
1670         public void Type_GetObject () {
1671                 Event e = run_until ("o1");
1672                 StackFrame frame = e.Thread.GetFrames () [0];
1673
1674                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1675
1676                 TypeMirror t = o.Type;
1677
1678                 Assert.AreEqual ("RuntimeType", t.GetTypeObject ().Type.Name);
1679         }
1680
1681         [Test]
1682         public void VTypes () {
1683                 Event e = run_until ("vtypes1");
1684                 StackFrame frame = e.Thread.GetFrames () [0];
1685
1686                 // vtypes as fields
1687                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1688                 var obj = o.GetValue (o.Type.GetField ("field_struct"));
1689                 Assert.IsTrue (obj is StructMirror);
1690                 var s = obj as StructMirror;
1691                 Assert.AreEqual ("AStruct", s.Type.Name);
1692                 AssertValue (42, s ["i"]);
1693                 obj = s ["s"];
1694                 AssertValue ("S", obj);
1695                 AssertValue (43, s ["k"]);
1696                 obj = o.GetValue (o.Type.GetField ("field_boxed_struct"));
1697                 Assert.IsTrue (obj is StructMirror);
1698                 s = obj as StructMirror;
1699                 Assert.AreEqual ("AStruct", s.Type.Name);
1700                 AssertValue (42, s ["i"]);
1701
1702                 // Check decoding of nested structs (#14942)
1703                 obj = o.GetValue (o.Type.GetField ("nested_struct"));
1704                 o.SetValue (o.Type.GetField ("nested_struct"), obj);
1705
1706                 // Check round tripping of boxed struct fields (#12354)
1707                 obj = o.GetValue (o.Type.GetField ("boxed_struct_field"));
1708                 o.SetValue (o.Type.GetField ("boxed_struct_field"), obj);
1709                 obj = o.GetValue (o.Type.GetField ("boxed_struct_field"));
1710                 s = obj as StructMirror;
1711                 AssertValue (1, s ["key"]);
1712                 obj = s ["value"];
1713                 Assert.IsTrue (obj is StructMirror);
1714                 s = obj as StructMirror;
1715                 AssertValue (42, s ["m_value"]);
1716
1717                 // vtypes as arguments
1718                 s = frame.GetArgument (0) as StructMirror;
1719                 AssertValue (44, s ["i"]);
1720                 obj = s ["s"];
1721                 AssertValue ("T", obj);
1722                 AssertValue (45, s ["k"]);
1723
1724                 // vtypes as array entries
1725                 var arr = frame.GetArgument (1) as ArrayMirror;
1726                 obj = arr [0];
1727                 Assert.IsTrue (obj is StructMirror);
1728                 s = obj as StructMirror;
1729                 AssertValue (1, s ["i"]);
1730                 AssertValue ("S1", s ["s"]);
1731                 obj = arr [1];
1732                 Assert.IsTrue (obj is StructMirror);
1733                 s = obj as StructMirror;
1734                 AssertValue (2, s ["i"]);
1735                 AssertValue ("S2", s ["s"]);
1736
1737                 // typedbyref
1738                 var typedref = frame.GetArgument (2) as StructMirror;
1739                 Assert.IsTrue (typedref is StructMirror);
1740
1741                 // Argument checking
1742                 s = frame.GetArgument (0) as StructMirror;
1743                 AssertThrows<ArgumentException> (delegate () {
1744                                 obj = s ["FOO"];
1745                         });
1746
1747                 // generic vtype instances
1748                 o = frame.GetThis () as ObjectMirror;
1749                 obj = o.GetValue (o.Type.GetField ("generic_field_struct"));
1750                 Assert.IsTrue (obj is StructMirror);
1751                 s = obj as StructMirror;
1752                 Assert.AreEqual ("GStruct`1", s.Type.Name);
1753                 AssertValue (42, s ["i"]);
1754
1755                 // this on vtype methods
1756                 e = run_until ("vtypes2");
1757                 e = step_until (e.Thread, "foo");
1758
1759                 frame = e.Thread.GetFrames () [0];
1760
1761                 Assert.AreEqual ("foo", (e as StepEvent).Method.Name);
1762                 obj = frame.GetThis ();
1763
1764                 Assert.IsTrue (obj is StructMirror);
1765                 s = obj as StructMirror;
1766                 AssertValue (44, s ["i"]);
1767                 AssertValue ("T", s ["s"]);
1768                 AssertValue (45, s ["k"]);
1769
1770                 // this on static vtype methods
1771                 e = run_until ("vtypes3");
1772                 e = step_until (e.Thread, "static_foo");
1773
1774                 frame = e.Thread.GetFrames () [0];
1775
1776                 Assert.AreEqual ("static_foo", (e as StepEvent).Method.Name);
1777                 obj = frame.GetThis ();
1778                 AssertValue (null, obj);
1779
1780                 // vtypes which reference themselves recursively
1781                 e = run_until ("vtypes4_2");
1782                 frame = e.Thread.GetFrames () [0];
1783
1784                 Assert.IsTrue (frame.GetArgument (0) is StructMirror);
1785         }
1786
1787         [Test]
1788         public void AssemblyInfo () {
1789                 Event e = run_until ("single_stepping");
1790
1791                 StackFrame frame = e.Thread.GetFrames () [0];
1792
1793                 var aname = frame.Method.DeclaringType.Assembly.GetName ();
1794                 Assert.AreEqual ("dtest-app, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", aname.ToString ());
1795
1796                 ModuleMirror m = frame.Method.DeclaringType.Module;
1797
1798                 Assert.AreEqual ("dtest-app.exe", m.Name);
1799                 Assert.AreEqual ("dtest-app.exe", m.ScopeName);
1800                 Assert.IsTrue (m.FullyQualifiedName.IndexOf ("dtest-app.exe") != -1);
1801                 Guid guid = m.ModuleVersionId;
1802                 Assert.AreEqual (frame.Method.DeclaringType.Assembly, m.Assembly);
1803                 Assert.AreEqual (frame.Method.DeclaringType.Assembly.ManifestModule, m);
1804
1805                 // This is no longer true on 4.0
1806                 //Assert.AreEqual ("Assembly", frame.Method.DeclaringType.Assembly.GetAssemblyObject ().Type.Name);
1807
1808                 TypeMirror t = vm.RootDomain.Corlib.GetType ("System.Diagnostics.DebuggerDisplayAttribute");
1809                 Assert.AreEqual ("DebuggerDisplayAttribute", t.Name);
1810         }
1811
1812         [Test]
1813         public void LocalsInfo () {
1814                 Event e = run_until ("locals2");
1815
1816                 StackFrame frame = e.Thread.GetFrames () [0];
1817
1818                 var locals = frame.Method.GetLocals ();
1819                 Assert.AreEqual (9, locals.Length);
1820                 for (int i = 0; i < 9; ++i) {
1821                         if (locals [i].Name == "args") {
1822                                 Assert.IsTrue (locals [i].IsArg);
1823                                 Assert.AreEqual ("String[]", locals [i].Type.Name);
1824                         } else if (locals [i].Name == "arg") {
1825                                 Assert.IsTrue (locals [i].IsArg);
1826                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1827                         } else if (locals [i].Name == "i") {
1828                                 Assert.IsFalse (locals [i].IsArg);
1829                                 Assert.AreEqual ("Int64", locals [i].Type.Name);
1830                         } else if (locals [i].Name == "j") {
1831                                 Assert.IsFalse (locals [i].IsArg);
1832                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1833                         } else if (locals [i].Name == "s") {
1834                                 Assert.IsFalse (locals [i].IsArg);
1835                                 Assert.AreEqual ("String", locals [i].Type.Name);
1836                         } else if (locals [i].Name == "t") {
1837                                 // gshared
1838                                 Assert.IsTrue (locals [i].IsArg);
1839                                 Assert.AreEqual ("String", locals [i].Type.Name);
1840                         } else if (locals [i].Name == "rs") {
1841                                 Assert.IsTrue (locals [i].IsArg);
1842                                 Assert.AreEqual ("String", locals [i].Type.Name);
1843                         } else if (locals [i].Name == "astruct") {
1844                         } else if (locals [i].Name == "alist") {
1845                         } else {
1846                                 Assert.Fail ();
1847                         }
1848                 }
1849         }
1850
1851         Event step_once () {
1852                 vm.Resume ();
1853                 var e = GetNextEvent ();
1854                 Assert.IsTrue (e is StepEvent);
1855                 return e;
1856         }
1857
1858         Event step_into () {
1859                 step_req.Disable ();
1860                 step_req.Depth = StepDepth.Into;
1861                 step_req.Enable ();
1862                 return step_once ();
1863         }
1864
1865         Event step_over () {
1866                 step_req.Disable ();
1867                 step_req.Depth = StepDepth.Over;
1868                 step_req.Enable ();
1869                 return step_once ();
1870         }
1871
1872         Event step_out () {
1873                 step_req.Disable ();
1874                 step_req.Depth = StepDepth.Out;
1875                 step_req.Enable ();
1876                 return step_once ();
1877         }
1878
1879         Event step_once_or_breakpoint () {
1880                 vm.Resume ();
1881                 var e = GetNextEvent ();
1882                 Assert.IsTrue (e is StepEvent || e is BreakpointEvent);
1883                 return e;
1884         }
1885
1886         Event step_over_or_breakpoint () {
1887                 step_req.Disable ();
1888                 step_req.Depth = StepDepth.Over;
1889                 step_req.Enable ();
1890                 return step_once_or_breakpoint ();
1891         }
1892
1893         Event step_out_or_breakpoint () {
1894                 step_req.Disable ();
1895                 step_req.Depth = StepDepth.Out;
1896                 step_req.Enable ();
1897                 return step_once_or_breakpoint ();
1898         }
1899
1900         [Test]
1901         public void Locals () {
1902                 var be = run_until ("locals1");
1903
1904                 StackFrame frame = be.Thread.GetFrames () [0];
1905                 MethodMirror m1 = frame.Method;
1906
1907                 // Compiler generated byref local
1908                 foreach (var l in m1.GetLocals ()) {
1909                         // The byval flag is hidden from the type
1910                         if (l.Name != "ri" && l.Type.Name == "Double")
1911                                 AssertValue (null, frame.GetValue (l));
1912                 }
1913
1914                 be = run_until ("locals2");
1915
1916                 frame = be.Thread.GetFrames () [0];
1917
1918                 object val = frame.GetValue (frame.Method.GetLocal ("i"));
1919                 AssertValue (0, val);
1920
1921                 var req = create_step (be);
1922                 req.Enable ();
1923
1924                 // Skip nop
1925                 step_once ();
1926
1927                 // Execute i = 42
1928                 var e = step_once ();
1929                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1930
1931                 // Execute s = "AB";
1932                 e = step_once ();
1933                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1934
1935                 frame = e.Thread.GetFrames () [0];
1936
1937                 val = frame.GetValue (frame.Method.GetLocal ("i"));
1938                 AssertValue (42, val);
1939
1940                 LocalVariable[] locals = frame.Method.GetLocals ();
1941                 var vals = frame.GetValues (locals);
1942                 Assert.AreEqual (locals.Length, vals.Length);
1943                 for (int i = 0; i < locals.Length; ++i) {
1944                         if (locals [i].Name == "i")
1945                                 AssertValue (42, vals [i]);
1946                         if (locals [i].Name == "s")
1947                                 AssertValue ("AB", vals [i]);
1948                         if (locals [i].Name == "t")
1949                                 AssertValue ("ABC", vals [i]);
1950                         if (locals [i].Name == "alist") {
1951                         }
1952                 }
1953
1954                 // Argument checking
1955
1956                 // GetValue () null
1957                 AssertThrows<ArgumentNullException> (delegate () {
1958                                 frame.GetValue ((LocalVariable)null);
1959                         });
1960                 // GetValue () local from another method
1961                 AssertThrows<ArgumentException> (delegate () {
1962                                 frame.GetValue (m1.GetLocal ("foo"));
1963                         });
1964
1965                 // GetValue () null
1966                 AssertThrows<ArgumentNullException> (delegate () {
1967                                 frame.GetValue ((ParameterInfoMirror)null);
1968                         });
1969                 // GetValue () local from another method
1970                 AssertThrows<ArgumentException> (delegate () {
1971                                 frame.GetValue (m1.GetParameters ()[0]);
1972                         });
1973
1974                 // GetValues () null
1975                 AssertThrows<ArgumentNullException> (delegate () {
1976                                 frame.GetValues (null);
1977                         });
1978                 // GetValues () embedded null
1979                 AssertThrows<ArgumentNullException> (delegate () {
1980                                 frame.GetValues (new LocalVariable [] { null });
1981                         });
1982                 // GetValues () local from another method
1983                 AssertThrows<ArgumentException> (delegate () {
1984                                 frame.GetValues (new LocalVariable [] { m1.GetLocal ("foo") });
1985                         });
1986                 // return value
1987                 AssertThrows<ArgumentException> (delegate () {
1988                                 val = frame.GetValue (frame.Method.ReturnParameter);
1989                         });
1990
1991                 // invalid stack frames
1992                 vm.Resume ();
1993                 e = GetNextEvent ();
1994                 Assert.IsTrue (e is StepEvent);
1995                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1996
1997                 AssertThrows<InvalidStackFrameException> (delegate () {
1998                                 frame.GetValue (frame.Method.GetLocal ("i"));
1999                         });
2000
2001                 req.Disable ();
2002
2003                 // gsharedvt
2004                 be = run_until ("locals7");
2005
2006                 req = create_step (be);
2007                 req.Enable ();
2008
2009                 // Skip nop
2010                 e = step_once ();
2011
2012                 // Test that locals are initialized
2013                 frame = e.Thread.GetFrames () [0];
2014                 val = frame.GetValue (frame.Method.GetLocal ("t"));
2015                 AssertValue (0, val);
2016
2017                 // Execute t = arg
2018                 e = step_once ();
2019                 Assert.AreEqual ("locals7", (e as StepEvent).Method.Name);
2020
2021                 // Execute t2 = t
2022                 e = step_once ();
2023                 Assert.AreEqual ("locals7", (e as StepEvent).Method.Name);
2024
2025                 frame = e.Thread.GetFrames () [0];
2026                 val = frame.GetValue (frame.Method.GetParameters ()[0]);
2027                 AssertValue (22, val);
2028                 val = frame.GetValue (frame.Method.GetLocal ("t"));
2029                 AssertValue (22, val);
2030                 val = frame.GetValue (frame.Method.GetLocal ("t2"));
2031                 AssertValue (22, val);
2032         }
2033
2034         [Test]
2035         public void GetVisibleVariables () {
2036                 Event e = run_until ("locals4");
2037
2038                 // First scope
2039                 var locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
2040                 Assert.AreEqual (2, locals.Count);
2041                 var loc = locals.First (l => l.Name == "i");
2042                 Assert.AreEqual ("Int64", loc.Type.Name);
2043                 loc = locals.First (l => l.Name == "s");
2044                 Assert.AreEqual ("String", loc.Type.Name);
2045
2046                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
2047                 Assert.AreEqual ("i", loc.Name);
2048                 Assert.AreEqual ("Int64", loc.Type.Name);
2049
2050                 e = run_until ("locals5");
2051
2052                 // Second scope
2053                 locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
2054                 Assert.AreEqual (2, locals.Count);
2055                 loc = locals.First (l => l.Name == "i");
2056                 Assert.AreEqual ("String", loc.Type.Name);
2057                 loc = locals.First (l => l.Name == "s");
2058                 Assert.AreEqual ("String", loc.Type.Name);
2059
2060                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
2061                 Assert.AreEqual ("i", loc.Name);
2062                 Assert.AreEqual ("String", loc.Type.Name);
2063
2064                 // Variable in another scope
2065                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("j");
2066                 Assert.IsNull (loc);
2067         }
2068
2069         [Test]
2070         public void Exit () {
2071                 run_until ("Main");
2072
2073                 vm.Exit (5);
2074
2075                 var e = GetNextEvent ();
2076                 Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
2077
2078                 Assert.AreEqual (5, (e as VMDeathEvent).ExitCode);
2079
2080                 var p = vm.Process;
2081                 /* Could be a remote vm with no process */
2082                 if (p != null) {
2083                         p.WaitForExit ();
2084                         Assert.AreEqual (5, p.ExitCode);
2085
2086                         // error handling
2087                         AssertThrows<VMDisconnectedException> (delegate () {
2088                                         vm.Resume ();
2089                                 });
2090                 }
2091
2092                 vm = null;
2093         }
2094
2095         [Test]
2096         public void Dispose () {
2097                 run_until ("Main");
2098
2099                 vm.Detach ();
2100
2101                 var e = GetNextEvent ();
2102                 Assert.IsInstanceOfType (typeof (VMDisconnectEvent), e);
2103
2104                 var p = vm.Process;
2105                 /* Could be a remote vm with no process */
2106                 if (p != null) {
2107                         p.WaitForExit ();
2108                         Assert.AreEqual (3, p.ExitCode);
2109
2110                         // error handling
2111                         AssertThrows<VMDisconnectedException> (delegate () {
2112                                         vm.Resume ();
2113                                 });
2114                 }
2115
2116                 vm = null;
2117         }
2118
2119         [Test]
2120         public void ColumnNumbers () {
2121                 Event e = run_until ("line_numbers");
2122
2123                 // FIXME: Merge this with LineNumbers () when its fixed
2124
2125                 step_req = create_step (e);
2126                 step_req.Depth = StepDepth.Into;
2127                 step_req.Enable ();
2128
2129                 Location l;
2130                 
2131                 while (true) {
2132                         vm.Resume ();
2133
2134                         e = GetNextEvent ();
2135                         Assert.IsTrue (e is StepEvent);
2136                         if (e.Thread.GetFrames ()[0].Method.Name == "ln1")
2137                                 break;
2138                 }
2139
2140                 // Do an additional step over so we are not on the beginning line of the method
2141                 step_req.Disable ();
2142                 step_req.Depth = StepDepth.Over;
2143                 step_req.Enable ();
2144                 vm.Resume ();
2145                 e = GetNextEvent ();
2146                 Assert.IsTrue (e is StepEvent);         
2147
2148                 l = e.Thread.GetFrames ()[0].Location;
2149
2150                 Assert.AreEqual (3, l.ColumnNumber);
2151
2152                 step_req.Disable ();
2153         }
2154
2155         [Test]
2156         // Broken by mcs+runtime changes (#5438)
2157         [Category("NotWorking")]
2158         public void LineNumbers () {
2159                 Event e = run_until ("line_numbers");
2160
2161                 step_req = create_step (e);
2162                 step_req.Depth = StepDepth.Into;
2163                 step_req.Enable ();
2164
2165                 Location l;
2166                 
2167                 vm.Resume ();
2168
2169                 e = GetNextEvent ();
2170                 Assert.IsTrue (e is StepEvent);
2171
2172                 l = e.Thread.GetFrames ()[0].Location;
2173
2174                 Assert.IsTrue (l.SourceFile.IndexOf ("dtest-app.cs") != -1);
2175                 Assert.AreEqual ("ln1", l.Method.Name);
2176
2177                 // Check hash
2178                 using (FileStream fs = new FileStream (l.SourceFile, FileMode.Open, FileAccess.Read)) {
2179                         MD5 md5 = MD5.Create ();
2180                         var hash = md5.ComputeHash (fs);
2181
2182                         for (int i = 0; i < 16; ++i)
2183                                 Assert.AreEqual (hash [i], l.SourceFileHash [i]);
2184                 }
2185                 
2186                 int line_base = l.LineNumber;
2187
2188                 vm.Resume ();
2189                 e = GetNextEvent ();
2190                 Assert.IsTrue (e is StepEvent);
2191                 l = e.Thread.GetFrames ()[0].Location;
2192                 Assert.AreEqual ("ln2", l.Method.Name);
2193                 Assert.AreEqual (line_base + 6, l.LineNumber);
2194
2195                 vm.Resume ();
2196                 e = GetNextEvent ();
2197                 Assert.IsTrue (e is StepEvent);
2198                 l = e.Thread.GetFrames ()[0].Location;
2199                 Assert.AreEqual ("ln1", l.Method.Name);
2200                 Assert.AreEqual (line_base + 1, l.LineNumber);
2201
2202                 vm.Resume ();
2203                 e = GetNextEvent ();
2204                 Assert.IsTrue (e is StepEvent);
2205                 l = e.Thread.GetFrames ()[0].Location;
2206                 Assert.AreEqual ("ln3", l.Method.Name);
2207                 Assert.AreEqual (line_base + 11, l.LineNumber);
2208
2209                 vm.Resume ();
2210                 e = GetNextEvent ();
2211                 Assert.IsTrue (e is StepEvent);
2212                 l = e.Thread.GetFrames ()[0].Location;
2213                 Assert.AreEqual ("ln3", l.Method.Name);
2214                 Assert.IsTrue (l.SourceFile.EndsWith ("FOO"));
2215                 Assert.AreEqual (55, l.LineNumber);
2216
2217                 vm.Resume ();
2218                 e = GetNextEvent ();
2219                 Assert.IsTrue (e is StepEvent);
2220                 l = e.Thread.GetFrames ()[0].Location;
2221                 Assert.AreEqual ("ln1", l.Method.Name);
2222                 Assert.AreEqual (line_base + 2, l.LineNumber);
2223
2224                 // GetSourceFiles ()
2225                 string[] sources = l.Method.DeclaringType.GetSourceFiles ();
2226                 Assert.AreEqual (2, sources.Length);
2227                 Assert.AreEqual ("dtest-app.cs", sources [0]);
2228                 Assert.AreEqual ("FOO", sources [1]);
2229
2230                 sources = l.Method.DeclaringType.GetSourceFiles (true);
2231                 Assert.AreEqual (2, sources.Length);
2232                 Assert.IsTrue (sources [0].EndsWith ("dtest-app.cs"));
2233                 Assert.IsTrue (sources [1].EndsWith ("FOO"));
2234         }
2235
2236         [Test]
2237         public void Suspend () {
2238                 vm.Detach ();
2239
2240                 Start (new string [] { "dtest-app.exe", "suspend-test" });
2241
2242                 Event e = run_until ("suspend");
2243
2244                 ThreadMirror main = e.Thread;
2245
2246                 vm.Resume ();
2247
2248                 Thread.Sleep (100);
2249
2250                 vm.Suspend ();
2251
2252                 // The debuggee should be suspended while it is running the infinite loop
2253                 // in suspend ()
2254                 StackFrame frame = main.GetFrames ()[0];
2255                 Assert.AreEqual ("suspend", frame.Method.Name);
2256
2257                 vm.Resume ();
2258
2259                 // resuming when not suspended
2260                 AssertThrows<InvalidOperationException> (delegate () {
2261                                 vm.Resume ();
2262                         });
2263
2264                 vm.Exit (0);
2265
2266                 vm = null;
2267         }
2268
2269         [Test]
2270         public void AssemblyLoad () {
2271                 Event e = run_until ("assembly_load");
2272
2273                 var load_req = vm.CreateAssemblyLoadRequest ();
2274                 load_req.Enable ();
2275
2276                 vm.Resume ();
2277
2278                 e = GetNextEvent ();
2279                 Assert.IsInstanceOfType (typeof (AssemblyLoadEvent), e);
2280                 Assert.IsTrue ((e as AssemblyLoadEvent).Assembly.Location.EndsWith ("System.dll"));
2281
2282                 var frames = e.Thread.GetFrames ();
2283                 Assert.IsTrue (frames.Length > 0);
2284                 Assert.AreEqual ("assembly_load", frames [0].Method.Name);
2285         }
2286
2287         [Test]
2288         public void CreateValue () {
2289                 PrimitiveValue v;
2290
2291                 v = vm.CreateValue (1);
2292                 Assert.AreEqual (vm, v.VirtualMachine);
2293                 Assert.AreEqual (1, v.Value);
2294
2295                 v = vm.CreateValue (null);
2296                 Assert.AreEqual (vm, v.VirtualMachine);
2297                 Assert.AreEqual (null, v.Value);
2298
2299                 // Argument checking
2300                 AssertThrows <ArgumentException> (delegate () {
2301                                 v = vm.CreateValue ("FOO");
2302                         });
2303         }
2304
2305         [Test]
2306         public void CreateString () {
2307                 StringMirror s = vm.RootDomain.CreateString ("ABC");
2308
2309                 Assert.AreEqual (vm, s.VirtualMachine);
2310                 Assert.AreEqual ("ABC", s.Value);
2311                 Assert.AreEqual (vm.RootDomain, s.Domain);
2312
2313                 // Long strings
2314                 StringBuilder sb = new StringBuilder ();
2315                 for (int i = 0; i < 1024; ++i)
2316                         sb.Append ('A');
2317                 s = vm.RootDomain.CreateString (sb.ToString ());
2318
2319                 // Argument checking
2320                 AssertThrows <ArgumentNullException> (delegate () {
2321                                 s = vm.RootDomain.CreateString (null);
2322                         });
2323         }
2324
2325         [Test]
2326         public void CreateBoxedValue () {
2327                 ObjectMirror o = vm.RootDomain.CreateBoxedValue (new PrimitiveValue (vm, 42));
2328
2329                 Assert.AreEqual ("Int32", o.Type.Name);
2330                 //AssertValue (42, m.GetValue (o.Type.GetField ("m_value")));
2331
2332                 // Argument checking
2333                 AssertThrows <ArgumentNullException> (delegate () {
2334                                 vm.RootDomain.CreateBoxedValue (null);
2335                         });
2336
2337                 AssertThrows <ArgumentException> (delegate () {
2338                                 vm.RootDomain.CreateBoxedValue (o);
2339                         });
2340         }
2341
2342         [Test]
2343         public void Invoke () {
2344                 Event e = run_until ("invoke1");
2345
2346                 StackFrame frame = e.Thread.GetFrames () [0];
2347
2348                 TypeMirror t = frame.Method.DeclaringType;
2349                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2350
2351                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2352
2353                 MethodMirror m;
2354                 Value v;
2355
2356                 // return void
2357                 m = t.GetMethod ("invoke_return_void");
2358                 v = this_obj.InvokeMethod (e.Thread, m, null);
2359                 Assert.IsNull (v);
2360
2361                 // return ref
2362                 m = t.GetMethod ("invoke_return_ref");
2363                 v = this_obj.InvokeMethod (e.Thread, m, null);
2364                 AssertValue ("ABC", v);
2365
2366                 // return null
2367                 m = t.GetMethod ("invoke_return_null");
2368                 v = this_obj.InvokeMethod (e.Thread, m, null);
2369                 AssertValue (null, v);
2370
2371                 // return primitive
2372                 m = t.GetMethod ("invoke_return_primitive");
2373                 v = this_obj.InvokeMethod (e.Thread, m, null);
2374                 AssertValue (42, v);
2375
2376                 // return nullable
2377                 m = t.GetMethod ("invoke_return_nullable");
2378                 v = this_obj.InvokeMethod (e.Thread, m, null);
2379                 Assert.IsInstanceOfType (typeof (StructMirror), v);
2380                 var s = v as StructMirror;
2381                 AssertValue (42, s.Fields [0]);
2382                 AssertValue (true, s.Fields [1]);
2383
2384                 // pass nullable as this
2385                 //m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2386                 m = s.Type.GetMethod ("ToString");
2387                 v = s.InvokeMethod (e.Thread, m, null);
2388
2389                 // return nullable null
2390                 m = t.GetMethod ("invoke_return_nullable_null");
2391                 v = this_obj.InvokeMethod (e.Thread, m, null);
2392                 Assert.IsInstanceOfType (typeof (StructMirror), v);
2393                 s = v as StructMirror;
2394                 AssertValue (0, s.Fields [0]);
2395                 AssertValue (false, s.Fields [1]);
2396
2397                 // pass nullable as this
2398                 //m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2399                 m = s.Type.GetMethod ("ToString");
2400                 v = s.InvokeMethod (e.Thread, m, null);
2401
2402                 // pass primitive
2403                 m = t.GetMethod ("invoke_pass_primitive");
2404                 Value[] args = new Value [] {
2405                         vm.CreateValue ((byte)Byte.MaxValue),
2406                         vm.CreateValue ((sbyte)SByte.MaxValue),
2407                         vm.CreateValue ((short)1),
2408                         vm.CreateValue ((ushort)1),
2409                         vm.CreateValue ((int)1),
2410                         vm.CreateValue ((uint)1),
2411                         vm.CreateValue ((long)1),
2412                         vm.CreateValue ((ulong)1),
2413                         vm.CreateValue ('A'),
2414                         vm.CreateValue (true),
2415                         vm.CreateValue (3.14f),
2416                         vm.CreateValue (3.14) };
2417
2418                 v = this_obj.InvokeMethod (e.Thread, m, args);
2419                 AssertValue ((int)Byte.MaxValue + (int)SByte.MaxValue + 1 + 1 + 1 + 1 + 1 + 1 + 'A' + 1 + 3 + 3, v);
2420
2421                 // pass ref
2422                 m = t.GetMethod ("invoke_pass_ref");
2423                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2424                 AssertValue ("ABC", v);
2425
2426                 // pass null
2427                 m = t.GetMethod ("invoke_pass_ref");
2428                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (null) });
2429                 AssertValue (null, v);
2430
2431                 // static
2432                 m = t.GetMethod ("invoke_static_pass_ref");
2433                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2434                 AssertValue ("ABC", v);
2435
2436                 // static invoked using ObjectMirror.InvokeMethod
2437                 m = t.GetMethod ("invoke_static_pass_ref");
2438                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2439                 AssertValue ("ABC", v);
2440
2441                 // method which throws an exception
2442                 try {
2443                         m = t.GetMethod ("invoke_throws");
2444                         v = this_obj.InvokeMethod (e.Thread, m, null);
2445                         Assert.Fail ();
2446                 } catch (InvocationException ex) {
2447                         Assert.AreEqual ("Exception", ex.Exception.Type.Name);
2448                 }
2449
2450 #if NET_4_5
2451                 // out argument
2452                 m = t.GetMethod ("invoke_out");
2453                 var out_task = this_obj.InvokeMethodAsyncWithResult (e.Thread, m, new Value [] { vm.CreateValue (1), vm.CreateValue (null) }, InvokeOptions.ReturnOutArgs);
2454                 var out_args = out_task.Result.OutArgs;
2455                 AssertValue (5, out_args [0]);
2456                 Assert.IsTrue (out_args [1] is ArrayMirror);
2457                 Assert.AreEqual (10, (out_args [1] as ArrayMirror).Length);
2458
2459                 // without ReturnOutArgs flag
2460                 out_task = this_obj.InvokeMethodAsyncWithResult (e.Thread, m, new Value [] { vm.CreateValue (1), vm.CreateValue (null) });
2461                 out_args = out_task.Result.OutArgs;
2462                 Assert.IsNull (out_args);
2463 #endif
2464
2465                 // newobj
2466                 m = t.GetMethod (".ctor");
2467                 v = t.InvokeMethod (e.Thread, m, null);
2468                 Assert.IsInstanceOfType (typeof (ObjectMirror), v);
2469                 Assert.AreEqual ("Tests", (v as ObjectMirror).Type.Name);
2470
2471                 // interface method
2472                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("ITest2");
2473                 m = cl1.GetMethod ("invoke_iface");
2474                 v = this_obj.InvokeMethod (e.Thread, m, null);
2475                 AssertValue (42, v);
2476
2477                 // virtual call
2478                 m = t.BaseType.GetMethod ("virtual_method");
2479                 v = this_obj.InvokeMethod (e.Thread, m, null, InvokeOptions.Virtual);
2480                 AssertValue ("V2", v);
2481
2482                 // virtual call on static method
2483                 m = t.GetMethod ("invoke_static_pass_ref");
2484                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") }, InvokeOptions.Virtual);
2485                 AssertValue ("ABC", v);
2486
2487 #if NET_4_5
2488                 // instance
2489                 m = t.GetMethod ("invoke_pass_ref");
2490                 var task = this_obj.InvokeMethodAsync (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2491                 AssertValue ("ABC", task.Result);
2492
2493                 // static
2494                 m = t.GetMethod ("invoke_static_pass_ref");
2495                 task = t.InvokeMethodAsync (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2496                 AssertValue ("ABC", task.Result);
2497 #endif
2498
2499                 // Argument checking
2500                 
2501                 // null thread
2502                 AssertThrows<ArgumentNullException> (delegate {
2503                                 m = t.GetMethod ("invoke_pass_ref");
2504                                 v = this_obj.InvokeMethod (null, m, new Value [] { vm.CreateValue (null) });                            
2505                         });
2506
2507                 // null method
2508                 AssertThrows<ArgumentNullException> (delegate {
2509                                 v = this_obj.InvokeMethod (e.Thread, null, new Value [] { vm.CreateValue (null) });                             
2510                         });
2511
2512                 // invalid number of arguments
2513                 m = t.GetMethod ("invoke_pass_ref");
2514                 AssertThrows<ArgumentException> (delegate {
2515                                 v = this_obj.InvokeMethod (e.Thread, m, null);
2516                         });
2517
2518                 // invalid type of argument (ref != primitive)
2519                 m = t.GetMethod ("invoke_pass_ref");
2520                 AssertThrows<ArgumentException> (delegate {
2521                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2522                         });
2523
2524                 // invalid type of argument (primitive != primitive)
2525                 m = t.GetMethod ("invoke_pass_primitive_2");
2526                 AssertThrows<ArgumentException> (delegate {
2527                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2528                         });
2529
2530                 // invoking a non-static method as static
2531                 m = t.GetMethod ("invoke_pass_ref");
2532                 AssertThrows<ArgumentException> (delegate {
2533                                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2534                         });
2535
2536                 // invoking a method defined in another class
2537                 m = t2.GetMethod ("invoke");
2538                 AssertThrows<ArgumentException> (delegate {
2539                                 v = this_obj.InvokeMethod (e.Thread, m, null);
2540                         });
2541         }
2542
2543         [Test]
2544         public void InvokeVType () {
2545                 Event e = run_until ("invoke1");
2546
2547                 StackFrame frame = e.Thread.GetFrames () [0];
2548
2549                 var s = frame.GetArgument (1) as StructMirror;
2550
2551                 TypeMirror t = s.Type;
2552
2553                 MethodMirror m;
2554                 Value v;
2555
2556                 // Pass struct as this, receive int
2557                 m = t.GetMethod ("invoke_return_int");
2558                 v = s.InvokeMethod (e.Thread, m, null);
2559                 AssertValue (42, v);
2560
2561                 // Pass boxed struct as this
2562                 var boxed_this = t.NewInstance () as ObjectMirror;
2563                 m = t.GetMethod ("invoke_return_int");
2564                 v = boxed_this.InvokeMethod (e.Thread, m, null);
2565                 AssertValue (0, v);
2566
2567                 // Pass struct as this, receive intptr
2568                 m = t.GetMethod ("invoke_return_intptr");
2569                 v = s.InvokeMethod (e.Thread, m, null);
2570                 AssertValue (43, v);
2571
2572                 // Static method
2573                 m = t.GetMethod ("invoke_static");
2574                 v = t.InvokeMethod (e.Thread, m, null);
2575                 AssertValue (5, v);
2576
2577                 // Pass generic struct as this
2578                 s = frame.GetArgument (2) as StructMirror;
2579                 t = s.Type;
2580                 m = t.GetMethod ("invoke_return_int");
2581                 v = s.InvokeMethod (e.Thread, m, null);
2582                 AssertValue (42, v);
2583
2584                 // .ctor
2585                 s = frame.GetArgument (1) as StructMirror;
2586                 t = s.Type;
2587                 m = t.GetMethods ().First (method => method.Name == ".ctor" && method.GetParameters ().Length == 1);
2588                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2589                 AssertValue (1, (v as StructMirror)["i"]);
2590
2591 #if NET_4_5
2592                 // Invoke a method which changes state
2593                 s = frame.GetArgument (1) as StructMirror;
2594                 t = s.Type;
2595                 m = t.GetMethod ("invoke_mutate");
2596                 var task = s.InvokeMethodAsyncWithResult (e.Thread, m, null, InvokeOptions.ReturnOutThis);
2597                 var out_this = task.Result.OutThis as StructMirror;
2598                 AssertValue (5, out_this ["l"]);
2599
2600                 // Without the ReturnOutThis flag
2601                 s = frame.GetArgument (1) as StructMirror;
2602                 t = s.Type;
2603                 m = t.GetMethod ("invoke_mutate");
2604                 task = s.InvokeMethodAsyncWithResult (e.Thread, m, null);
2605                 out_this = task.Result.OutThis as StructMirror;
2606                 Assert.AreEqual (null, out_this);
2607
2608                 // interface method
2609                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("ITest2");
2610                 m = cl1.GetMethod ("invoke_iface");
2611                 v = s.InvokeMethod (e.Thread, m, null);
2612                 AssertValue (42, v);
2613
2614                 // virtual method
2615                 m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2616                 v = s.InvokeMethod (e.Thread, m, null, InvokeOptions.Virtual);
2617                 AssertValue ("42", v);
2618 #endif
2619         }
2620
2621         [Test]
2622         public void BreakpointDuringInvoke () {
2623                 Event e = run_until ("invoke1");
2624
2625                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
2626                 Assert.IsNotNull (m);
2627                 vm.SetBreakpoint (m, 0);
2628
2629                 StackFrame frame = e.Thread.GetFrames () [0];
2630                 var o = frame.GetThis () as ObjectMirror;
2631
2632                 bool failed = false;
2633
2634                 bool finished = false;
2635                 object wait = new object ();
2636
2637                 // Have to invoke in a separate thread as the invoke is suspended until we
2638                 // resume after the breakpoint
2639                 Thread t = new Thread (delegate () {
2640                                 try {
2641                                         o.InvokeMethod (e.Thread, m, null);
2642                                 } catch {
2643                                         failed = true;
2644                                 }
2645                                 lock (wait) {
2646                                         finished = true;
2647                                         Monitor.Pulse (wait);
2648                                 }
2649                         });
2650
2651                 t.Start ();
2652
2653                 StackFrame invoke_frame = null;
2654
2655                 try {
2656                         e = GetNextEvent ();
2657                         Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
2658                         // Check stack trace support and invokes
2659                         var frames = e.Thread.GetFrames ();
2660                         invoke_frame = frames [0];
2661                         Assert.AreEqual ("invoke2", frames [0].Method.Name);
2662                         Assert.IsTrue (frames [0].IsDebuggerInvoke);
2663                         Assert.AreEqual ("invoke1", frames [1].Method.Name);
2664                 } finally {
2665                         vm.Resume ();
2666                 }
2667
2668                 lock (wait) {
2669                         if (!finished)
2670                                 Monitor.Wait (wait);
2671                 }
2672
2673                 // Check that the invoke frames are no longer valid
2674                 AssertThrows<InvalidStackFrameException> (delegate {
2675                                 invoke_frame.GetThis ();
2676                         });
2677
2678                 // Check InvokeOptions.DisableBreakpoints flag
2679                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2680         }
2681
2682         [Test]
2683         public void DisabledExceptionDuringInvoke () {
2684                 Event e = run_until ("invoke_ex");
2685
2686                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_ex_inner");
2687
2688                 StackFrame frame = e.Thread.GetFrames () [0];
2689                 var o = frame.GetThis () as ObjectMirror;
2690
2691                 var req = vm.CreateExceptionRequest (null);
2692                 req.Enable ();
2693
2694                 // Check InvokeOptions.DisableBreakpoints flag
2695                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2696
2697                 req.Disable ();
2698         }
2699
2700         [Test]
2701         public void InvokeSingleThreaded () {
2702                 vm.Detach ();
2703
2704                 Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
2705
2706                 Event e = run_until ("invoke_single_threaded_2");
2707
2708                 StackFrame f = e.Thread.GetFrames ()[0];
2709
2710                 var obj = f.GetThis () as ObjectMirror;
2711
2712                 // Check that the counter value incremented by the other thread does not increase
2713                 // during the invoke.
2714                 object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2715
2716                 var m = obj.Type.GetMethod ("invoke_return_void");
2717                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2718
2719             object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2720
2721                 Assert.AreEqual ((int)counter1, (int)counter2);
2722
2723                 // Test multiple invokes done in succession
2724                 m = obj.Type.GetMethod ("invoke_return_void");
2725                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2726
2727                 // Test events during single-threaded invokes
2728                 vm.EnableEvents (EventType.TypeLoad);
2729                 m = obj.Type.GetMethod ("invoke_type_load");
2730                 obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
2731                                 vm.Resume ();
2732                         }, null);
2733
2734                 e = GetNextEvent ();
2735                 Assert.AreEqual (EventType.TypeLoad, e.EventType);
2736         }
2737
2738         List<Value> invoke_results;
2739
2740         [Test]
2741         public void InvokeMultiple () {
2742                 Event e = run_until ("invoke1");
2743
2744                 StackFrame frame = e.Thread.GetFrames () [0];
2745
2746                 TypeMirror t = frame.Method.DeclaringType;
2747                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2748
2749                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2750
2751                 var methods = new MethodMirror [2];
2752                 methods [0] = t.GetMethod ("invoke_return_ref");
2753                 methods [1] = t.GetMethod ("invoke_return_primitive");
2754
2755                 invoke_results = new List<Value> ();
2756
2757                 var r = this_obj.BeginInvokeMultiple (e.Thread, methods, null, InvokeOptions.SingleThreaded, invoke_multiple_cb, this_obj);
2758                 WaitHandle.WaitAll (new WaitHandle[] { r.AsyncWaitHandle });
2759                 this_obj.EndInvokeMultiple (r);
2760                 // The callback might still be running
2761                 while (invoke_results.Count < 2) {
2762                         Thread.Sleep (100);
2763                 }
2764                 if (invoke_results [0] is PrimitiveValue) {
2765                         AssertValue ("ABC", invoke_results [1]);
2766                         AssertValue (42, invoke_results [0]);
2767                 } else {
2768                         AssertValue ("ABC", invoke_results [0]);
2769                         AssertValue (42, invoke_results [1]);
2770                 }
2771         }
2772
2773         void invoke_multiple_cb (IAsyncResult ar) {
2774                 ObjectMirror this_obj = (ObjectMirror)ar.AsyncState;
2775
2776                 var res = this_obj.EndInvokeMethod (ar);
2777                 lock (invoke_results)
2778                         invoke_results.Add (res);
2779         }
2780
2781         [Test]
2782         public void InvokeAbort () {
2783                 vm.Detach ();
2784
2785                 Start (new string [] { "dtest-app.exe", "invoke-abort" });
2786
2787                 Event e = run_until ("invoke_abort");
2788
2789                 StackFrame f = e.Thread.GetFrames ()[0];
2790
2791                 var obj = f.GetThis () as ObjectMirror;
2792                 var t = obj.Type;
2793                 var m = t.GetMethod ("invoke_abort_2");
2794                 // Invoke multiple times to check that the subsequent invokes are aborted too
2795                 var res = (IInvokeAsyncResult)obj.BeginInvokeMultiple (e.Thread, new MethodMirror[] { m, m, m, m }, null, InvokeOptions.None, delegate { }, null);
2796                 Thread.Sleep (500);
2797                 res.Abort ();
2798                 AssertThrows<CommandException> (delegate {
2799                                 obj.EndInvokeMethod (res);
2800                         });
2801         }
2802
2803         [Test]
2804         public void GetThreads () {
2805                 vm.GetThreads ();
2806         }
2807
2808         [Test]
2809         public void Threads () {
2810                 Event e = run_until ("threads");
2811
2812                 Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
2813
2814                 Assert.IsTrue (e.Thread.ThreadId > 0);
2815
2816                 Assert.AreEqual (e.Thread.TID, e.Thread.TID);
2817
2818                 vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
2819
2820                 vm.Resume ();
2821
2822                 e = GetNextEvent ();
2823                 Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
2824                 var state = e.Thread.ThreadState;
2825                 Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
2826
2827                 vm.Resume ();
2828
2829                 e = GetNextEvent ();
2830                 Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
2831                 Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
2832         }
2833
2834         [Test]
2835         public void Frame_SetValue () {
2836                 Event e = run_until ("locals2");
2837
2838                 StackFrame frame = e.Thread.GetFrames () [0];
2839
2840                 // primitive
2841                 var l = frame.Method.GetLocal ("i");
2842                 frame.SetValue (l, vm.CreateValue ((long)55));
2843                 AssertValue (55, frame.GetValue (l));
2844
2845                 // reference
2846                 l = frame.Method.GetLocal ("s");
2847                 frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
2848                 AssertValue ("DEF", frame.GetValue (l));
2849
2850                 // argument as local
2851                 l = frame.Method.GetLocal ("arg");
2852                 frame.SetValue (l, vm.CreateValue (6));
2853                 AssertValue (6, frame.GetValue (l));
2854
2855                 // argument
2856                 var p = frame.Method.GetParameters ()[1];
2857                 frame.SetValue (p, vm.CreateValue (7));
2858                 AssertValue (7, frame.GetValue (p));
2859
2860                 // gshared
2861                 p = frame.Method.GetParameters ()[2];
2862                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF"));
2863                 AssertValue ("DEF", frame.GetValue (p));
2864
2865                 // byref
2866                 p = frame.Method.GetParameters ()[3];
2867                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF2"));
2868                 AssertValue ("DEF2", frame.GetValue (p));
2869
2870                 // byref struct
2871                 p = frame.Method.GetParameters ()[4];
2872                 var v = frame.GetValue (p) as StructMirror;
2873                 v ["i"] = vm.CreateValue (43);
2874                 frame.SetValue (p, v);
2875                 v = frame.GetValue (p) as StructMirror;
2876                 AssertValue (43, v ["i"]);
2877
2878                 // argument checking
2879
2880                 // variable null
2881                 AssertThrows<ArgumentNullException> (delegate () {
2882                                 frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
2883                         });
2884
2885                 // value null
2886                 AssertThrows<ArgumentNullException> (delegate () {
2887                                 l = frame.Method.GetLocal ("i");
2888                                 frame.SetValue (l, null);
2889                         });
2890
2891                 // value of invalid type
2892                 AssertThrows<ArgumentException> (delegate () {
2893                                 l = frame.Method.GetLocal ("i");
2894                                 frame.SetValue (l, vm.CreateValue (55));
2895                         });
2896         }
2897
2898         [Test]
2899         [Category ("only")]
2900         public void Frame_SetValue_Registers () {
2901                 Event e = run_until ("locals6_1");
2902
2903                 StackFrame frame = e.Thread.GetFrames () [1];
2904
2905                 // Set 'j' to 99
2906                 var l = frame.Method.GetLocal ("j");
2907                 frame.SetValue (l, vm.CreateValue (99));
2908                 AssertValue (99, frame.GetValue (l));
2909
2910                 // Check it during execution
2911                 e = run_until ("locals6_2");
2912                 frame = e.Thread.GetFrames () [0];
2913                 AssertValue (99, frame.GetValue (frame.Method.GetParameters ()[0]));
2914
2915                 // Set it while in a frame which clobbers its register
2916                 e = run_until ("locals6_3");
2917                 frame = e.Thread.GetFrames () [1];
2918                 frame.SetValue (l, vm.CreateValue (100));
2919                 AssertValue (100, frame.GetValue (l));
2920
2921                 // Check it during execution
2922                 e = run_until ("locals6_4");
2923                 frame = e.Thread.GetFrames () [0];
2924                 AssertValue (100, frame.GetValue (frame.Method.GetParameters ()[0]));
2925
2926                 // Signed byte value
2927                 e = run_until ("locals6_5");
2928                 frame = e.Thread.GetFrames () [1];
2929                 var l2 = frame.Method.GetLocal ("sb");
2930                 frame.SetValue (l2, vm.CreateValue ((sbyte)-99));
2931                 AssertValue (-99, frame.GetValue (l2));
2932
2933                 // Check it during execution
2934                 e = run_until ("locals6_6");
2935                 frame = e.Thread.GetFrames () [0];
2936                 AssertValue (-99, frame.GetValue (frame.Method.GetParameters ()[0]));
2937         }
2938
2939         [Test]
2940         public void InvokeRegress () {
2941                 Event e = run_until ("invoke1");
2942
2943                 StackFrame frame = e.Thread.GetFrames () [0];
2944
2945                 TypeMirror t = frame.Method.DeclaringType;
2946                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2947
2948                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2949
2950                 MethodMirror m;
2951                 Value v;
2952
2953                 // do an invoke
2954                 m = t.GetMethod ("invoke_return_void");
2955                 v = this_obj.InvokeMethod (e.Thread, m, null);
2956                 Assert.IsNull (v);
2957
2958                 // Check that the stack frames remain valid during the invoke
2959                 Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
2960
2961                 // do another invoke
2962                 m = t.GetMethod ("invoke_return_void");
2963                 v = this_obj.InvokeMethod (e.Thread, m, null);
2964                 Assert.IsNull (v);
2965
2966                 // Try a single step after the invoke
2967                 var req = create_step (e);
2968                 req.Depth = StepDepth.Into;
2969                 req.Size = StepSize.Line;
2970                 req.Enable ();
2971
2972                 // Skip nop
2973                 step_once ();
2974
2975                 // Step into invoke2
2976                 vm.Resume ();
2977                 e = GetNextEvent ();
2978                 Assert.IsTrue (e is StepEvent);
2979                 Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
2980
2981                 req.Disable ();
2982
2983                 frame = e.Thread.GetFrames () [0];
2984         }
2985
2986         [Test]
2987         public void Exceptions () {
2988                 Event e = run_until ("exceptions");
2989                 var req = vm.CreateExceptionRequest (null);
2990                 req.Enable ();
2991
2992                 vm.Resume ();
2993
2994                 e = GetNextEvent ();
2995                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2996                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2997
2998                 var frames = e.Thread.GetFrames ();
2999                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
3000                 req.Disable ();
3001
3002                 // exception type filter
3003
3004                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
3005                 req.Enable ();
3006
3007                 // Skip the throwing of the second OverflowException       
3008                 vm.Resume ();
3009
3010                 e = GetNextEvent ();
3011                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3012                 Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
3013                 req.Disable ();
3014
3015                 // exception type filter for subclasses
3016                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
3017                 req.Enable ();
3018
3019                 vm.Resume ();
3020
3021                 e = GetNextEvent ();
3022                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3023                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
3024                 req.Disable ();
3025
3026                 // no subclasses
3027                 req.IncludeSubclasses = false;
3028                 req.Enable ();
3029
3030                 vm.Resume ();
3031
3032                 e = GetNextEvent ();
3033                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3034                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
3035                 req.Disable ();
3036
3037                 // Implicit exceptions
3038                 req = vm.CreateExceptionRequest (null);
3039                 req.Enable ();
3040
3041                 vm.Resume ();
3042
3043                 e = GetNextEvent ();
3044                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3045                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
3046                 req.Disable ();
3047
3048                 // Single stepping after an exception
3049                 req = vm.CreateExceptionRequest (null);
3050                 req.Enable ();
3051
3052                 vm.Resume ();
3053
3054                 e = GetNextEvent ();
3055                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3056                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
3057                 frames = e.Thread.GetFrames ();
3058                 Assert.AreEqual ("exceptions2", frames [0].Method.Name);
3059                 req.Disable ();
3060
3061                 var sreq = create_step (e);
3062                 sreq.Depth = StepDepth.Over;
3063                 sreq.Size = StepSize.Line;
3064                 sreq.Enable ();
3065
3066                 vm.Resume ();
3067                 e = GetNextEvent ();
3068                 Assert.IsInstanceOfType (typeof (StepEvent), e);
3069                 frames = e.Thread.GetFrames ();
3070                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
3071                 sreq.Disable ();
3072
3073                 // Argument checking
3074                 AssertThrows<ArgumentException> (delegate {
3075                                 vm.CreateExceptionRequest (e.Thread.Type);
3076                         });
3077         }
3078
3079         [Test]
3080         public void ExceptionFilter () {
3081                 Event e = run_until ("exception_filter");
3082
3083                 MethodMirror m = entry_point.DeclaringType.GetMethod ("exception_filter_filter");
3084                 Assert.IsNotNull (m);
3085
3086                 vm.SetBreakpoint (m, 0);
3087
3088                 vm.Resume ();
3089
3090                 e = GetNextEvent ();
3091                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
3092                 Assert.IsTrue (e is BreakpointEvent);
3093                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
3094
3095                 var frames = e.Thread.GetFrames ();
3096
3097                 Assert.IsTrue (frames [0].Location.SourceFile.IndexOf ("dtest-app.cs") != -1);
3098                 Assert.AreEqual ("exception_filter_filter", frames [0].Location.Method.Name);
3099
3100                 Assert.AreEqual (0, frames [1].Location.Method.MetadataToken);
3101                 Assert.AreEqual (0x0f, frames [1].Location.ILOffset);
3102
3103                 Assert.AreEqual ("exception_filter_method", frames [2].Location.Method.Name);
3104                 Assert.AreEqual (0x06, frames [2].Location.ILOffset);
3105
3106                 Assert.AreEqual (0, frames [3].Location.Method.MetadataToken, 0);
3107                 Assert.AreEqual (0, frames [3].Location.ILOffset);
3108
3109                 Assert.AreEqual ("exception_filter", frames [4].Location.Method.Name);
3110         }
3111
3112         [Test]
3113         public void ExceptionFilter2 () {
3114                 vm.Detach ();
3115
3116                 Start (new string [] { "dtest-excfilter.exe" });
3117
3118                 MethodMirror filter_method = entry_point.DeclaringType.GetMethod ("Filter");
3119                 Assert.IsNotNull (filter_method);
3120
3121                 MethodMirror test_method = entry_point.DeclaringType.GetMethod ("Test");
3122                 Assert.IsNotNull (test_method);
3123
3124                 vm.SetBreakpoint (filter_method, 0);
3125
3126                 vm.Resume ();
3127
3128                 var e = GetNextEvent ();
3129                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
3130                 Assert.IsTrue (e is BreakpointEvent);
3131                 Assert.AreEqual (filter_method.Name, (e as BreakpointEvent).Method.Name);
3132
3133                 var frames = e.Thread.GetFrames ();
3134
3135                 Assert.AreEqual (4, frames.Count ());
3136
3137                 Assert.AreEqual (filter_method.Name, frames [0].Location.Method.Name);
3138                 Assert.AreEqual (20, frames [0].Location.LineNumber);
3139                 Assert.AreEqual (0, frames [0].Location.ILOffset);
3140
3141                 Assert.AreEqual (test_method.Name, frames [1].Location.Method.Name);
3142                 Assert.AreEqual (37, frames [1].Location.LineNumber);
3143                 Assert.AreEqual (0x0b, frames [1].Location.ILOffset);
3144
3145                 Assert.AreEqual (test_method.Name, frames [2].Location.Method.Name);
3146                 Assert.AreEqual (33, frames [2].Location.LineNumber);
3147                 Assert.AreEqual (0x05, frames [2].Location.ILOffset);
3148
3149                 Assert.AreEqual (entry_point.Name, frames [3].Location.Method.Name);
3150                 Assert.AreEqual (14, frames [3].Location.LineNumber);
3151                 Assert.AreEqual (0x00, frames [3].Location.ILOffset);
3152
3153                 vm.Exit (0);
3154
3155                 vm = null;
3156         }
3157
3158         [Test]
3159         public void EventSets () {
3160                 //
3161                 // Create two filter which both match the same exception
3162                 //
3163                 Event e = run_until ("exceptions");
3164
3165                 var req = vm.CreateExceptionRequest (null);
3166                 req.Enable ();
3167
3168                 var req2 = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.OverflowException"));
3169                 req2.Enable ();
3170
3171                 vm.Resume ();
3172
3173                 var es = vm.GetNextEventSet ();
3174                 Assert.AreEqual (2, es.Events.Length);
3175
3176                 e = es [0];
3177                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3178                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
3179
3180                 e = es [1];
3181                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3182                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
3183
3184                 req.Disable ();
3185                 req2.Disable ();
3186         }
3187
3188         //
3189         // Test single threaded invokes during processing of nullref exceptions.
3190         // These won't work if the exception handling is done from the sigsegv signal
3191         // handler, since the sigsegv signal is disabled until control returns from the
3192         // signal handler.
3193         //
3194         [Test]
3195         [Category ("only3")]
3196         public void NullRefExceptionAndSingleThreadedInvoke () {
3197                 Event e = run_until ("exceptions");
3198                 var req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.NullReferenceException"));
3199                 req.Enable ();
3200
3201                 vm.Resume ();
3202
3203                 e = GetNextEvent ();
3204                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3205                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
3206
3207                 var ex = (e as ExceptionEvent).Exception;
3208                 var tostring_method = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
3209                 ex.InvokeMethod (e.Thread, tostring_method, null, InvokeOptions.SingleThreaded);
3210         }
3211
3212         [Test]
3213         public void MemberInOtherDomain () {
3214                 vm.Detach ();
3215
3216                 Start (new string [] { "dtest-app.exe", "domain-test" });
3217
3218                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
3219
3220                 Event e = run_until ("domains_print_across");
3221
3222                 var frame = e.Thread.GetFrames ()[0];
3223                 var inOtherDomain = frame.GetArgument (0) as ObjectMirror;
3224                 var crossDomainField = (ObjectMirror) inOtherDomain.GetValue (inOtherDomain.Type.GetField("printMe"));
3225                 Assert.AreEqual ("SentinelClass", crossDomainField.Type.Name);
3226         }
3227
3228         [Test]
3229         public void Domains () {
3230                 vm.Detach ();
3231
3232                 Start (new string [] { "dtest-app.exe", "domain-test" });
3233
3234                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
3235
3236                 Event e = run_until ("domains");
3237
3238                 vm.Resume ();
3239                 
3240                 e = GetNextEvent ();
3241                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
3242
3243                 var domain = (e as AppDomainCreateEvent).Domain;
3244
3245                 // Check the object type
3246                 e = run_until ("domains_2");
3247                 var frame = e.Thread.GetFrames ()[0];
3248                 var o = frame.GetArgument (0) as ObjectMirror;
3249                 Assert.AreEqual ("CrossDomain", o.Type.Name);
3250
3251                 // Do a remoting invoke
3252                 var cross_domain_type = o.Type;
3253                 var v = o.InvokeMethod (e.Thread, cross_domain_type.GetMethod ("invoke_3"), null);
3254                 AssertValue (42, v);
3255
3256                 // Run until the callback in the domain
3257                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
3258                 Assert.IsNotNull (m);
3259                 vm.SetBreakpoint (m, 0);
3260
3261                 while (true) {
3262                         vm.Resume ();
3263                         e = GetNextEvent ();
3264                         if (e is BreakpointEvent)
3265                                 break;
3266                 }
3267
3268                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
3269
3270                 // d_method is from another domain
3271                 MethodMirror d_method = (e as BreakpointEvent).Method;
3272                 Assert.IsTrue (m != d_method);
3273
3274                 var frames = e.Thread.GetFrames ();
3275                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
3276                 Assert.AreEqual (domain, frames [0].Domain);
3277                 Assert.AreEqual ("invoke", frames [1].Method.Name);
3278                 Assert.AreEqual ("domains", frames [2].Method.Name);
3279                 Assert.AreEqual (vm.RootDomain, frames [2].Domain);
3280
3281                 // Test breakpoints on already JITted methods in other domains
3282                 m = entry_point.DeclaringType.GetMethod ("invoke_in_domain_2");
3283                 Assert.IsNotNull (m);
3284                 vm.SetBreakpoint (m, 0);
3285
3286                 while (true) {
3287                         vm.Resume ();
3288                         e = GetNextEvent ();
3289                         if (e is BreakpointEvent)
3290                                 break;
3291                 }
3292
3293                 Assert.AreEqual ("invoke_in_domain_2", (e as BreakpointEvent).Method.Name);
3294
3295                 // This is empty when receiving the AppDomainCreateEvent
3296                 Assert.AreEqual ("domain", domain.FriendlyName);
3297
3298                 // Run until the unload
3299                 while (true) {
3300                         vm.Resume ();
3301                         e = GetNextEvent ();
3302                         if (e is AssemblyUnloadEvent) {
3303                                 continue;
3304                         } else {
3305                                 break;
3306                         }
3307                 }
3308                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
3309                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
3310
3311                 // Run past the unload
3312                 e = run_until ("domains_3");
3313
3314                 // Test access to unloaded types
3315                 // FIXME: Add an exception type for this
3316                 AssertThrows<Exception> (delegate {
3317                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
3318                         });
3319
3320                 // Check that .Domain is accessible for stack frames with native transitions
3321                 e = run_until ("called_from_invoke");
3322                 ThreadMirror.NativeTransitions = true;
3323                 foreach (var f in e.Thread.GetFrames ()) {
3324                         var dom = f.Domain;
3325                 }
3326         }
3327
3328         [Test]
3329         public void DynamicMethods () {
3330                 Event e = run_until ("dyn_call");
3331
3332                 var m = e.Thread.GetFrames ()[1].Method;
3333                 Assert.AreEqual ("dyn_method", m.Name);
3334
3335                 // Test access to IL
3336                 var body = m.GetMethodBody ();
3337
3338                 ILInstruction ins = body.Instructions [0];
3339                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
3340                 Assert.AreEqual ("FOO", ins.Operand);
3341         }
3342
3343         [Test]
3344         public void RefEmit () {
3345                 vm.Detach ();
3346
3347                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
3348
3349                 Event e = run_until ("ref_emit_call");
3350
3351                 var m = e.Thread.GetFrames ()[1].Method;
3352                 Assert.AreEqual ("ref_emit_method", m.Name);
3353
3354                 // Test access to IL
3355                 var body = m.GetMethodBody ();
3356
3357                 ILInstruction ins;
3358
3359                 ins = body.Instructions [0];
3360                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
3361                 Assert.AreEqual ("FOO", ins.Operand);
3362
3363                 ins = body.Instructions [1];
3364                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
3365                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
3366                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
3367         }
3368
3369         [Test]
3370         public void IsAttached () {
3371                 var f = entry_point.DeclaringType.GetField ("is_attached");
3372
3373                 Event e = run_until ("Main");
3374
3375                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
3376         }
3377
3378         [Test]
3379         public void StackTraceInNative () {
3380                 // Check that stack traces can be produced for threads in native code
3381                 vm.Detach ();
3382
3383                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
3384
3385                 var e = run_until ("frames_in_native");
3386
3387                 // FIXME: This is racy
3388                 vm.Resume ();
3389
3390                 Thread.Sleep (100);
3391
3392                 vm.Suspend ();
3393
3394                 StackFrame[] frames = e.Thread.GetFrames ();
3395
3396                 int frame_index = -1;
3397                 for (int i = 0; i < frames.Length; ++i) {
3398                         if (frames [i].Method.Name == "Sleep") {
3399                                 frame_index = i;
3400                                 break;
3401                         }
3402                 }
3403
3404                 Assert.IsTrue (frame_index != -1);
3405                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
3406                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
3407                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
3408
3409                 // Check that invokes are disabled for such threads
3410                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
3411
3412                 var m = t.GetMethod ("invoke_static_return_void");
3413                 AssertThrows<InvalidOperationException> (delegate {
3414                                 t.InvokeMethod (e.Thread, m, null);
3415                         });
3416
3417                 // Check that the frame info is invalidated
3418                 run_until ("frames_in_native_2");
3419
3420                 AssertThrows<InvalidStackFrameException> (delegate {
3421                                 Console.WriteLine (frames [frame_index].GetThis ());
3422                         });
3423         }
3424
3425         [Test]
3426         public void VirtualMachine_CreateEnumMirror () {
3427                 var e = run_until ("o1");
3428                 var frame = e.Thread.GetFrames () [0];
3429
3430                 object val = frame.GetThis ();
3431                 Assert.IsTrue (val is ObjectMirror);
3432                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
3433                 ObjectMirror o = (val as ObjectMirror);
3434
3435                 FieldInfoMirror field = o.Type.GetField ("field_enum");
3436                 Value f = o.GetValue (field);
3437                 TypeMirror enumType = (f as EnumMirror).Type;
3438
3439                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
3440                 f = o.GetValue (field);
3441                 Assert.AreEqual (1, (f as EnumMirror).Value);
3442
3443                 // Argument checking
3444                 AssertThrows<ArgumentNullException> (delegate () {
3445                                 vm.CreateEnumMirror (enumType, null);
3446                         });
3447
3448                 AssertThrows<ArgumentNullException> (delegate () {
3449                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
3450                         });
3451
3452                 // null value
3453                 AssertThrows<ArgumentException> (delegate () {
3454                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
3455                         });
3456
3457                 // value of a wrong type
3458                 AssertThrows<ArgumentException> (delegate () {
3459                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
3460                         });
3461         }
3462
3463         [Test]
3464         public void VirtualMachine_EnableEvents_Breakpoint () {
3465                 AssertThrows<ArgumentException> (delegate () {
3466                                 vm.EnableEvents (EventType.Breakpoint);
3467                         });
3468         }
3469
3470         [Test]
3471         public void SingleStepRegress654694 () {
3472                 int il_offset = -1;
3473
3474                 MethodMirror m = entry_point.DeclaringType.GetMethod ("ss_regress_654694");
3475                 foreach (Location l in m.Locations) {
3476                         if (l.ILOffset > 0 && il_offset == -1)
3477                                 il_offset = l.ILOffset;
3478                 }
3479
3480                 Event e = run_until ("ss_regress_654694");
3481
3482                 Assert.IsNotNull (m);
3483                 vm.SetBreakpoint (m, il_offset);
3484
3485                 vm.Resume ();
3486
3487                 e = GetNextEvent ();
3488                 Assert.IsTrue (e is BreakpointEvent);
3489
3490                 var req = create_step (e);
3491                 req.Depth = StepDepth.Over;
3492                 req.Size = StepSize.Line;
3493                 req.Enable ();
3494
3495                 vm.Resume ();
3496
3497                 e = GetNextEvent ();
3498                 Assert.IsTrue (e is StepEvent);
3499
3500                 req.Disable ();
3501         }
3502
3503         [Test]
3504         public void DebugBreak () {
3505                 vm.EnableEvents (EventType.UserBreak);
3506
3507                 run_until ("user");
3508
3509                 vm.Resume ();
3510                 var e = GetNextEvent ();
3511                 Assert.IsTrue (e is UserBreakEvent);
3512         }
3513
3514         [Test]
3515         public void DebugLog () {
3516                 vm.EnableEvents (EventType.UserLog);
3517
3518                 run_until ("user");
3519
3520                 vm.Resume ();
3521                 var e = GetNextEvent ();
3522                 Assert.IsTrue (e is UserLogEvent);
3523                 var le = e as UserLogEvent;
3524
3525                 Assert.AreEqual (5, le.Level);
3526                 Assert.AreEqual ("A", le.Category);
3527                 Assert.AreEqual ("B", le.Message);
3528         }
3529
3530         [Test]
3531         public void TypeGetMethodsByNameFlags () {
3532                 MethodMirror[] mm;
3533                 var assembly = entry_point.DeclaringType.Assembly;
3534                 var type = assembly.GetType ("Tests3");
3535
3536                 Assert.IsNotNull (type);
3537
3538                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Public, false);
3539                 Assert.AreEqual (1, mm.Length, "#1");
3540                 Assert.AreEqual ("M1", mm[0].Name, "#2");
3541
3542                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.NonPublic, false);
3543                 Assert.AreEqual (1, mm.Length, "#3");
3544                 Assert.AreEqual ("M2", mm[0].Name, "#4");
3545
3546                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public, false);
3547                 Assert.AreEqual (7, mm.Length, "#5"); //M3 plus Equals, GetHashCode, GetType, ToString, .ctor
3548
3549                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, false);
3550                 Assert.AreEqual (2, mm.Length, "#7");
3551
3552                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
3553                 Assert.AreEqual (1, mm.Length, "#9");
3554
3555                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
3556                 Assert.AreEqual (5, mm.Length, "#11");
3557
3558                 //Now with name
3559                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static | BindingFlags.Public, false);
3560                 Assert.AreEqual (1, mm.Length, "#12");
3561                 Assert.AreEqual ("M1", mm[0].Name, "#13");
3562
3563                 mm = type.GetMethodsByNameFlags ("m1", BindingFlags.Static | BindingFlags.Public, true);
3564                 Assert.AreEqual (1, mm.Length, "#14");
3565                 Assert.AreEqual ("M1", mm[0].Name, "#15");
3566
3567                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static  | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, false);
3568                 Assert.AreEqual (1, mm.Length, "#16");
3569                 Assert.AreEqual ("M1", mm[0].Name, "#17");
3570         }
3571
3572         [Test]
3573         [Category ("only88")]
3574         public void TypeLoadSourceFileFilter () {
3575                 Event e = run_until ("type_load");
3576
3577                 if (!vm.Version.AtLeast (2, 7))
3578                         return;
3579
3580                 string srcfile = (e as BreakpointEvent).Method.DeclaringType.GetSourceFiles (true)[0];
3581
3582                 var req = vm.CreateTypeLoadRequest ();
3583                 req.SourceFileFilter = new string [] { srcfile.ToUpper () };
3584                 req.Enable ();
3585
3586                 vm.Resume ();
3587                 e = GetNextEvent ();
3588                 Assert.IsTrue (e is TypeLoadEvent);
3589                 Assert.AreEqual ("TypeLoadClass", (e as TypeLoadEvent).Type.FullName);
3590         }
3591
3592         [Test]
3593         public void TypeLoadTypeNameFilter () {
3594                 Event e = run_until ("type_load");
3595
3596                 var req = vm.CreateTypeLoadRequest ();
3597                 req.TypeNameFilter = new string [] { "TypeLoadClass2" };
3598                 req.Enable ();
3599
3600                 vm.Resume ();
3601                 e = GetNextEvent ();
3602                 Assert.IsTrue (e is TypeLoadEvent);
3603                 Assert.AreEqual ("TypeLoadClass2", (e as TypeLoadEvent).Type.FullName);
3604         }
3605
3606         [Test]
3607         public void GetTypesForSourceFile () {
3608                 run_until ("user");
3609
3610                 var types = vm.GetTypesForSourceFile ("dtest-app.cs", false);
3611                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3612                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3613
3614                 types = vm.GetTypesForSourceFile ("DTEST-app.cs", true);
3615                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3616                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3617         }
3618
3619         [Test]
3620         public void GetTypesNamed () {
3621                 run_until ("user");
3622
3623                 var types = vm.GetTypes ("Tests", false);
3624                 Assert.AreEqual (1, types.Count);
3625                 Assert.AreEqual ("Tests", types [0].FullName);
3626
3627                 types = vm.GetTypes ("System.Exception", false);
3628                 Assert.AreEqual (1, types.Count);
3629                 Assert.AreEqual ("System.Exception", types [0].FullName);
3630         }
3631
3632         [Test]
3633         public void String_GetValue () {
3634                 // Embedded nulls
3635                 object val;
3636
3637                 // Reuse this test
3638                 var e = run_until ("arg2");
3639
3640                 var frame = e.Thread.GetFrames () [0];
3641
3642                 val = frame.GetArgument (6);
3643                 Assert.AreEqual ('\0'.ToString () + "A", (val as StringMirror).Value);
3644         }
3645
3646         [Test]
3647         public void String_GetChars () {
3648                 object val;
3649
3650                 // Reuse this test
3651                 var e = run_until ("arg2");
3652
3653                 var frame = e.Thread.GetFrames () [0];
3654
3655                 val = frame.GetArgument (0);
3656                 Assert.IsTrue (val is StringMirror);
3657                 AssertValue ("FOO", val);
3658                 var s = (val as StringMirror);
3659                 Assert.AreEqual (3, s.Length);
3660
3661                 var c = s.GetChars (0, 2);
3662                 Assert.AreEqual (2, c.Length);
3663                 Assert.AreEqual ('F', c [0]);
3664                 Assert.AreEqual ('O', c [1]);
3665
3666                 AssertThrows<ArgumentException> (delegate () {          
3667                                 s.GetChars (2, 2);
3668                         });
3669         }
3670
3671         [Test]
3672         public void GetInterfaces () {
3673                 var e = run_until ("arg2");
3674
3675                 var frame = e.Thread.GetFrames () [0];
3676
3677                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3678                 var ifaces = cl1.GetInterfaces ();
3679                 Assert.AreEqual (1, ifaces.Length);
3680                 Assert.AreEqual ("ITest", ifaces [0].Name);
3681
3682                 var cl2 = cl1.GetMethod ("Baz").ReturnType;
3683                 var ifaces2 = cl2.GetInterfaces ();
3684                 Assert.AreEqual (1, ifaces2.Length);
3685                 Assert.AreEqual ("ITest`1", ifaces2 [0].Name);
3686         }
3687
3688         [Test]
3689         public void GetInterfaceMap () {
3690                 var e = run_until ("arg2");
3691
3692                 var frame = e.Thread.GetFrames () [0];
3693
3694                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3695                 var iface = cl1.Assembly.GetType ("ITest");
3696                 var map = cl1.GetInterfaceMap (iface);
3697                 Assert.AreEqual (cl1, map.TargetType);
3698                 Assert.AreEqual (iface, map.InterfaceType);
3699                 Assert.AreEqual (2, map.InterfaceMethods.Length);
3700                 Assert.AreEqual (2, map.TargetMethods.Length);
3701         }
3702
3703         [Test]
3704         public void StackAlloc_Breakpoints_Regress2775 () {
3705                 // Check that breakpoints on arm don't overwrite stackalloc-ed memory
3706                 var e = run_until ("regress_2755");
3707
3708                 var frame = e.Thread.GetFrames () [0];
3709                 var m = e.Method;
3710                 // This breaks at the call site
3711                 vm.SetBreakpoint (m, m.Locations [2].ILOffset);
3712
3713                 vm.Resume ();
3714                 var e2 = GetNextEvent ();
3715                 Assert.IsTrue (e2 is BreakpointEvent);
3716
3717                 e = run_until ("regress_2755_3");
3718                 frame = e.Thread.GetFrames () [1];
3719                 var res = frame.GetValue (m.GetLocal ("sum"));
3720                 AssertValue (0, res);
3721         }
3722
3723         [Test]
3724         public void MethodInfo () {
3725                 Event e = run_until ("locals2");
3726
3727                 StackFrame frame = e.Thread.GetFrames () [0];
3728                 var m = frame.Method;
3729
3730                 Assert.IsTrue (m.IsGenericMethod);
3731                 Assert.IsFalse (m.IsGenericMethodDefinition);
3732
3733                 var args = m.GetGenericArguments ();
3734                 Assert.AreEqual (1, args.Length);
3735                 Assert.AreEqual ("String", args [0].Name);
3736
3737                 var gmd = m.GetGenericMethodDefinition ();
3738                 Assert.IsTrue (gmd.IsGenericMethod);
3739                 Assert.IsTrue (gmd.IsGenericMethodDefinition);
3740                 Assert.AreEqual (gmd, gmd.GetGenericMethodDefinition ());
3741
3742                 args = gmd.GetGenericArguments ();
3743                 Assert.AreEqual (1, args.Length);
3744                 Assert.AreEqual ("T", args [0].Name);
3745
3746                 var attrs = m.GetCustomAttributes (true);
3747                 Assert.AreEqual (1, attrs.Length);
3748                 Assert.AreEqual ("StateMachineAttribute", attrs [0].Constructor.DeclaringType.Name);
3749         }
3750
3751         [Test]
3752         public void UnhandledException () {
3753                 vm.Exit (0);
3754
3755                 Start (new string [] { "dtest-app.exe", "unhandled-exception" });
3756
3757                 var req = vm.CreateExceptionRequest (null, false, true);
3758                 req.Enable ();
3759
3760                 var e = run_until ("unhandled_exception");
3761                 vm.Resume ();
3762
3763                 var e2 = GetNextEvent ();
3764                 Assert.IsTrue (e2 is ExceptionEvent);
3765
3766                 vm.Exit (0);
3767                 vm = null;
3768         }
3769
3770         [Test]
3771         public void UnhandledException_2 () {
3772                 vm.Exit (0);
3773
3774                 Start (new string [] { "dtest-app.exe", "unhandled-exception-endinvoke" });
3775
3776                 var req = vm.CreateExceptionRequest (null, false, true);
3777                 req.Enable ();
3778
3779                 MethodMirror m = entry_point.DeclaringType.GetMethod ("unhandled_exception_endinvoke_2");
3780                 Assert.IsNotNull (m);
3781                 vm.SetBreakpoint (m, m.ILOffsets [0]);
3782
3783                 var e = run_until ("unhandled_exception_endinvoke");
3784                 vm.Resume ();
3785
3786                 var e2 = GetNextEvent ();
3787                 Assert.IsFalse (e2 is ExceptionEvent);
3788
3789                 vm.Exit (0);
3790                 vm = null;
3791         }
3792
3793 #if NET_4_5
3794         [Test]
3795         public void UnhandledExceptionUserCode () {
3796                 vm.Detach ();
3797
3798                 // Exceptions caught in non-user code are treated as unhandled
3799                 Start (new string [] { "dtest-app.exe", "unhandled-exception-user" });
3800
3801                 var req = vm.CreateExceptionRequest (null, false, true);
3802                 req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
3803                 req.Enable ();
3804
3805                 var e = run_until ("unhandled_exception_user");
3806                 vm.Resume ();
3807
3808                 var e2 = GetNextEvent ();
3809                 Assert.IsTrue (e2 is ExceptionEvent);
3810
3811                 vm.Exit (0);
3812                 vm = null;
3813         }
3814 #endif
3815
3816         [Test]
3817         public void GCWhileSuspended () {
3818                 // Check that objects are kept alive during suspensions
3819                 Event e = run_until ("gc_suspend_1");
3820
3821                 MethodMirror m = entry_point.DeclaringType.GetMethod ("gc_suspend_invoke");
3822
3823                 var o = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3824                 //Console.WriteLine (o);
3825
3826                 StackFrame frame = e.Thread.GetFrames () [0];
3827                 TypeMirror t = frame.Method.DeclaringType;
3828                 for (int i = 0; i < 10; ++i)
3829                         t.InvokeMethod (e.Thread, m, new Value [] { });
3830
3831                 // This throws an exception if the object is collected
3832                 long addr = o.Address;
3833
3834                 var o2 = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3835                 Assert.IsNull (o2);
3836         }
3837
3838         [Test]
3839         public void MakeGenericMethod () {
3840                 Event e = run_until ("bp1");
3841
3842                 var intm = vm.RootDomain.GetCorrespondingType (typeof (int));
3843                 var stringm = vm.RootDomain.GetCorrespondingType (typeof (string));
3844                 var gm = entry_point.DeclaringType.GetMethod ("generic_method");
3845                 var res = gm.MakeGenericMethod (new TypeMirror [] { stringm });
3846                 var args = res.GetGenericArguments ();
3847                 Assert.AreEqual (1, args.Length);
3848                 Assert.AreEqual (stringm, args [0]);
3849
3850                 // Error checking
3851                 AssertThrows<ArgumentNullException> (delegate {
3852                                 gm.MakeGenericMethod (null);
3853                         });
3854                 AssertThrows<ArgumentNullException> (delegate {
3855                                 gm.MakeGenericMethod (new TypeMirror [] { null });
3856                         });
3857                 AssertThrows<ArgumentException> (delegate {
3858                                 gm.MakeGenericMethod (new TypeMirror [] { stringm, stringm });
3859                         });
3860                 AssertThrows<InvalidOperationException> (delegate {
3861                                 gm.MakeGenericMethod (new TypeMirror [] { intm });
3862                         });
3863                 AssertThrows<InvalidOperationException> (delegate {
3864                                 entry_point.DeclaringType.GetMethod ("Main").MakeGenericMethod (new TypeMirror [] { intm });
3865                         });
3866         }
3867
3868         [Test]
3869         public void InspectThreadSuspenedOnWaitOne () {
3870                 TearDown ();
3871                 Start (true, "dtest-app.exe", "wait-one" );
3872
3873                 ThreadMirror.NativeTransitions = true;
3874
3875                 var evt = run_until ("wait_one");
3876                 Assert.IsNotNull (evt, "#1");
3877
3878                 var thread = evt.Thread;
3879                 Assert.AreEqual (ThreadState.Running, thread.ThreadState, "#1.1");
3880
3881                 var frames = thread.GetFrames ();
3882                 Assert.IsNotNull (frames, "#2");
3883                 Assert.AreEqual (2, frames.Length, "#3");
3884                 Assert.AreEqual ("wait_one", frames [0].Method.Name, "#4");
3885                 Assert.AreEqual ("Main", frames [1].Method.Name, "#5");
3886
3887                 vm.Resume ();
3888
3889                 Thread.Sleep (500); //FIXME this is racy, maybe single step? or something?
3890
3891                 vm.Suspend ();
3892                 Assert.AreEqual (ThreadState.WaitSleepJoin, thread.ThreadState, "#6");
3893
3894                 frames = thread.GetFrames ();
3895                 Assert.AreEqual (8, frames.Length, "#7");
3896                 Assert.AreEqual ("WaitOne_internal", frames [0].Method.Name, "#8.0");
3897                 Assert.AreEqual ("WaitOneNative", frames [1].Method.Name, "#8.1");
3898                 Assert.AreEqual ("InternalWaitOne", frames [2].Method.Name, "#8.2");
3899                 Assert.AreEqual ("WaitOne", frames [3].Method.Name, "#8.3");
3900                 Assert.AreEqual ("WaitOne", frames [4].Method.Name, "#8.4");
3901                 Assert.AreEqual ("WaitOne", frames [5].Method.Name, "#8.5");
3902                 Assert.AreEqual ("wait_one", frames [6].Method.Name, "#8.6");
3903                 Assert.AreEqual ("Main", frames [7].Method.Name, "#8.7");
3904
3905                 var frame = frames [0];
3906                 Assert.IsTrue (frame.IsNativeTransition, "#11.1");
3907                 try {
3908                         frame.GetThis ();
3909                         Assert.Fail ("Known limitation - can't get info from m2n frames");
3910                 } catch (AbsentInformationException) {}
3911
3912                 frame = frames [3];
3913                 Assert.IsFalse (frame.IsNativeTransition, "#12.1");
3914                 var wait_one_this = frame.GetThis ();
3915                 Assert.IsNotNull (wait_one_this, "#12.2");
3916
3917                 frame = frames [6];
3918                 var locals = frame.GetVisibleVariables ();
3919                 Assert.AreEqual (1, locals.Count, "#13.1");
3920
3921                 var local_0 = frame.GetValue (locals [0]);
3922                 Assert.IsNotNull (local_0, "#13.2");
3923
3924                 Assert.AreEqual (wait_one_this, local_0, "#14.2");
3925         }
3926
3927         [Test]
3928         public void GetMethodBody () {
3929                 var bevent = run_until ("Main");
3930
3931                 var m = bevent.Method.DeclaringType.GetMethod ("get_IntProperty");
3932                 var body = m.GetMethodBody ();
3933                 foreach (var ins in body.Instructions) {
3934                         if (ins.OpCode == OpCodes.Ldfld) {
3935                                 var field = (FieldInfoMirror)ins.Operand;
3936                                 Assert.AreEqual ("field_i", field.Name);
3937                         }
3938                 }
3939         }
3940
3941         [Test]
3942         public void EvaluateMethod () {
3943                 var bevent = run_until ("evaluate_method_2");
3944
3945                 var m = bevent.Method.DeclaringType.GetMethod ("get_IntProperty");
3946
3947                 var this_obj = bevent.Thread.GetFrames ()[0].GetThis ();
3948                 var v = m.Evaluate (this_obj, null);
3949                 AssertValue (42, v);
3950         }
3951
3952         [Test]
3953         public void SetIP () {
3954                 var bevent = run_until ("set_ip_1");
3955
3956                 var invalid_loc = bevent.Thread.GetFrames ()[0].Location;
3957
3958                 var req = create_step (bevent);
3959                 var e = step_out ();
3960                 req.Disable ();
3961                 var frames = e.Thread.GetFrames ();
3962                 var locs = frames [0].Method.Locations;
3963                 var next_loc = locs.First (l => (l.LineNumber == frames [0].Location.LineNumber + 2));
3964
3965                 e.Thread.SetIP (next_loc);
3966
3967                 /* Check that i ++; j = 5; was skipped */
3968                 bevent = run_until ("set_ip_2");
3969                 var f = bevent.Thread.GetFrames ()[1];
3970                 AssertValue (2, f.GetValue (f.Method.GetLocal ("i")));
3971                 AssertValue (0, f.GetValue (f.Method.GetLocal ("j")));
3972
3973                 // Error handling
3974                 AssertThrows<ArgumentNullException> (delegate {
3975                                 e.Thread.SetIP (null);
3976                         });
3977
3978                 AssertThrows<ArgumentException> (delegate {
3979                                 e.Thread.SetIP (invalid_loc);
3980                         });
3981         }
3982
3983         [Test]
3984         public void SetIPSingleStep () {
3985                 // Check that single stepping after set-ip steps from the new ip
3986                 var bevent = run_until ("set_ip_1");
3987
3988                 var invalid_loc = bevent.Thread.GetFrames ()[0].Location;
3989
3990                 var req = create_step (bevent);
3991                 req.Size = StepSize.Line;
3992                 var e = step_out ();
3993                 req.Disable ();
3994                 var frames = e.Thread.GetFrames ();
3995                 var locs = frames [0].Method.Locations;
3996                 var prev_loc = locs.First (l => (l.LineNumber == frames [0].Location.LineNumber - 3));
3997                 AssertValue (2, frames [0].GetValue (frames [0].Method.GetLocal ("i")));
3998
3999                 // Set back the ip to the first i ++; line
4000                 e.Thread.SetIP (prev_loc);
4001
4002                 e = step_over ();
4003                 var f = e.Thread.GetFrames ()[0];
4004                 AssertValue (3, f.GetValue (f.Method.GetLocal ("i")));
4005         }
4006
4007         [Test]
4008         public void NewInstanceNoCtor () {
4009                 var bevent = run_until ("Main");
4010
4011                 var stype = bevent.Method.DeclaringType.Assembly.GetType ("AStruct");
4012                 var obj = stype.NewInstance ();
4013                 Assert.IsTrue (obj is ObjectMirror);
4014                 Assert.AreEqual ("AStruct", (obj as ObjectMirror).Type.Name);
4015         }
4016
4017         [Test]
4018         public void StaticCtorFilterInCctor () {
4019                 // Check that single stepping when in a cctor only ignores
4020                 // other cctors, not the current one
4021                 var bevent = run_until ("step_filters");
4022
4023                 var assembly = entry_point.DeclaringType.Assembly;
4024                 var type = assembly.GetType ("Tests/ClassWithCctor");
4025                 var cctor = type.GetMethod (".cctor");
4026                 vm.SetBreakpoint (cctor, 0);
4027
4028                 vm.Resume ();
4029                 var e = vm.GetNextEvent ();
4030                 Assert.IsTrue (e is BreakpointEvent);
4031
4032                 var req = create_step (e);
4033                 req.Filter = StepFilter.StaticCtor;
4034                 e = step_into ();
4035                 // Make sure we are still in the cctor
4036                 Assert.AreEqual (".cctor", e.Thread.GetFrames ()[0].Location.Method.Name);
4037         }
4038 }
4039
4040 }