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