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