2586a315eb4561e0147fb5b6739e4563f670ad07
[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
1054                 // Check hoisted scope information
1055                 var hoisted = (e as StepEvent).Method.GetHoistedScopes ();
1056                 Assert.AreEqual (2, hoisted.Length);
1057
1058                 e = step_out_await ("ss_await", e);//ss_await_1_exc (true, true).Wait ();//out
1059         }
1060
1061         Event step_in_await (string method, Event e)
1062         {
1063                 if (step_req != null)
1064                         step_req.Disable ();
1065                 create_step (e);
1066                 step_req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
1067                 var ef = step_into ();
1068                 assert_location (ef, method);
1069                 return ef;
1070         }
1071
1072         Event step_over_await (string method, Event e)
1073         {
1074                 if (step_req != null)
1075                         step_req.Disable ();
1076                 create_step (e);
1077                 step_req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
1078                 var ef = step_over ();
1079                 assert_location (ef, method);
1080                 return ef;
1081         }
1082
1083         Event step_out_await (string method, Event e)
1084         {
1085                 if (step_req != null)
1086                         step_req.Disable ();
1087                 create_step (e);
1088                 step_req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
1089                 var ef = step_out ();
1090                 assert_location (ef, method);
1091                 return ef;
1092         }
1093
1094         [Test]
1095         public void SingleSteppingNoFrames () {
1096                 //
1097                 // Test what happens when starting a single step operation on a thread
1098                 // with no managed frames
1099                 //
1100                 // Run a delegate on a tp thread
1101                 var e = run_until ("ss_no_frames_2");
1102
1103                 var this_type = e.Thread.GetFrames ()[0].Method.DeclaringType;
1104                 this_type.SetValue (this_type.GetField ("static_i"), vm.CreateValue (56));
1105
1106                 var thread = e.Thread;
1107                 var e2 = run_until ("ss_no_frames_3");
1108                 // The tp thread should be idle now
1109                 step_req = vm.CreateStepRequest (thread);
1110                 step_req.Depth = StepDepth.Over;
1111                 AssertThrows<Exception> (delegate {
1112                         step_req.Enable ();
1113                         });
1114         }
1115
1116         [Test]
1117         public void MethodEntryExit () {
1118                 run_until ("single_stepping");
1119
1120                 var req1 = vm.CreateMethodEntryRequest ();
1121                 var req2 = vm.CreateMethodExitRequest ();
1122
1123                 req1.Enable ();
1124                 req2.Enable ();
1125
1126                 vm.Resume ();
1127                 Event e = GetNextEvent ();
1128                 Assert.IsTrue (e is MethodEntryEvent);
1129                 Assert.AreEqual ("ss1", (e as MethodEntryEvent).Method.Name);
1130
1131                 vm.Resume ();
1132                 e = GetNextEvent ();
1133                 Assert.IsTrue (e is MethodExitEvent);
1134                 Assert.AreEqual ("ss1", (e as MethodExitEvent).Method.Name);
1135
1136                 req1.Disable ();
1137                 req2.Disable ();
1138         }
1139
1140         [Test]
1141         public void CountFilter () {
1142                 run_until ("single_stepping");
1143
1144                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("ss3");
1145                 Assert.IsNotNull (m2);
1146                 vm.SetBreakpoint (m2, 0);
1147
1148                 var req1 = vm.CreateMethodEntryRequest ();
1149                 req1.Count = 2;
1150                 req1.Enable ();
1151
1152                 // Enter ss2, ss1 is skipped
1153                 vm.Resume ();
1154                 Event e = GetNextEvent ();
1155                 Assert.IsTrue (e is MethodEntryEvent);
1156                 Assert.AreEqual ("ss2", (e as MethodEntryEvent).Method.Name);
1157
1158                 // Breakpoint on ss3, the entry event is no longer reported
1159                 vm.Resume ();
1160                 e = GetNextEvent ();
1161                 Assert.IsTrue (e is BreakpointEvent);
1162
1163                 req1.Disable ();
1164         }
1165
1166         [Test]
1167         public void Arguments () {
1168                 object val;
1169
1170                 var e = run_until ("arg1");
1171
1172                 StackFrame frame = e.Thread.GetFrames () [0];
1173
1174                 check_arg_val (frame, 0, typeof (sbyte), SByte.MaxValue - 5);
1175                 check_arg_val (frame, 1, typeof (byte), Byte.MaxValue - 5);
1176                 check_arg_val (frame, 2, typeof (bool), true);
1177                 check_arg_val (frame, 3, typeof (short), Int16.MaxValue - 5);
1178                 check_arg_val (frame, 4, typeof (ushort), UInt16.MaxValue - 5);
1179                 check_arg_val (frame, 5, typeof (char), 'F');
1180                 check_arg_val (frame, 6, typeof (int), Int32.MaxValue - 5);
1181                 check_arg_val (frame, 7, typeof (uint), UInt32.MaxValue - 5);
1182                 check_arg_val (frame, 8, typeof (long), Int64.MaxValue - 5);
1183                 check_arg_val (frame, 9, typeof (ulong), UInt64.MaxValue - 5);
1184                 check_arg_val (frame, 10, typeof (float), 1.2345f);
1185                 check_arg_val (frame, 11, typeof (double), 6.78910);
1186
1187                 e = run_until ("arg2");
1188
1189                 frame = e.Thread.GetFrames () [0];
1190
1191                 // String
1192                 val = frame.GetArgument (0);
1193                 AssertValue ("FOO", val);
1194                 Assert.AreEqual ("String", (val as ObjectMirror).Type.Name);
1195
1196                 // null
1197                 val = frame.GetArgument (1);
1198                 AssertValue (null, val);
1199
1200                 // object
1201                 val = frame.GetArgument (2);
1202                 AssertValue ("BLA", val);
1203
1204                 // byref
1205                 val = frame.GetArgument (3);
1206                 AssertValue (42, val);
1207
1208                 // generic instance
1209                 val = frame.GetArgument (4);
1210                 Assert.IsTrue (val is ObjectMirror);
1211                 Assert.AreEqual ("GClass`1", (val as ObjectMirror).Type.Name);
1212
1213                 // System.Object
1214                 val = frame.GetArgument (5);
1215                 Assert.IsTrue (val is ObjectMirror);
1216                 Assert.AreEqual ("Object", (val as ObjectMirror).Type.Name);
1217
1218                 // this on static methods
1219                 val = frame.GetThis ();
1220                 AssertValue (null, val);
1221
1222                 e = run_until ("arg3");
1223
1224                 frame = e.Thread.GetFrames () [0];
1225
1226                 // this
1227                 val = frame.GetThis ();
1228                 Assert.IsTrue (val is ObjectMirror);
1229                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
1230
1231                 // objref in register
1232                 val = frame.GetArgument (0);
1233                 AssertValue ("BLA", val);
1234         }
1235
1236         [Test]
1237         public void Arrays () {
1238                 object val;
1239
1240                 var e = run_until ("o2");
1241
1242                 StackFrame frame = e.Thread.GetFrames () [0];
1243
1244                 // String[]
1245                 val = frame.GetArgument (0);
1246                 Assert.IsTrue (val is ArrayMirror);
1247                 ArrayMirror arr = val as ArrayMirror;
1248                 Assert.AreEqual (2, arr.Length);
1249                 AssertValue ("BAR", arr [0]);
1250                 AssertValue ("BAZ", arr [1]);
1251
1252                 var vals = arr.GetValues (0, 2);
1253                 Assert.AreEqual (2, vals.Count);
1254                 AssertValue ("BAR", vals [0]);
1255                 AssertValue ("BAZ", vals [1]);
1256
1257                 arr [0] = vm.RootDomain.CreateString ("ABC");
1258                 AssertValue ("ABC", arr [0]);
1259
1260                 arr [0] = vm.CreateValue (null);
1261                 AssertValue (null, arr [0]);
1262
1263                 arr.SetValues (0, new Value [] { vm.RootDomain.CreateString ("D1"), vm.RootDomain.CreateString ("D2") });
1264                 AssertValue ("D1", arr [0]);
1265                 AssertValue ("D2", arr [1]);
1266
1267                 // int
1268                 val = frame.GetArgument (1);
1269                 Assert.IsTrue (val is ArrayMirror);
1270                 arr = val as ArrayMirror;
1271                 Assert.AreEqual (2, arr.Length);
1272                 AssertValue (42, arr [0]);
1273                 AssertValue (43, arr [1]);
1274
1275                 // Argument checking
1276                 AssertThrows<IndexOutOfRangeException> (delegate () {
1277                                 val = arr [2];
1278                         });
1279
1280                 AssertThrows<IndexOutOfRangeException> (delegate () {
1281                                 val = arr [Int32.MinValue];
1282                         });
1283
1284                 AssertThrows<IndexOutOfRangeException> (delegate () {
1285                                 vals = arr.GetValues (0, 3);
1286                         });
1287
1288                 AssertThrows<IndexOutOfRangeException> (delegate () {
1289                                 arr [2] = vm.CreateValue (null);
1290                         });
1291
1292                 AssertThrows<IndexOutOfRangeException> (delegate () {
1293                                 arr [Int32.MinValue] = vm.CreateValue (null);
1294                         });
1295
1296                 AssertThrows<IndexOutOfRangeException> (delegate () {
1297                                 arr.SetValues (0, new Value [] { null, null, null });
1298                         });
1299
1300                 // Multidim arrays
1301                 val = frame.GetArgument (2);
1302                 Assert.IsTrue (val is ArrayMirror);
1303                 arr = val as ArrayMirror;
1304                 Assert.AreEqual (2, arr.Rank);
1305                 Assert.AreEqual (4, arr.Length);
1306                 Assert.AreEqual (2, arr.GetLength (0));
1307                 Assert.AreEqual (2, arr.GetLength (1));
1308                 Assert.AreEqual (0, arr.GetLowerBound (0));
1309                 Assert.AreEqual (0, arr.GetLowerBound (1));
1310                 vals = arr.GetValues (0, 4);
1311                 AssertValue (1, vals [0]);
1312                 AssertValue (2, vals [1]);
1313                 AssertValue (3, vals [2]);
1314                 AssertValue (4, vals [3]);
1315
1316                 val = frame.GetArgument (3);
1317                 Assert.IsTrue (val is ArrayMirror);
1318                 arr = val as ArrayMirror;
1319                 Assert.AreEqual (2, arr.Rank);
1320                 Assert.AreEqual (4, arr.Length);
1321                 Assert.AreEqual (2, arr.GetLength (0));
1322                 Assert.AreEqual (2, arr.GetLength (1));
1323                 Assert.AreEqual (1, arr.GetLowerBound (0));
1324                 Assert.AreEqual (3, arr.GetLowerBound (1));
1325
1326                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
1327                                 arr.GetLength (-1);
1328                         });
1329                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
1330                                 arr.GetLength (2);
1331                         });
1332
1333                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
1334                                 arr.GetLowerBound (-1);
1335                         });
1336                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
1337                                 arr.GetLowerBound (2);
1338                         });
1339
1340                 // arrays treated as generic collections
1341                 val = frame.GetArgument (4);
1342                 Assert.IsTrue (val is ArrayMirror);
1343                 arr = val as ArrayMirror;
1344         }
1345
1346         [Test]
1347         public void Object_GetValue () {
1348                 var e = run_until ("o1");
1349                 var frame = e.Thread.GetFrames () [0];
1350
1351                 object val = frame.GetThis ();
1352                 Assert.IsTrue (val is ObjectMirror);
1353                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
1354                 ObjectMirror o = (val as ObjectMirror);
1355
1356                 TypeMirror t = o.Type;
1357
1358                 // object fields
1359                 object f = o.GetValue (t.GetField ("field_i"));
1360                 AssertValue (42, f);
1361                 f = o.GetValue (t.GetField ("field_s"));
1362                 AssertValue ("S", f);
1363                 f = o.GetValue (t.GetField ("field_enum"));
1364                 Assert.IsTrue (f is EnumMirror);
1365                 Assert.AreEqual (1, (f as EnumMirror).Value);
1366                 Assert.AreEqual ("B", (f as EnumMirror).StringValue);
1367
1368                 // Inherited object fields
1369                 TypeMirror parent = t.BaseType;
1370                 f = o.GetValue (parent.GetField ("base_field_i"));
1371                 AssertValue (43, f);
1372                 f = o.GetValue (parent.GetField ("base_field_s"));
1373                 AssertValue ("T", f);
1374
1375                 // Static fields
1376                 f = o.GetValue (o.Type.GetField ("static_i"));
1377                 AssertValue (55, f);
1378
1379                 // generic instances
1380                 ObjectMirror o2 = frame.GetValue (frame.Method.GetParameters ()[1]) as ObjectMirror;
1381                 Assert.AreEqual ("GClass`1", o2.Type.Name);
1382                 TypeMirror t2 = o2.Type;
1383                 f = o2.GetValue (t2.GetField ("field"));
1384                 AssertValue (42, f);
1385
1386                 ObjectMirror o3 = frame.GetValue (frame.Method.GetParameters ()[2]) as ObjectMirror;
1387                 Assert.AreEqual ("GClass`1", o3.Type.Name);
1388                 TypeMirror t3 = o3.Type;
1389                 f = o3.GetValue (t3.GetField ("field"));
1390                 AssertValue ("FOO", f);
1391
1392                 // Argument checking
1393                 AssertThrows<ArgumentNullException> (delegate () {
1394                         o.GetValue (null);
1395                         });
1396         }
1397
1398         [Test]
1399         public void Object_GetValues () {
1400                 var e = run_until ("o1");
1401                 var frame = e.Thread.GetFrames () [0];
1402
1403                 object val = frame.GetThis ();
1404                 Assert.IsTrue (val is ObjectMirror);
1405                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
1406                 ObjectMirror o = (val as ObjectMirror);
1407
1408                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1409
1410                 TypeMirror t = o.Type;
1411
1412                 object[] vals = o.GetValues (new FieldInfoMirror [] { t.GetField ("field_i"), t.GetField ("field_s") });
1413                 object f = vals [0];
1414                 AssertValue (42, f);
1415                 f = vals [1];
1416                 AssertValue ("S", f);
1417
1418                 // Argument checking
1419                 AssertThrows<ArgumentNullException> (delegate () {
1420                         o.GetValues (null);
1421                         });
1422
1423                 AssertThrows<ArgumentNullException> (delegate () {
1424                         o.GetValues (new FieldInfoMirror [] { null });
1425                         });
1426
1427                 // field of another class
1428                 AssertThrows<ArgumentException> (delegate () {
1429                                 o.GetValue (val2.Type.GetField ("field_j"));
1430                         });
1431         }
1432
1433         void TestSetValue (ObjectMirror o, string field_name, object val) {
1434                 if (val is string)
1435                         o.SetValue (o.Type.GetField (field_name), vm.RootDomain.CreateString ((string)val));
1436                 else
1437                         o.SetValue (o.Type.GetField (field_name), vm.CreateValue (val));
1438                 Value f = o.GetValue (o.Type.GetField (field_name));
1439                 AssertValue (val, f);
1440         }
1441
1442         [Test]
1443         public void Object_SetValues () {
1444                 var e = run_until ("o1");
1445                 var frame = e.Thread.GetFrames () [0];
1446
1447                 object val = frame.GetThis ();
1448                 Assert.IsTrue (val is ObjectMirror);
1449                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
1450                 ObjectMirror o = (val as ObjectMirror);
1451
1452                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1453
1454                 TestSetValue (o, "field_i", 22);
1455                 TestSetValue (o, "field_bool1", false);
1456                 TestSetValue (o, "field_bool2", true);
1457                 TestSetValue (o, "field_char", 'B');
1458                 TestSetValue (o, "field_byte", (byte)129);
1459                 TestSetValue (o, "field_sbyte", (sbyte)-33);
1460                 TestSetValue (o, "field_short", (short)(Int16.MaxValue - 5));
1461                 TestSetValue (o, "field_ushort", (ushort)(UInt16.MaxValue - 5));
1462                 TestSetValue (o, "field_long", Int64.MaxValue - 5);
1463                 TestSetValue (o, "field_ulong", (ulong)(UInt64.MaxValue - 5));
1464                 TestSetValue (o, "field_float", 6.28f);
1465                 TestSetValue (o, "field_double", 6.28);
1466                 TestSetValue (o, "static_i", 23);
1467                 TestSetValue (o, "field_s", "CDEF");
1468
1469                 Value f;
1470
1471                 // intptrs
1472                 f = o.GetValue (o.Type.GetField ("field_intptr"));
1473                 Assert.IsInstanceOfType (typeof (StructMirror), f);
1474                 AssertValue (Int32.MaxValue - 5, (f as StructMirror).Fields [0]);
1475
1476                 // enums
1477                 FieldInfoMirror field = o.Type.GetField ("field_enum");
1478                 f = o.GetValue (field);
1479                 (f as EnumMirror).Value = 5;
1480                 o.SetValue (field, f);
1481                 f = o.GetValue (field);
1482                 Assert.AreEqual (5, (f as EnumMirror).Value);
1483
1484                 // null
1485                 o.SetValue (o.Type.GetField ("field_s"), vm.CreateValue (null));
1486                 f = o.GetValue (o.Type.GetField ("field_s"));
1487                 AssertValue (null, f);
1488
1489                 // vtype instances
1490                 field = o.Type.GetField ("generic_field_struct");
1491                 f = o.GetValue (field);
1492                 o.SetValue (field, f);
1493
1494                 // nullables
1495                 field = o.Type.GetField ("field_nullable");
1496                 f = o.GetValue (field);
1497                 AssertValue (0, (f as StructMirror).Fields [0]);
1498                 AssertValue (false, (f as StructMirror).Fields [1]);
1499                 o.SetValue (field, vm.CreateValue (6));
1500                 f = o.GetValue (field);
1501                 AssertValue (6, (f as StructMirror).Fields [0]);
1502                 AssertValue (true, (f as StructMirror).Fields [1]);
1503                 o.SetValue (field, vm.CreateValue (null));
1504                 f = o.GetValue (field);
1505                 AssertValue (0, (f as StructMirror).Fields [0]);
1506                 AssertValue (false, (f as StructMirror).Fields [1]);
1507
1508                 // Argument checking
1509                 AssertThrows<ArgumentNullException> (delegate () {
1510                                 o.SetValues (null, new Value [0]);
1511                         });
1512
1513                 AssertThrows<ArgumentNullException> (delegate () {
1514                                 o.SetValues (new FieldInfoMirror [0], null);
1515                         });
1516
1517                 AssertThrows<ArgumentNullException> (delegate () {
1518                                 o.SetValues (new FieldInfoMirror [] { null }, new Value [1] { null });
1519                         });
1520
1521                 // vtype with a wrong type
1522                 AssertThrows<ArgumentException> (delegate () {
1523                                 o.SetValue (o.Type.GetField ("field_struct"), o.GetValue (o.Type.GetField ("field_enum")));
1524                         });
1525
1526                 // reference type not assignment compatible
1527                 AssertThrows<ArgumentException> (delegate () {
1528                                 o.SetValue (o.Type.GetField ("field_class"), o);
1529                         });
1530
1531                 // field of another class
1532                 AssertThrows<ArgumentException> (delegate () {
1533                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
1534                         });
1535         }
1536
1537         [Test]
1538         public void Type_SetValue () {
1539                 var e = run_until ("o1");
1540                 var frame = e.Thread.GetFrames () [0];
1541                 Value f;
1542
1543                 object val = frame.GetThis ();
1544                 Assert.IsTrue (val is ObjectMirror);
1545                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
1546                 ObjectMirror o = (val as ObjectMirror);
1547
1548                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1549
1550                 o.Type.SetValue (o.Type.GetField ("static_i"), vm.CreateValue (55));
1551                 f = o.Type.GetValue (o.Type.GetField ("static_i"));
1552                 AssertValue (55, f);
1553
1554                 o.Type.SetValue (o.Type.GetField ("static_s"), vm.RootDomain.CreateString ("B"));
1555                 f = o.Type.GetValue (o.Type.GetField ("static_s"));
1556                 AssertValue ("B", f);
1557
1558                 // Argument checking
1559                 AssertThrows<ArgumentNullException> (delegate () {
1560                                 o.Type.SetValue (null, vm.CreateValue (0));
1561                         });
1562
1563                 AssertThrows<ArgumentNullException> (delegate () {
1564                                 o.Type.SetValue (o.Type.GetField ("static_i"), null);
1565                         });
1566
1567                 // field of another class
1568                 AssertThrows<ArgumentException> (delegate () {
1569                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
1570                         });
1571         }
1572
1573         [Test]
1574         public void TypeInfo () {
1575                 Event e = run_until ("ti2");
1576                 StackFrame frame = e.Thread.GetFrames () [0];
1577
1578                 TypeMirror t;
1579
1580                 // Array types
1581                 t = frame.Method.GetParameters ()[0].ParameterType;
1582
1583                 Assert.AreEqual ("String[]", t.Name);
1584                 Assert.AreEqual ("string[]", t.CSharpName);
1585                 Assert.AreEqual ("Array", t.BaseType.Name);
1586                 Assert.AreEqual (true, t.HasElementType);
1587                 Assert.AreEqual (true, t.IsArray);
1588                 Assert.AreEqual (1, t.GetArrayRank ());
1589                 Assert.AreEqual ("String", t.GetElementType ().Name);
1590
1591                 t = frame.Method.GetParameters ()[2].ParameterType;
1592
1593                 Assert.AreEqual ("Int32[,]", t.Name);
1594                 // FIXME:
1595                 //Assert.AreEqual ("int[,]", t.CSharpName);
1596                 Assert.AreEqual ("Array", t.BaseType.Name);
1597                 Assert.AreEqual (true, t.HasElementType);
1598                 Assert.AreEqual (true, t.IsArray);
1599                 Assert.AreEqual (2, t.GetArrayRank ());
1600                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
1601
1602                 // Byref types
1603                 t = frame.Method.GetParameters ()[3].ParameterType;
1604                 // FIXME:
1605                 //Assert.AreEqual ("Int32&", t.Name);
1606                 //Assert.AreEqual (true, t.IsByRef);
1607                 //Assert.AreEqual (true, t.HasElementType);
1608
1609                 // Pointer types
1610                 t = frame.Method.GetParameters ()[4].ParameterType;
1611                 // FIXME:
1612                 //Assert.AreEqual ("Int32*", t.Name);
1613                 Assert.AreEqual (true, t.IsPointer);
1614                 Assert.AreEqual (true, t.HasElementType);
1615                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
1616                 Assert.AreEqual (false, t.IsPrimitive);
1617
1618                 // primitive types 
1619                 t = frame.Method.GetParameters ()[5].ParameterType;
1620                 Assert.AreEqual (true, t.IsPrimitive);
1621
1622                 // value types
1623                 t = frame.Method.GetParameters ()[6].ParameterType;
1624                 Assert.AreEqual ("AStruct", t.Name);
1625                 Assert.AreEqual (false, t.IsPrimitive);
1626                 Assert.AreEqual (true, t.IsValueType);
1627                 Assert.AreEqual (false, t.IsClass);
1628
1629                 // reference types
1630                 t = frame.Method.GetParameters ()[7].ParameterType;
1631                 Assert.AreEqual ("Tests", t.Name);
1632                 var nested = (from nt in t.GetNestedTypes () where nt.IsNestedPublic select nt).ToArray ();
1633                 Assert.AreEqual (1, nested.Length);
1634                 Assert.AreEqual ("NestedClass", nested [0].Name);
1635                 Assert.IsTrue (t.BaseType.IsAssignableFrom (t));
1636                 Assert.IsTrue (!t.IsAssignableFrom (t.BaseType));
1637
1638                 // generic instances
1639                 t = frame.Method.GetParameters ()[9].ParameterType;
1640                 Assert.AreEqual ("GClass`1", t.Name);
1641                 Assert.IsTrue (t.IsGenericType);
1642                 Assert.IsFalse (t.IsGenericTypeDefinition);
1643
1644                 var args = t.GetGenericArguments ();
1645                 Assert.AreEqual (1, args.Length);
1646                 Assert.AreEqual ("Int32", args [0].Name);
1647
1648                 // generic type definitions
1649                 var gtd = t.GetGenericTypeDefinition ();
1650                 Assert.AreEqual ("GClass`1", gtd.Name);
1651                 Assert.IsTrue (gtd.IsGenericType);
1652                 Assert.IsTrue (gtd.IsGenericTypeDefinition);
1653                 Assert.AreEqual (gtd, gtd.GetGenericTypeDefinition ());
1654
1655                 args = gtd.GetGenericArguments ();
1656                 Assert.AreEqual (1, args.Length);
1657                 Assert.AreEqual ("T", args [0].Name);
1658
1659                 // enums
1660                 t = frame.Method.GetParameters ()[10].ParameterType;
1661                 Assert.AreEqual ("AnEnum", t.Name);
1662                 Assert.IsTrue (t.IsEnum);
1663                 Assert.AreEqual ("Int32", t.EnumUnderlyingType.Name);
1664
1665                 // TypedReferences
1666                 t = frame.Method.GetParameters ()[11].ParameterType;
1667                 Assert.AreEqual ("TypedReference", t.Name);
1668
1669                 // properties
1670                 t = frame.Method.GetParameters ()[7].ParameterType;
1671
1672                 var props = t.GetProperties ();
1673                 Assert.AreEqual (3, props.Length);
1674                 foreach (PropertyInfoMirror prop in props) {
1675                         ParameterInfoMirror[] indexes = prop.GetIndexParameters ();
1676
1677                         if (prop.Name == "IntProperty") {
1678                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1679                                 Assert.AreEqual ("get_IntProperty", prop.GetGetMethod ().Name);
1680                                 Assert.AreEqual ("set_IntProperty", prop.GetSetMethod ().Name);
1681                                 Assert.AreEqual (0, indexes.Length);
1682                         } else if (prop.Name == "ReadOnlyProperty") {
1683                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1684                                 Assert.AreEqual ("get_ReadOnlyProperty", prop.GetGetMethod ().Name);
1685                                 Assert.AreEqual (null, prop.GetSetMethod ());
1686                                 Assert.AreEqual (0, indexes.Length);
1687                         } else if (prop.Name == "IndexedProperty") {
1688                                 Assert.AreEqual (1, indexes.Length);
1689                                 Assert.AreEqual ("Int32", indexes [0].ParameterType.Name);
1690                         }
1691                 }
1692
1693                 // custom attributes
1694                 t = frame.Method.GetParameters ()[8].ParameterType;
1695                 Assert.AreEqual ("Tests2", t.Name);
1696                 var attrs = t.GetCustomAttributes (true);
1697                 Assert.AreEqual (5, attrs.Length);
1698                 foreach (var attr in attrs) {
1699                         if (attr.Constructor.DeclaringType.Name == "DebuggerDisplayAttribute") {
1700                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1701                                 Assert.AreEqual ("Tests", attr.ConstructorArguments [0].Value);
1702                                 Assert.AreEqual (2, attr.NamedArguments.Count);
1703                                 Assert.AreEqual ("Name", attr.NamedArguments [0].Property.Name);
1704                                 Assert.AreEqual ("FOO", attr.NamedArguments [0].TypedValue.Value);
1705                                 Assert.AreEqual ("Target", attr.NamedArguments [1].Property.Name);
1706                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.NamedArguments [1].TypedValue.Value);
1707                                 Assert.AreEqual ("Int32", (attr.NamedArguments [1].TypedValue.Value as TypeMirror).Name);
1708                         } else if (attr.Constructor.DeclaringType.Name == "DebuggerTypeProxyAttribute") {
1709                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1710                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.ConstructorArguments [0].Value);
1711                                 Assert.AreEqual ("Tests", (attr.ConstructorArguments [0].Value as TypeMirror).Name);
1712                         } else if (attr.Constructor.DeclaringType.Name == "BAttribute") {
1713                                 Assert.AreEqual (2, attr.NamedArguments.Count);
1714                                 Assert.AreEqual ("afield", attr.NamedArguments [0].Field.Name);
1715                                 Assert.AreEqual ("bfield", attr.NamedArguments [1].Field.Name);
1716                         } else if (attr.Constructor.DeclaringType.Name == "ClassInterfaceAttribute") {
1717                                 // inherited from System.Object
1718                                 //} else if (attr.Constructor.DeclaringType.Name == "Serializable") {
1719                                 // inherited from System.Object
1720                         } else if (attr.Constructor.DeclaringType.Name == "ComVisibleAttribute") {
1721                                 // inherited from System.Object
1722                         } else {
1723                                 Assert.Fail (attr.Constructor.DeclaringType.Name);
1724                         }
1725                 }
1726
1727                 var assembly = entry_point.DeclaringType.Assembly;
1728                 var type = assembly.GetType ("Tests4");
1729                 Assert.IsFalse (type.IsInitialized);
1730         }
1731
1732         [Test]
1733         public void FieldInfo () {
1734                 Event e = run_until ("ti2");
1735                 StackFrame frame = e.Thread.GetFrames () [0];
1736
1737                 TypeMirror t;
1738
1739                 t = frame.Method.GetParameters ()[8].ParameterType;
1740                 Assert.AreEqual ("Tests2", t.Name);
1741
1742                 var fi = t.GetField ("field_j");
1743                 var attrs = fi.GetCustomAttributes (true);
1744                 Assert.AreEqual (1, attrs.Length);
1745                 var attr = attrs [0];
1746                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1747                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1748                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1749                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1750         }
1751
1752         [Test]
1753         public void PropertyInfo () {
1754                 Event e = run_until ("ti2");
1755                 StackFrame frame = e.Thread.GetFrames () [0];
1756
1757                 TypeMirror t;
1758
1759                 t = frame.Method.GetParameters ()[8].ParameterType;
1760                 Assert.AreEqual ("Tests2", t.Name);
1761
1762                 var pi = t.GetProperty ("AProperty");
1763                 var attrs = pi.GetCustomAttributes (true);
1764                 Assert.AreEqual (1, attrs.Length);
1765                 var attr = attrs [0];
1766                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1767                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1768                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1769                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1770         }
1771
1772         [Test]
1773         [Category ("only5")]
1774         public void Type_GetValue () {
1775                 Event e = run_until ("o1");
1776                 StackFrame frame = e.Thread.GetFrames () [0];
1777
1778                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1779
1780                 TypeMirror t = o.Type;
1781
1782                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1783
1784                 // static fields
1785                 object f = t.GetValue (o.Type.GetField ("static_i"));
1786                 AssertValue (55, f);
1787
1788                 f = t.GetValue (o.Type.GetField ("static_s"));
1789                 AssertValue ("A", f);
1790
1791                 // literal static fields
1792                 f = t.GetValue (o.Type.GetField ("literal_i"));
1793                 AssertValue (56, f);
1794
1795                 f = t.GetValue (o.Type.GetField ("literal_s"));
1796                 AssertValue ("B", f);
1797
1798                 // Inherited static fields
1799                 TypeMirror parent = t.BaseType;
1800                 f = t.GetValue (parent.GetField ("base_static_i"));
1801                 AssertValue (57, f);
1802
1803                 f = t.GetValue (parent.GetField ("base_static_s"));
1804                 AssertValue ("C", f);
1805
1806                 // thread static field
1807                 f = t.GetValue (t.GetField ("tls_i"), e.Thread);
1808                 AssertValue (42, f);
1809
1810                 // Argument checking
1811                 AssertThrows<ArgumentNullException> (delegate () {
1812                         t.GetValue (null);
1813                         });
1814
1815                 // instance fields
1816                 AssertThrows<ArgumentException> (delegate () {
1817                         t.GetValue (o.Type.GetField ("field_i"));
1818                         });
1819
1820                 // field on another type
1821                 AssertThrows<ArgumentException> (delegate () {
1822                                 t.GetValue (val2.Type.GetField ("static_field_j"));
1823                         });
1824
1825                 // special static field
1826                 AssertThrows<ArgumentException> (delegate () {
1827                                 t.GetValue (t.GetField ("tls_i"));
1828                         });
1829         }
1830
1831         [Test]
1832         public void Type_GetValues () {
1833                 Event e = run_until ("o1");
1834                 StackFrame frame = e.Thread.GetFrames () [0];
1835
1836                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1837
1838                 TypeMirror t = o.Type;
1839
1840                 // static fields
1841                 object[] vals = t.GetValues (new FieldInfoMirror [] { t.GetField ("static_i"), t.GetField ("static_s") });
1842                 object f = vals [0];
1843                 AssertValue (55, f);
1844
1845                 f = vals [1];
1846                 AssertValue ("A", f);
1847
1848                 // Argument checking
1849                 AssertThrows<ArgumentNullException> (delegate () {
1850                         t.GetValues (null);
1851                         });
1852
1853                 AssertThrows<ArgumentNullException> (delegate () {
1854                         t.GetValues (new FieldInfoMirror [] { null });
1855                         });
1856         }
1857
1858         [Test]
1859         public void ObjRefs () {
1860                 Event e = run_until ("objrefs1");
1861                 StackFrame frame = e.Thread.GetFrames () [0];
1862
1863                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1864                 ObjectMirror child = o.GetValue (o.Type.GetField ("child")) as ObjectMirror;
1865
1866                 Assert.IsTrue (child.Address != 0);
1867
1868                 // Check that object references are internalized correctly
1869                 Assert.AreEqual (o, frame.GetThis ());
1870
1871                 run_until ("objrefs2");
1872
1873                 // child should be gc'd now
1874                 // This is not deterministic
1875                 //Assert.IsTrue (child.IsCollected);
1876
1877                 /*
1878                  * No longer works since Type is read eagerly
1879                  */
1880                 /*
1881                 AssertThrows<ObjectCollectedException> (delegate () {
1882                         TypeMirror t = child.Type;
1883                         });
1884                 */
1885                 /*
1886                 AssertThrows<ObjectCollectedException> (delegate () {
1887                                 long addr = child.Address;
1888                         });
1889                 */
1890         }
1891
1892         [Test]
1893         public void Type_GetObject () {
1894                 Event e = run_until ("o1");
1895                 StackFrame frame = e.Thread.GetFrames () [0];
1896
1897                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1898
1899                 TypeMirror t = o.Type;
1900
1901                 Assert.AreEqual ("RuntimeType", t.GetTypeObject ().Type.Name);
1902         }
1903
1904         [Test]
1905         public void VTypes () {
1906                 Event e = run_until ("vtypes1");
1907                 StackFrame frame = e.Thread.GetFrames () [0];
1908
1909                 // vtypes as fields
1910                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1911                 var obj = o.GetValue (o.Type.GetField ("field_struct"));
1912                 Assert.IsTrue (obj is StructMirror);
1913                 var s = obj as StructMirror;
1914                 Assert.AreEqual ("AStruct", s.Type.Name);
1915                 AssertValue (42, s ["i"]);
1916                 obj = s ["s"];
1917                 AssertValue ("S", obj);
1918                 AssertValue (43, s ["k"]);
1919                 obj = o.GetValue (o.Type.GetField ("field_boxed_struct"));
1920                 Assert.IsTrue (obj is StructMirror);
1921                 s = obj as StructMirror;
1922                 Assert.AreEqual ("AStruct", s.Type.Name);
1923                 AssertValue (42, s ["i"]);
1924
1925                 // Check decoding of nested structs (#14942)
1926                 obj = o.GetValue (o.Type.GetField ("nested_struct"));
1927                 o.SetValue (o.Type.GetField ("nested_struct"), obj);
1928
1929                 // Check round tripping of boxed struct fields (#12354)
1930                 obj = o.GetValue (o.Type.GetField ("boxed_struct_field"));
1931                 o.SetValue (o.Type.GetField ("boxed_struct_field"), obj);
1932                 obj = o.GetValue (o.Type.GetField ("boxed_struct_field"));
1933                 s = obj as StructMirror;
1934                 AssertValue (1, s ["key"]);
1935                 obj = s ["value"];
1936                 Assert.IsTrue (obj is StructMirror);
1937                 s = obj as StructMirror;
1938                 AssertValue (42, s ["m_value"]);
1939
1940                 // vtypes as arguments
1941                 s = frame.GetArgument (0) as StructMirror;
1942                 AssertValue (44, s ["i"]);
1943                 obj = s ["s"];
1944                 AssertValue ("T", obj);
1945                 AssertValue (45, s ["k"]);
1946
1947                 // vtypes as array entries
1948                 var arr = frame.GetArgument (1) as ArrayMirror;
1949                 obj = arr [0];
1950                 Assert.IsTrue (obj is StructMirror);
1951                 s = obj as StructMirror;
1952                 AssertValue (1, s ["i"]);
1953                 AssertValue ("S1", s ["s"]);
1954                 obj = arr [1];
1955                 Assert.IsTrue (obj is StructMirror);
1956                 s = obj as StructMirror;
1957                 AssertValue (2, s ["i"]);
1958                 AssertValue ("S2", s ["s"]);
1959
1960                 // typedbyref
1961                 var typedref = frame.GetArgument (2) as StructMirror;
1962                 Assert.IsTrue (typedref is StructMirror);
1963
1964                 // Argument checking
1965                 s = frame.GetArgument (0) as StructMirror;
1966                 AssertThrows<ArgumentException> (delegate () {
1967                                 obj = s ["FOO"];
1968                         });
1969
1970                 // generic vtype instances
1971                 o = frame.GetThis () as ObjectMirror;
1972                 obj = o.GetValue (o.Type.GetField ("generic_field_struct"));
1973                 Assert.IsTrue (obj is StructMirror);
1974                 s = obj as StructMirror;
1975                 Assert.AreEqual ("GStruct`1", s.Type.Name);
1976                 AssertValue (42, s ["i"]);
1977
1978                 // this on vtype methods
1979                 e = run_until ("vtypes2");
1980                 e = step_until (e.Thread, "foo");
1981
1982                 frame = e.Thread.GetFrames () [0];
1983
1984                 Assert.AreEqual ("foo", (e as StepEvent).Method.Name);
1985                 obj = frame.GetThis ();
1986
1987                 Assert.IsTrue (obj is StructMirror);
1988                 s = obj as StructMirror;
1989                 AssertValue (44, s ["i"]);
1990                 AssertValue ("T", s ["s"]);
1991                 AssertValue (45, s ["k"]);
1992
1993                 // Test SetThis ()
1994                 s ["i"] = vm.CreateValue (55);
1995                 frame.SetThis (s);
1996                 obj = frame.GetThis ();
1997                 Assert.IsTrue (obj is StructMirror);
1998                 s = obj as StructMirror;
1999                 AssertValue (55, s ["i"]);
2000                 AssertValue ("T", s ["s"]);
2001                 AssertValue (45, s ["k"]);
2002
2003                 // this on static vtype methods
2004                 e = run_until ("vtypes3");
2005                 e = step_until (e.Thread, "static_foo");
2006
2007                 frame = e.Thread.GetFrames () [0];
2008
2009                 Assert.AreEqual ("static_foo", (e as StepEvent).Method.Name);
2010                 obj = frame.GetThis ();
2011                 AssertValue (null, obj);
2012
2013                 // vtypes which reference themselves recursively
2014                 e = run_until ("vtypes4_2");
2015                 frame = e.Thread.GetFrames () [0];
2016
2017                 Assert.IsTrue (frame.GetArgument (0) is StructMirror);
2018         }
2019
2020         [Test]
2021         public void AssemblyInfo () {
2022                 Event e = run_until ("single_stepping");
2023
2024                 StackFrame frame = e.Thread.GetFrames () [0];
2025
2026                 var aname = frame.Method.DeclaringType.Assembly.GetName ();
2027                 Assert.AreEqual ("dtest-app, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", aname.ToString ());
2028
2029                 ModuleMirror m = frame.Method.DeclaringType.Module;
2030
2031                 Assert.AreEqual ("dtest-app.exe", m.Name);
2032                 Assert.AreEqual ("dtest-app.exe", m.ScopeName);
2033                 Assert.IsTrue (m.FullyQualifiedName.IndexOf ("dtest-app.exe") != -1);
2034                 Guid guid = m.ModuleVersionId;
2035                 Assert.AreEqual (frame.Method.DeclaringType.Assembly, m.Assembly);
2036                 Assert.AreEqual (frame.Method.DeclaringType.Assembly.ManifestModule, m);
2037
2038                 // This is no longer true on 4.0
2039                 //Assert.AreEqual ("Assembly", frame.Method.DeclaringType.Assembly.GetAssemblyObject ().Type.Name);
2040
2041                 TypeMirror t = vm.RootDomain.Corlib.GetType ("System.Diagnostics.DebuggerDisplayAttribute");
2042                 Assert.AreEqual ("DebuggerDisplayAttribute", t.Name);
2043         }
2044
2045         [Test]
2046         public void LocalsInfo () {
2047                 Event e = run_until ("locals2");
2048
2049                 StackFrame frame = e.Thread.GetFrames () [0];
2050
2051                 var locals = frame.Method.GetLocals ();
2052                 Assert.AreEqual (9, locals.Length);
2053                 for (int i = 0; i < 9; ++i) {
2054                         if (locals [i].Name == "args") {
2055                                 Assert.IsTrue (locals [i].IsArg);
2056                                 Assert.AreEqual ("String[]", locals [i].Type.Name);
2057                         } else if (locals [i].Name == "arg") {
2058                                 Assert.IsTrue (locals [i].IsArg);
2059                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
2060                         } else if (locals [i].Name == "i") {
2061                                 Assert.IsFalse (locals [i].IsArg);
2062                                 Assert.AreEqual ("Int64", locals [i].Type.Name);
2063                         } else if (locals [i].Name == "j") {
2064                                 Assert.IsFalse (locals [i].IsArg);
2065                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
2066                         } else if (locals [i].Name == "s") {
2067                                 Assert.IsFalse (locals [i].IsArg);
2068                                 Assert.AreEqual ("String", locals [i].Type.Name);
2069                         } else if (locals [i].Name == "t") {
2070                                 // gshared
2071                                 Assert.IsTrue (locals [i].IsArg);
2072                                 Assert.AreEqual ("String", locals [i].Type.Name);
2073                         } else if (locals [i].Name == "rs") {
2074                                 Assert.IsTrue (locals [i].IsArg);
2075                                 Assert.AreEqual ("String", locals [i].Type.Name);
2076                         } else if (locals [i].Name == "astruct") {
2077                         } else if (locals [i].Name == "alist") {
2078                         } else {
2079                                 Assert.Fail ();
2080                         }
2081                 }
2082
2083                 var scopes = frame.Method.GetScopes ();
2084                 Assert.AreEqual (2, scopes.Length);
2085         }
2086
2087         Event step_once () {
2088                 vm.Resume ();
2089                 var e = GetNextEvent ();
2090                 Assert.IsTrue (e is StepEvent);
2091                 return e;
2092         }
2093
2094         Event step_into () {
2095                 step_req.Disable ();
2096                 step_req.Depth = StepDepth.Into;
2097                 step_req.Enable ();
2098                 return step_once ();
2099         }
2100
2101         Event step_over () {
2102                 step_req.Disable ();
2103                 step_req.Depth = StepDepth.Over;
2104                 step_req.Enable ();
2105                 return step_once ();
2106         }
2107
2108         Event step_out () {
2109                 step_req.Disable ();
2110                 step_req.Depth = StepDepth.Out;
2111                 step_req.Enable ();
2112                 return step_once ();
2113         }
2114
2115         Event step_once_or_breakpoint () {
2116                 vm.Resume ();
2117                 var e = GetNextEvent ();
2118                 Assert.IsTrue (e is StepEvent || e is BreakpointEvent);
2119                 return e;
2120         }
2121
2122         Event step_over_or_breakpoint () {
2123                 step_req.Disable ();
2124                 step_req.Depth = StepDepth.Over;
2125                 step_req.Enable ();
2126                 return step_once_or_breakpoint ();
2127         }
2128
2129         Event step_out_or_breakpoint () {
2130                 step_req.Disable ();
2131                 step_req.Depth = StepDepth.Out;
2132                 step_req.Enable ();
2133                 return step_once_or_breakpoint ();
2134         }
2135
2136         [Test]
2137         public void Locals () {
2138                 var be = run_until ("locals1");
2139
2140                 StackFrame frame = be.Thread.GetFrames () [0];
2141                 MethodMirror m1 = frame.Method;
2142
2143                 // Compiler generated byref local
2144                 foreach (var l in m1.GetLocals ()) {
2145                         // The byval flag is hidden from the type
2146                         if (l.Name != "ri" && l.Type.Name == "Double")
2147                                 AssertValue (null, frame.GetValue (l));
2148                 }
2149
2150                 be = run_until ("locals2");
2151
2152                 frame = be.Thread.GetFrames () [0];
2153
2154                 object val = frame.GetValue (frame.Method.GetLocal ("i"));
2155                 AssertValue (0, val);
2156
2157                 var req = create_step (be);
2158                 req.Enable ();
2159
2160                 // Skip nop
2161                 step_once ();
2162
2163                 // Execute i = 42
2164                 var e = step_once ();
2165                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
2166
2167                 // Execute s = "AB";
2168                 e = step_once ();
2169                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
2170
2171                 frame = e.Thread.GetFrames () [0];
2172
2173                 val = frame.GetValue (frame.Method.GetLocal ("i"));
2174                 AssertValue (42, val);
2175
2176                 LocalVariable[] locals = frame.Method.GetLocals ();
2177                 var vals = frame.GetValues (locals);
2178                 Assert.AreEqual (locals.Length, vals.Length);
2179                 for (int i = 0; i < locals.Length; ++i) {
2180                         if (locals [i].Name == "i")
2181                                 AssertValue (42, vals [i]);
2182                         if (locals [i].Name == "s")
2183                                 AssertValue ("AB", vals [i]);
2184                         if (locals [i].Name == "t")
2185                                 AssertValue ("ABC", vals [i]);
2186                         if (locals [i].Name == "alist") {
2187                         }
2188                 }
2189
2190                 // Argument checking
2191
2192                 // GetValue () null
2193                 AssertThrows<ArgumentNullException> (delegate () {
2194                                 frame.GetValue ((LocalVariable)null);
2195                         });
2196                 // GetValue () local from another method
2197                 AssertThrows<ArgumentException> (delegate () {
2198                                 frame.GetValue (m1.GetLocal ("foo"));
2199                         });
2200
2201                 // GetValue () null
2202                 AssertThrows<ArgumentNullException> (delegate () {
2203                                 frame.GetValue ((ParameterInfoMirror)null);
2204                         });
2205                 // GetValue () local from another method
2206                 AssertThrows<ArgumentException> (delegate () {
2207                                 frame.GetValue (m1.GetParameters ()[0]);
2208                         });
2209
2210                 // GetValues () null
2211                 AssertThrows<ArgumentNullException> (delegate () {
2212                                 frame.GetValues (null);
2213                         });
2214                 // GetValues () embedded null
2215                 AssertThrows<ArgumentNullException> (delegate () {
2216                                 frame.GetValues (new LocalVariable [] { null });
2217                         });
2218                 // GetValues () local from another method
2219                 AssertThrows<ArgumentException> (delegate () {
2220                                 frame.GetValues (new LocalVariable [] { m1.GetLocal ("foo") });
2221                         });
2222                 // return value
2223                 AssertThrows<ArgumentException> (delegate () {
2224                                 val = frame.GetValue (frame.Method.ReturnParameter);
2225                         });
2226
2227                 // invalid stack frames
2228                 vm.Resume ();
2229                 e = GetNextEvent ();
2230                 Assert.IsTrue (e is StepEvent);
2231                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
2232
2233                 AssertThrows<InvalidStackFrameException> (delegate () {
2234                                 frame.GetValue (frame.Method.GetLocal ("i"));
2235                         });
2236
2237                 req.Disable ();
2238
2239                 // gsharedvt
2240                 be = run_until ("locals7");
2241
2242                 req = create_step (be);
2243                 req.Enable ();
2244
2245                 // Skip nop
2246                 e = step_once ();
2247
2248                 // Test that locals are initialized
2249                 frame = e.Thread.GetFrames () [0];
2250                 val = frame.GetValue (frame.Method.GetLocal ("t"));
2251                 AssertValue (0, val);
2252
2253                 // Execute t = arg
2254                 e = step_once ();
2255                 Assert.AreEqual ("locals7", (e as StepEvent).Method.Name);
2256
2257                 // Execute t2 = t
2258                 e = step_once ();
2259                 Assert.AreEqual ("locals7", (e as StepEvent).Method.Name);
2260
2261                 frame = e.Thread.GetFrames () [0];
2262                 val = frame.GetValue (frame.Method.GetParameters ()[0]);
2263                 AssertValue (22, val);
2264                 val = frame.GetValue (frame.Method.GetLocal ("t"));
2265                 AssertValue (22, val);
2266                 val = frame.GetValue (frame.Method.GetLocal ("t2"));
2267                 AssertValue (22, val);
2268         }
2269
2270         [Test]
2271         public void GetVisibleVariables () {
2272                 Event e = run_until ("locals4");
2273
2274                 // First scope
2275                 var locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
2276                 Assert.AreEqual (2, locals.Count);
2277                 var loc = locals.First (l => l.Name == "i");
2278                 Assert.AreEqual ("Int64", loc.Type.Name);
2279                 loc = locals.First (l => l.Name == "s");
2280                 Assert.AreEqual ("String", loc.Type.Name);
2281
2282                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
2283                 Assert.AreEqual ("i", loc.Name);
2284                 Assert.AreEqual ("Int64", loc.Type.Name);
2285
2286                 e = run_until ("locals5");
2287
2288                 // Second scope
2289                 locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
2290                 Assert.AreEqual (2, locals.Count);
2291                 loc = locals.First (l => l.Name == "i");
2292                 Assert.AreEqual ("String", loc.Type.Name);
2293                 loc = locals.First (l => l.Name == "s");
2294                 Assert.AreEqual ("String", loc.Type.Name);
2295
2296                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
2297                 Assert.AreEqual ("i", loc.Name);
2298                 Assert.AreEqual ("String", loc.Type.Name);
2299
2300                 // Variable in another scope
2301                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("j");
2302                 Assert.IsNull (loc);
2303         }
2304
2305         [Test]
2306         public void Exit () {
2307                 run_until ("Main");
2308
2309                 vm.Exit (5);
2310
2311                 var e = GetNextEvent ();
2312                 Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
2313
2314                 Assert.AreEqual (5, (e as VMDeathEvent).ExitCode);
2315
2316                 var p = vm.Process;
2317                 /* Could be a remote vm with no process */
2318                 if (p != null) {
2319                         p.WaitForExit ();
2320                         Assert.AreEqual (5, p.ExitCode);
2321
2322                         // error handling
2323                         AssertThrows<VMDisconnectedException> (delegate () {
2324                                         vm.Resume ();
2325                                 });
2326                 }
2327
2328                 vm = null;
2329         }
2330
2331         [Test]
2332         public void Dispose () {
2333                 run_until ("Main");
2334
2335                 vm.Detach ();
2336
2337                 var e = GetNextEvent ();
2338                 Assert.IsInstanceOfType (typeof (VMDisconnectEvent), e);
2339
2340                 var p = vm.Process;
2341                 /* Could be a remote vm with no process */
2342                 if (p != null) {
2343                         p.WaitForExit ();
2344                         Assert.AreEqual (3, p.ExitCode);
2345
2346                         // error handling
2347                         AssertThrows<VMDisconnectedException> (delegate () {
2348                                         vm.Resume ();
2349                                 });
2350                 }
2351
2352                 vm = null;
2353         }
2354
2355         [Test]
2356         public void ColumnNumbers () {
2357                 Event e = run_until ("line_numbers");
2358
2359                 // FIXME: Merge this with LineNumbers () when its fixed
2360
2361                 step_req = create_step (e);
2362                 step_req.Depth = StepDepth.Into;
2363                 step_req.Enable ();
2364
2365                 Location l;
2366                 
2367                 while (true) {
2368                         vm.Resume ();
2369
2370                         e = GetNextEvent ();
2371                         Assert.IsTrue (e is StepEvent);
2372                         if (e.Thread.GetFrames ()[0].Method.Name == "ln1")
2373                                 break;
2374                 }
2375
2376                 // Do an additional step over so we are not on the beginning line of the method
2377                 step_req.Disable ();
2378                 step_req.Depth = StepDepth.Over;
2379                 step_req.Enable ();
2380                 vm.Resume ();
2381                 e = GetNextEvent ();
2382                 Assert.IsTrue (e is StepEvent);         
2383
2384                 l = e.Thread.GetFrames ()[0].Location;
2385
2386                 Assert.AreEqual (3, l.ColumnNumber);
2387
2388                 step_req.Disable ();
2389         }
2390
2391         [Test]
2392         // Broken by mcs+runtime changes (#5438)
2393         [Category("NotWorking")]
2394         public void LineNumbers () {
2395                 Event e = run_until ("line_numbers");
2396
2397                 step_req = create_step (e);
2398                 step_req.Depth = StepDepth.Into;
2399                 step_req.Enable ();
2400
2401                 Location l;
2402                 
2403                 vm.Resume ();
2404
2405                 e = GetNextEvent ();
2406                 Assert.IsTrue (e is StepEvent);
2407
2408                 l = e.Thread.GetFrames ()[0].Location;
2409
2410                 Assert.IsTrue (l.SourceFile.IndexOf ("dtest-app.cs") != -1);
2411                 Assert.AreEqual ("ln1", l.Method.Name);
2412
2413                 // Check hash
2414                 using (FileStream fs = new FileStream (l.SourceFile, FileMode.Open, FileAccess.Read)) {
2415                         MD5 md5 = MD5.Create ();
2416                         var hash = md5.ComputeHash (fs);
2417
2418                         for (int i = 0; i < 16; ++i)
2419                                 Assert.AreEqual (hash [i], l.SourceFileHash [i]);
2420                 }
2421                 
2422                 int line_base = l.LineNumber;
2423
2424                 vm.Resume ();
2425                 e = GetNextEvent ();
2426                 Assert.IsTrue (e is StepEvent);
2427                 l = e.Thread.GetFrames ()[0].Location;
2428                 Assert.AreEqual ("ln2", l.Method.Name);
2429                 Assert.AreEqual (line_base + 6, l.LineNumber);
2430
2431                 vm.Resume ();
2432                 e = GetNextEvent ();
2433                 Assert.IsTrue (e is StepEvent);
2434                 l = e.Thread.GetFrames ()[0].Location;
2435                 Assert.AreEqual ("ln1", l.Method.Name);
2436                 Assert.AreEqual (line_base + 1, l.LineNumber);
2437
2438                 vm.Resume ();
2439                 e = GetNextEvent ();
2440                 Assert.IsTrue (e is StepEvent);
2441                 l = e.Thread.GetFrames ()[0].Location;
2442                 Assert.AreEqual ("ln3", l.Method.Name);
2443                 Assert.AreEqual (line_base + 11, l.LineNumber);
2444
2445                 vm.Resume ();
2446                 e = GetNextEvent ();
2447                 Assert.IsTrue (e is StepEvent);
2448                 l = e.Thread.GetFrames ()[0].Location;
2449                 Assert.AreEqual ("ln3", l.Method.Name);
2450                 Assert.IsTrue (l.SourceFile.EndsWith ("FOO"));
2451                 Assert.AreEqual (55, l.LineNumber);
2452
2453                 vm.Resume ();
2454                 e = GetNextEvent ();
2455                 Assert.IsTrue (e is StepEvent);
2456                 l = e.Thread.GetFrames ()[0].Location;
2457                 Assert.AreEqual ("ln1", l.Method.Name);
2458                 Assert.AreEqual (line_base + 2, l.LineNumber);
2459
2460                 // GetSourceFiles ()
2461                 string[] sources = l.Method.DeclaringType.GetSourceFiles ();
2462                 Assert.AreEqual (2, sources.Length);
2463                 Assert.AreEqual ("dtest-app.cs", sources [0]);
2464                 Assert.AreEqual ("FOO", sources [1]);
2465
2466                 sources = l.Method.DeclaringType.GetSourceFiles (true);
2467                 Assert.AreEqual (2, sources.Length);
2468                 Assert.IsTrue (sources [0].EndsWith ("dtest-app.cs"));
2469                 Assert.IsTrue (sources [1].EndsWith ("FOO"));
2470         }
2471
2472         [Test]
2473         public void Suspend () {
2474                 vm.Detach ();
2475
2476                 Start (new string [] { "dtest-app.exe", "suspend-test" });
2477
2478                 Event e = run_until ("suspend");
2479
2480                 ThreadMirror main = e.Thread;
2481
2482                 vm.Resume ();
2483
2484                 Thread.Sleep (100);
2485
2486                 vm.Suspend ();
2487
2488                 // The debuggee should be suspended while it is running the infinite loop
2489                 // in suspend ()
2490                 StackFrame frame = main.GetFrames ()[0];
2491                 Assert.AreEqual ("suspend", frame.Method.Name);
2492
2493                 vm.Resume ();
2494
2495                 // resuming when not suspended
2496                 AssertThrows<InvalidOperationException> (delegate () {
2497                                 vm.Resume ();
2498                         });
2499
2500                 vm.Exit (0);
2501
2502                 vm = null;
2503         }
2504
2505         [Test]
2506         public void AssemblyLoad () {
2507                 Event e = run_until ("assembly_load");
2508
2509                 var load_req = vm.CreateAssemblyLoadRequest ();
2510                 load_req.Enable ();
2511
2512                 vm.Resume ();
2513
2514                 e = GetNextEvent ();
2515                 Assert.IsInstanceOfType (typeof (AssemblyLoadEvent), e);
2516                 Assert.IsTrue ((e as AssemblyLoadEvent).Assembly.Location.EndsWith ("System.dll"));
2517
2518                 var frames = e.Thread.GetFrames ();
2519                 Assert.IsTrue (frames.Length > 0);
2520                 Assert.AreEqual ("assembly_load", frames [0].Method.Name);
2521         }
2522
2523         [Test]
2524         public void CreateValue () {
2525                 PrimitiveValue v;
2526
2527                 v = vm.CreateValue (1);
2528                 Assert.AreEqual (vm, v.VirtualMachine);
2529                 Assert.AreEqual (1, v.Value);
2530
2531                 v = vm.CreateValue (null);
2532                 Assert.AreEqual (vm, v.VirtualMachine);
2533                 Assert.AreEqual (null, v.Value);
2534
2535                 // Argument checking
2536                 AssertThrows <ArgumentException> (delegate () {
2537                                 v = vm.CreateValue ("FOO");
2538                         });
2539         }
2540
2541         [Test]
2542         public void CreateString () {
2543                 StringMirror s = vm.RootDomain.CreateString ("ABC");
2544
2545                 Assert.AreEqual (vm, s.VirtualMachine);
2546                 Assert.AreEqual ("ABC", s.Value);
2547                 Assert.AreEqual (vm.RootDomain, s.Domain);
2548
2549                 // Long strings
2550                 StringBuilder sb = new StringBuilder ();
2551                 for (int i = 0; i < 1024; ++i)
2552                         sb.Append ('A');
2553                 s = vm.RootDomain.CreateString (sb.ToString ());
2554
2555                 // Argument checking
2556                 AssertThrows <ArgumentNullException> (delegate () {
2557                                 s = vm.RootDomain.CreateString (null);
2558                         });
2559         }
2560
2561         [Test]
2562         public void CreateBoxedValue () {
2563                 ObjectMirror o = vm.RootDomain.CreateBoxedValue (new PrimitiveValue (vm, 42));
2564
2565                 Assert.AreEqual ("Int32", o.Type.Name);
2566                 //AssertValue (42, m.GetValue (o.Type.GetField ("m_value")));
2567
2568                 // Argument checking
2569                 AssertThrows <ArgumentNullException> (delegate () {
2570                                 vm.RootDomain.CreateBoxedValue (null);
2571                         });
2572
2573                 AssertThrows <ArgumentException> (delegate () {
2574                                 vm.RootDomain.CreateBoxedValue (o);
2575                         });
2576         }
2577
2578         [Test]
2579         public void Invoke () {
2580                 Event e = run_until ("invoke1");
2581
2582                 StackFrame frame = e.Thread.GetFrames () [0];
2583
2584                 TypeMirror t = frame.Method.DeclaringType;
2585                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2586
2587                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2588
2589                 MethodMirror m;
2590                 Value v;
2591
2592                 // return void
2593                 m = t.GetMethod ("invoke_return_void");
2594                 v = this_obj.InvokeMethod (e.Thread, m, null);
2595                 Assert.IsNull (v);
2596
2597                 // return ref
2598                 m = t.GetMethod ("invoke_return_ref");
2599                 v = this_obj.InvokeMethod (e.Thread, m, null);
2600                 AssertValue ("ABC", v);
2601
2602                 // return null
2603                 m = t.GetMethod ("invoke_return_null");
2604                 v = this_obj.InvokeMethod (e.Thread, m, null);
2605                 AssertValue (null, v);
2606
2607                 // return primitive
2608                 m = t.GetMethod ("invoke_return_primitive");
2609                 v = this_obj.InvokeMethod (e.Thread, m, null);
2610                 AssertValue (42, v);
2611
2612                 // return nullable
2613                 m = t.GetMethod ("invoke_return_nullable");
2614                 v = this_obj.InvokeMethod (e.Thread, m, null);
2615                 Assert.IsInstanceOfType (typeof (StructMirror), v);
2616                 var s = v as StructMirror;
2617                 AssertValue (42, s.Fields [0]);
2618                 AssertValue (true, s.Fields [1]);
2619
2620                 // pass nullable as this
2621                 //m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2622                 m = s.Type.GetMethod ("ToString");
2623                 v = s.InvokeMethod (e.Thread, m, null);
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 primitive
2639                 m = t.GetMethod ("invoke_pass_primitive");
2640                 Value[] args = new Value [] {
2641                         vm.CreateValue ((byte)Byte.MaxValue),
2642                         vm.CreateValue ((sbyte)SByte.MaxValue),
2643                         vm.CreateValue ((short)1),
2644                         vm.CreateValue ((ushort)1),
2645                         vm.CreateValue ((int)1),
2646                         vm.CreateValue ((uint)1),
2647                         vm.CreateValue ((long)1),
2648                         vm.CreateValue ((ulong)1),
2649                         vm.CreateValue ('A'),
2650                         vm.CreateValue (true),
2651                         vm.CreateValue (3.14f),
2652                         vm.CreateValue (3.14) };
2653
2654                 v = this_obj.InvokeMethod (e.Thread, m, args);
2655                 AssertValue ((int)Byte.MaxValue + (int)SByte.MaxValue + 1 + 1 + 1 + 1 + 1 + 1 + 'A' + 1 + 3 + 3, v);
2656
2657                 // pass ref
2658                 m = t.GetMethod ("invoke_pass_ref");
2659                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2660                 AssertValue ("ABC", v);
2661
2662                 // pass null
2663                 m = t.GetMethod ("invoke_pass_ref");
2664                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (null) });
2665                 AssertValue (null, v);
2666
2667                 // static
2668                 m = t.GetMethod ("invoke_static_pass_ref");
2669                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2670                 AssertValue ("ABC", v);
2671
2672                 // static invoked using ObjectMirror.InvokeMethod
2673                 m = t.GetMethod ("invoke_static_pass_ref");
2674                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2675                 AssertValue ("ABC", v);
2676
2677                 // method which throws an exception
2678                 try {
2679                         m = t.GetMethod ("invoke_throws");
2680                         v = this_obj.InvokeMethod (e.Thread, m, null);
2681                         Assert.Fail ();
2682                 } catch (InvocationException ex) {
2683                         Assert.AreEqual ("Exception", ex.Exception.Type.Name);
2684                 }
2685
2686                 // out argument
2687                 m = t.GetMethod ("invoke_out");
2688                 var out_task = this_obj.InvokeMethodAsyncWithResult (e.Thread, m, new Value [] { vm.CreateValue (1), vm.CreateValue (null) }, InvokeOptions.ReturnOutArgs);
2689                 var out_args = out_task.Result.OutArgs;
2690                 AssertValue (5, out_args [0]);
2691                 Assert.IsTrue (out_args [1] is ArrayMirror);
2692                 Assert.AreEqual (10, (out_args [1] as ArrayMirror).Length);
2693
2694                 // without ReturnOutArgs flag
2695                 out_task = this_obj.InvokeMethodAsyncWithResult (e.Thread, m, new Value [] { vm.CreateValue (1), vm.CreateValue (null) });
2696                 out_args = out_task.Result.OutArgs;
2697                 Assert.IsNull (out_args);
2698
2699                 // newobj
2700                 m = t.GetMethod (".ctor");
2701                 v = t.InvokeMethod (e.Thread, m, null);
2702                 Assert.IsInstanceOfType (typeof (ObjectMirror), v);
2703                 Assert.AreEqual ("Tests", (v as ObjectMirror).Type.Name);
2704
2705                 // interface method
2706                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("ITest2");
2707                 m = cl1.GetMethod ("invoke_iface");
2708                 v = this_obj.InvokeMethod (e.Thread, m, null);
2709                 AssertValue (42, v);
2710
2711                 // virtual call
2712                 m = t.BaseType.GetMethod ("virtual_method");
2713                 v = this_obj.InvokeMethod (e.Thread, m, null, InvokeOptions.Virtual);
2714                 AssertValue ("V2", v);
2715
2716                 // virtual call on static method
2717                 m = t.GetMethod ("invoke_static_pass_ref");
2718                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") }, InvokeOptions.Virtual);
2719                 AssertValue ("ABC", v);
2720
2721                 // instance
2722                 m = t.GetMethod ("invoke_pass_ref");
2723                 var task = this_obj.InvokeMethodAsync (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2724                 AssertValue ("ABC", task.Result);
2725
2726                 // static
2727                 m = t.GetMethod ("invoke_static_pass_ref");
2728                 task = t.InvokeMethodAsync (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2729                 AssertValue ("ABC", task.Result);
2730
2731                 // Argument checking
2732                 
2733                 // null thread
2734                 AssertThrows<ArgumentNullException> (delegate {
2735                                 m = t.GetMethod ("invoke_pass_ref");
2736                                 v = this_obj.InvokeMethod (null, m, new Value [] { vm.CreateValue (null) });                            
2737                         });
2738
2739                 // null method
2740                 AssertThrows<ArgumentNullException> (delegate {
2741                                 v = this_obj.InvokeMethod (e.Thread, null, new Value [] { vm.CreateValue (null) });                             
2742                         });
2743
2744                 // invalid number of arguments
2745                 m = t.GetMethod ("invoke_pass_ref");
2746                 AssertThrows<ArgumentException> (delegate {
2747                                 v = this_obj.InvokeMethod (e.Thread, m, null);
2748                         });
2749
2750                 // invalid type of argument (ref != primitive)
2751                 m = t.GetMethod ("invoke_pass_ref");
2752                 AssertThrows<ArgumentException> (delegate {
2753                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2754                         });
2755
2756                 // invalid type of argument (primitive != primitive)
2757                 m = t.GetMethod ("invoke_pass_primitive_2");
2758                 AssertThrows<ArgumentException> (delegate {
2759                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2760                         });
2761
2762                 // invoking a non-static method as static
2763                 m = t.GetMethod ("invoke_pass_ref");
2764                 AssertThrows<ArgumentException> (delegate {
2765                                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2766                         });
2767
2768                 // invoking a method defined in another class
2769                 m = t2.GetMethod ("invoke");
2770                 AssertThrows<ArgumentException> (delegate {
2771                                 v = this_obj.InvokeMethod (e.Thread, m, null);
2772                         });
2773         }
2774
2775         [Test]
2776         public void InvokeVType () {
2777                 Event e = run_until ("invoke1");
2778
2779                 StackFrame frame = e.Thread.GetFrames () [0];
2780
2781                 var s = frame.GetArgument (1) as StructMirror;
2782
2783                 TypeMirror t = s.Type;
2784
2785                 MethodMirror m;
2786                 Value v;
2787
2788                 // Pass struct as this, receive int
2789                 m = t.GetMethod ("invoke_return_int");
2790                 v = s.InvokeMethod (e.Thread, m, null);
2791                 AssertValue (42, v);
2792
2793                 // Pass boxed struct as this
2794                 var boxed_this = t.NewInstance () as ObjectMirror;
2795                 m = t.GetMethod ("invoke_return_int");
2796                 v = boxed_this.InvokeMethod (e.Thread, m, null);
2797                 AssertValue (0, v);
2798
2799                 // Pass struct as this, receive intptr
2800                 m = t.GetMethod ("invoke_return_intptr");
2801                 v = s.InvokeMethod (e.Thread, m, null);
2802                 AssertValue (43, v);
2803
2804                 // Static method
2805                 m = t.GetMethod ("invoke_static");
2806                 v = t.InvokeMethod (e.Thread, m, null);
2807                 AssertValue (5, v);
2808
2809                 // Pass generic struct as this
2810                 s = frame.GetArgument (2) as StructMirror;
2811                 t = s.Type;
2812                 m = t.GetMethod ("invoke_return_int");
2813                 v = s.InvokeMethod (e.Thread, m, null);
2814                 AssertValue (42, v);
2815
2816                 // .ctor
2817                 s = frame.GetArgument (1) as StructMirror;
2818                 t = s.Type;
2819                 m = t.GetMethods ().First (method => method.Name == ".ctor" && method.GetParameters ().Length == 1);
2820                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2821                 AssertValue (1, (v as StructMirror)["i"]);
2822
2823                 // Invoke a method which changes state
2824                 s = frame.GetArgument (1) as StructMirror;
2825                 t = s.Type;
2826                 m = t.GetMethod ("invoke_mutate");
2827                 var task = s.InvokeMethodAsyncWithResult (e.Thread, m, null, InvokeOptions.ReturnOutThis);
2828                 var out_this = task.Result.OutThis as StructMirror;
2829                 AssertValue (5, out_this ["l"]);
2830
2831                 // Without the ReturnOutThis flag
2832                 s = frame.GetArgument (1) as StructMirror;
2833                 t = s.Type;
2834                 m = t.GetMethod ("invoke_mutate");
2835                 task = s.InvokeMethodAsyncWithResult (e.Thread, m, null);
2836                 out_this = task.Result.OutThis as StructMirror;
2837                 Assert.AreEqual (null, out_this);
2838
2839                 // interface method
2840                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("ITest2");
2841                 m = cl1.GetMethod ("invoke_iface");
2842                 v = s.InvokeMethod (e.Thread, m, null);
2843                 AssertValue (42, v);
2844
2845                 // virtual method
2846                 m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2847                 v = s.InvokeMethod (e.Thread, m, null, InvokeOptions.Virtual);
2848                 AssertValue ("42", v);
2849         }
2850
2851         [Test]
2852         public void BreakpointDuringInvoke () {
2853                 Event e = run_until ("invoke1");
2854
2855                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
2856                 Assert.IsNotNull (m);
2857                 vm.SetBreakpoint (m, 0);
2858
2859                 StackFrame frame = e.Thread.GetFrames () [0];
2860                 var o = frame.GetThis () as ObjectMirror;
2861
2862                 bool failed = false;
2863
2864                 bool finished = false;
2865                 object wait = new object ();
2866
2867                 // Have to invoke in a separate thread as the invoke is suspended until we
2868                 // resume after the breakpoint
2869                 Thread t = new Thread (delegate () {
2870                                 try {
2871                                         o.InvokeMethod (e.Thread, m, null);
2872                                 } catch {
2873                                         failed = true;
2874                                 }
2875                                 lock (wait) {
2876                                         finished = true;
2877                                         Monitor.Pulse (wait);
2878                                 }
2879                         });
2880
2881                 t.Start ();
2882
2883                 StackFrame invoke_frame = null;
2884
2885                 try {
2886                         e = GetNextEvent ();
2887                         Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
2888                         // Check stack trace support and invokes
2889                         var frames = e.Thread.GetFrames ();
2890                         invoke_frame = frames [0];
2891                         Assert.AreEqual ("invoke2", frames [0].Method.Name);
2892                         Assert.IsTrue (frames [0].IsDebuggerInvoke);
2893                         Assert.AreEqual ("invoke1", frames [1].Method.Name);
2894                 } finally {
2895                         vm.Resume ();
2896                 }
2897
2898                 lock (wait) {
2899                         if (!finished)
2900                                 Monitor.Wait (wait);
2901                 }
2902
2903                 // Check that the invoke frames are no longer valid
2904                 AssertThrows<InvalidStackFrameException> (delegate {
2905                                 invoke_frame.GetThis ();
2906                         });
2907
2908                 // Check InvokeOptions.DisableBreakpoints flag
2909                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2910         }
2911
2912         [Test]
2913         public void DisabledExceptionDuringInvoke () {
2914                 Event e = run_until ("invoke_ex");
2915
2916                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_ex_inner");
2917
2918                 StackFrame frame = e.Thread.GetFrames () [0];
2919                 var o = frame.GetThis () as ObjectMirror;
2920
2921                 var req = vm.CreateExceptionRequest (null);
2922                 req.Enable ();
2923
2924                 // Check InvokeOptions.DisableBreakpoints flag
2925                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2926
2927                 req.Disable ();
2928         }
2929
2930         [Test]
2931         public void InvokeSingleThreaded () {
2932                 vm.Detach ();
2933
2934                 Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
2935
2936                 Event e = run_until ("invoke_single_threaded_2");
2937
2938                 StackFrame f = e.Thread.GetFrames ()[0];
2939
2940                 var obj = f.GetThis () as ObjectMirror;
2941
2942                 // Check that the counter value incremented by the other thread does not increase
2943                 // during the invoke.
2944                 object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2945
2946                 var m = obj.Type.GetMethod ("invoke_return_void");
2947                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2948
2949             object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2950
2951                 Assert.AreEqual ((int)counter1, (int)counter2);
2952
2953                 // Test multiple invokes done in succession
2954                 m = obj.Type.GetMethod ("invoke_return_void");
2955                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2956
2957                 // Test events during single-threaded invokes
2958                 vm.EnableEvents (EventType.TypeLoad);
2959                 m = obj.Type.GetMethod ("invoke_type_load");
2960                 obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
2961                                 vm.Resume ();
2962                         }, null);
2963
2964                 e = GetNextEvent ();
2965                 Assert.AreEqual (EventType.TypeLoad, e.EventType);
2966         }
2967
2968         List<Value> invoke_results;
2969
2970         [Test]
2971         public void InvokeMultiple () {
2972                 Event e = run_until ("invoke1");
2973
2974                 StackFrame frame = e.Thread.GetFrames () [0];
2975
2976                 TypeMirror t = frame.Method.DeclaringType;
2977                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2978
2979                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2980
2981                 var methods = new MethodMirror [2];
2982                 methods [0] = t.GetMethod ("invoke_return_ref");
2983                 methods [1] = t.GetMethod ("invoke_return_primitive");
2984
2985                 invoke_results = new List<Value> ();
2986
2987                 var r = this_obj.BeginInvokeMultiple (e.Thread, methods, null, InvokeOptions.SingleThreaded, invoke_multiple_cb, this_obj);
2988                 WaitHandle.WaitAll (new WaitHandle[] { r.AsyncWaitHandle });
2989                 this_obj.EndInvokeMultiple (r);
2990                 // The callback might still be running
2991                 while (invoke_results.Count < 2) {
2992                         Thread.Sleep (100);
2993                 }
2994                 if (invoke_results [0] is PrimitiveValue) {
2995                         AssertValue ("ABC", invoke_results [1]);
2996                         AssertValue (42, invoke_results [0]);
2997                 } else {
2998                         AssertValue ("ABC", invoke_results [0]);
2999                         AssertValue (42, invoke_results [1]);
3000                 }
3001         }
3002
3003         void invoke_multiple_cb (IAsyncResult ar) {
3004                 ObjectMirror this_obj = (ObjectMirror)ar.AsyncState;
3005
3006                 var res = this_obj.EndInvokeMethod (ar);
3007                 lock (invoke_results)
3008                         invoke_results.Add (res);
3009         }
3010
3011         [Test]
3012         public void InvokeAbort () {
3013                 vm.Detach ();
3014
3015                 Start (new string [] { "dtest-app.exe", "invoke-abort" });
3016
3017                 Event e = run_until ("invoke_abort");
3018
3019                 StackFrame f = e.Thread.GetFrames ()[0];
3020
3021                 var obj = f.GetThis () as ObjectMirror;
3022                 var t = obj.Type;
3023                 var m = t.GetMethod ("invoke_abort_2");
3024                 // Invoke multiple times to check that the subsequent invokes are aborted too
3025                 var res = (IInvokeAsyncResult)obj.BeginInvokeMultiple (e.Thread, new MethodMirror[] { m, m, m, m }, null, InvokeOptions.None, delegate { }, null);
3026                 Thread.Sleep (500);
3027                 res.Abort ();
3028                 AssertThrows<CommandException> (delegate {
3029                                 obj.EndInvokeMethod (res);
3030                         });
3031         }
3032
3033         [Test]
3034         public void GetThreads () {
3035                 vm.GetThreads ();
3036         }
3037
3038         [Test]
3039         public void Threads () {
3040                 Event e = run_until ("threads");
3041
3042                 Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
3043
3044                 Assert.IsTrue (e.Thread.ThreadId > 0);
3045
3046                 Assert.AreEqual (e.Thread.TID, e.Thread.TID);
3047
3048                 vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
3049
3050                 vm.Resume ();
3051
3052                 e = GetNextEvent ();
3053                 Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
3054                 var state = e.Thread.ThreadState;
3055                 Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
3056
3057                 vm.Resume ();
3058
3059                 e = GetNextEvent ();
3060                 Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
3061                 Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
3062         }
3063
3064         [Test]
3065         public void Frame_SetValue () {
3066                 Event e = run_until ("locals2");
3067
3068                 StackFrame frame = e.Thread.GetFrames () [0];
3069
3070                 // primitive
3071                 var l = frame.Method.GetLocal ("i");
3072                 frame.SetValue (l, vm.CreateValue ((long)55));
3073                 AssertValue (55, frame.GetValue (l));
3074
3075                 // reference
3076                 l = frame.Method.GetLocal ("s");
3077                 frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
3078                 AssertValue ("DEF", frame.GetValue (l));
3079
3080                 // argument as local
3081                 l = frame.Method.GetLocal ("arg");
3082                 frame.SetValue (l, vm.CreateValue (6));
3083                 AssertValue (6, frame.GetValue (l));
3084
3085                 // argument
3086                 var p = frame.Method.GetParameters ()[1];
3087                 frame.SetValue (p, vm.CreateValue (7));
3088                 AssertValue (7, frame.GetValue (p));
3089
3090                 // gshared
3091                 p = frame.Method.GetParameters ()[2];
3092                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF"));
3093                 AssertValue ("DEF", frame.GetValue (p));
3094
3095                 // byref
3096                 p = frame.Method.GetParameters ()[3];
3097                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF2"));
3098                 AssertValue ("DEF2", frame.GetValue (p));
3099
3100                 // byref struct
3101                 p = frame.Method.GetParameters ()[4];
3102                 var v = frame.GetValue (p) as StructMirror;
3103                 v ["i"] = vm.CreateValue (43);
3104                 frame.SetValue (p, v);
3105                 v = frame.GetValue (p) as StructMirror;
3106                 AssertValue (43, v ["i"]);
3107
3108                 // argument checking
3109
3110                 // variable null
3111                 AssertThrows<ArgumentNullException> (delegate () {
3112                                 frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
3113                         });
3114
3115                 // value null
3116                 AssertThrows<ArgumentNullException> (delegate () {
3117                                 l = frame.Method.GetLocal ("i");
3118                                 frame.SetValue (l, null);
3119                         });
3120
3121                 // value of invalid type
3122                 AssertThrows<ArgumentException> (delegate () {
3123                                 l = frame.Method.GetLocal ("i");
3124                                 frame.SetValue (l, vm.CreateValue (55));
3125                         });
3126         }
3127
3128         [Test]
3129         [Category ("only")]
3130         public void Frame_SetValue_Registers () {
3131                 Event e = run_until ("locals6_1");
3132
3133                 StackFrame frame = e.Thread.GetFrames () [1];
3134
3135                 // Set 'j' to 99
3136                 var l = frame.Method.GetLocal ("j");
3137                 frame.SetValue (l, vm.CreateValue (99));
3138                 AssertValue (99, frame.GetValue (l));
3139
3140                 // Check it during execution
3141                 e = run_until ("locals6_2");
3142                 frame = e.Thread.GetFrames () [0];
3143                 AssertValue (99, frame.GetValue (frame.Method.GetParameters ()[0]));
3144
3145                 // Set it while in a frame which clobbers its register
3146                 e = run_until ("locals6_3");
3147                 frame = e.Thread.GetFrames () [1];
3148                 frame.SetValue (l, vm.CreateValue (100));
3149                 AssertValue (100, frame.GetValue (l));
3150
3151                 // Check it during execution
3152                 e = run_until ("locals6_4");
3153                 frame = e.Thread.GetFrames () [0];
3154                 AssertValue (100, frame.GetValue (frame.Method.GetParameters ()[0]));
3155
3156                 // Signed byte value
3157                 e = run_until ("locals6_5");
3158                 frame = e.Thread.GetFrames () [1];
3159                 var l2 = frame.Method.GetLocal ("sb");
3160                 frame.SetValue (l2, vm.CreateValue ((sbyte)-99));
3161                 AssertValue (-99, frame.GetValue (l2));
3162
3163                 // Check it during execution
3164                 e = run_until ("locals6_6");
3165                 frame = e.Thread.GetFrames () [0];
3166                 AssertValue (-99, frame.GetValue (frame.Method.GetParameters ()[0]));
3167         }
3168
3169         [Test]
3170         public void InvokeRegress () {
3171                 Event e = run_until ("invoke1");
3172
3173                 StackFrame frame = e.Thread.GetFrames () [0];
3174
3175                 TypeMirror t = frame.Method.DeclaringType;
3176                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
3177
3178                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
3179
3180                 MethodMirror m;
3181                 Value v;
3182
3183                 // do an invoke
3184                 m = t.GetMethod ("invoke_return_void");
3185                 v = this_obj.InvokeMethod (e.Thread, m, null);
3186                 Assert.IsNull (v);
3187
3188                 // Check that the stack frames remain valid during the invoke
3189                 Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
3190
3191                 // do another invoke
3192                 m = t.GetMethod ("invoke_return_void");
3193                 v = this_obj.InvokeMethod (e.Thread, m, null);
3194                 Assert.IsNull (v);
3195
3196                 // Try a single step after the invoke
3197                 var req = create_step (e);
3198                 req.Depth = StepDepth.Into;
3199                 req.Size = StepSize.Line;
3200                 req.Enable ();
3201
3202                 // Skip nop
3203                 step_once ();
3204
3205                 // Step into invoke2
3206                 vm.Resume ();
3207                 e = GetNextEvent ();
3208                 Assert.IsTrue (e is StepEvent);
3209                 Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
3210
3211                 req.Disable ();
3212
3213                 frame = e.Thread.GetFrames () [0];
3214         }
3215
3216         [Test]
3217         public void Exceptions () {
3218                 Event e = run_until ("exceptions");
3219                 var req = vm.CreateExceptionRequest (null);
3220                 req.Enable ();
3221
3222                 vm.Resume ();
3223
3224                 e = GetNextEvent ();
3225                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3226                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
3227
3228                 var frames = e.Thread.GetFrames ();
3229                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
3230                 req.Disable ();
3231
3232                 // exception type filter
3233
3234                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
3235                 req.Enable ();
3236
3237                 // Skip the throwing of the second OverflowException       
3238                 vm.Resume ();
3239
3240                 e = GetNextEvent ();
3241                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3242                 Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
3243                 req.Disable ();
3244
3245                 // exception type filter for subclasses
3246                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
3247                 req.Enable ();
3248
3249                 vm.Resume ();
3250
3251                 e = GetNextEvent ();
3252                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3253                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
3254                 req.Disable ();
3255
3256                 // no subclasses
3257                 req.IncludeSubclasses = false;
3258                 req.Enable ();
3259
3260                 vm.Resume ();
3261
3262                 e = GetNextEvent ();
3263                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3264                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
3265                 req.Disable ();
3266
3267                 // Implicit exceptions
3268                 req = vm.CreateExceptionRequest (null);
3269                 req.Enable ();
3270
3271                 vm.Resume ();
3272
3273                 e = GetNextEvent ();
3274                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3275                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
3276                 req.Disable ();
3277
3278                 // Single stepping after an exception
3279                 req = vm.CreateExceptionRequest (null);
3280                 req.Enable ();
3281
3282                 vm.Resume ();
3283
3284                 e = GetNextEvent ();
3285                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3286                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
3287                 frames = e.Thread.GetFrames ();
3288                 Assert.AreEqual ("exceptions2", frames [0].Method.Name);
3289                 req.Disable ();
3290
3291                 var sreq = create_step (e);
3292                 sreq.Depth = StepDepth.Over;
3293                 sreq.Size = StepSize.Line;
3294                 sreq.Enable ();
3295
3296                 vm.Resume ();
3297                 e = GetNextEvent ();
3298                 Assert.IsInstanceOfType (typeof (StepEvent), e);
3299                 frames = e.Thread.GetFrames ();
3300                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
3301                 sreq.Disable ();
3302
3303                 // Argument checking
3304                 AssertThrows<ArgumentException> (delegate {
3305                                 vm.CreateExceptionRequest (e.Thread.Type);
3306                         });
3307         }
3308
3309         [Test]
3310         public void ExceptionFilter () {
3311                 Event e = run_until ("exception_filter");
3312
3313                 MethodMirror m = entry_point.DeclaringType.GetMethod ("exception_filter_filter");
3314                 Assert.IsNotNull (m);
3315
3316                 vm.SetBreakpoint (m, 0);
3317
3318                 vm.Resume ();
3319
3320                 e = GetNextEvent ();
3321                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
3322                 Assert.IsTrue (e is BreakpointEvent);
3323                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
3324
3325                 var frames = e.Thread.GetFrames ();
3326
3327                 Assert.IsTrue (frames [0].Location.SourceFile.IndexOf ("dtest-app.cs") != -1);
3328                 Assert.AreEqual ("exception_filter_filter", frames [0].Location.Method.Name);
3329
3330                 Assert.AreEqual (0, frames [1].Location.Method.MetadataToken);
3331                 Assert.AreEqual (0x0f, frames [1].Location.ILOffset);
3332
3333                 Assert.AreEqual ("exception_filter_method", frames [2].Location.Method.Name);
3334                 Assert.AreEqual (0x06, frames [2].Location.ILOffset);
3335
3336                 Assert.AreEqual (0, frames [3].Location.Method.MetadataToken, 0);
3337                 Assert.AreEqual (0, frames [3].Location.ILOffset);
3338
3339                 Assert.AreEqual ("exception_filter", frames [4].Location.Method.Name);
3340         }
3341
3342         [Test]
3343         public void ExceptionFilter2 () {
3344                 vm.Detach ();
3345
3346                 Start (new string [] { "dtest-excfilter.exe" });
3347
3348                 MethodMirror filter_method = entry_point.DeclaringType.GetMethod ("Filter");
3349                 Assert.IsNotNull (filter_method);
3350
3351                 MethodMirror test_method = entry_point.DeclaringType.GetMethod ("Test");
3352                 Assert.IsNotNull (test_method);
3353
3354                 vm.SetBreakpoint (filter_method, 0);
3355
3356                 vm.Resume ();
3357
3358                 var e = GetNextEvent ();
3359                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
3360                 Assert.IsTrue (e is BreakpointEvent);
3361                 Assert.AreEqual (filter_method.Name, (e as BreakpointEvent).Method.Name);
3362
3363                 var frames = e.Thread.GetFrames ();
3364
3365                 Assert.AreEqual (4, frames.Count ());
3366
3367                 Assert.AreEqual (filter_method.Name, frames [0].Location.Method.Name);
3368                 Assert.AreEqual (20, frames [0].Location.LineNumber);
3369                 Assert.AreEqual (0, frames [0].Location.ILOffset);
3370
3371                 Assert.AreEqual (test_method.Name, frames [1].Location.Method.Name);
3372                 Assert.AreEqual (37, frames [1].Location.LineNumber);
3373                 Assert.AreEqual (0x0b, frames [1].Location.ILOffset);
3374
3375                 Assert.AreEqual (test_method.Name, frames [2].Location.Method.Name);
3376                 Assert.AreEqual (33, frames [2].Location.LineNumber);
3377                 Assert.AreEqual (0x05, frames [2].Location.ILOffset);
3378
3379                 Assert.AreEqual (entry_point.Name, frames [3].Location.Method.Name);
3380                 Assert.AreEqual (14, frames [3].Location.LineNumber);
3381                 Assert.AreEqual (0x00, frames [3].Location.ILOffset);
3382
3383                 vm.Exit (0);
3384
3385                 vm = null;
3386         }
3387
3388         [Test]
3389         public void EventSets () {
3390                 //
3391                 // Create two filter which both match the same exception
3392                 //
3393                 Event e = run_until ("exceptions");
3394
3395                 var req = vm.CreateExceptionRequest (null);
3396                 req.Enable ();
3397
3398                 var req2 = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.OverflowException"));
3399                 req2.Enable ();
3400
3401                 vm.Resume ();
3402
3403                 var es = vm.GetNextEventSet ();
3404                 Assert.AreEqual (2, es.Events.Length);
3405
3406                 e = es [0];
3407                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3408                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
3409
3410                 e = es [1];
3411                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3412                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
3413
3414                 req.Disable ();
3415                 req2.Disable ();
3416         }
3417
3418         //
3419         // Test single threaded invokes during processing of nullref exceptions.
3420         // These won't work if the exception handling is done from the sigsegv signal
3421         // handler, since the sigsegv signal is disabled until control returns from the
3422         // signal handler.
3423         //
3424         [Test]
3425         [Category ("only3")]
3426         public void NullRefExceptionAndSingleThreadedInvoke () {
3427                 Event e = run_until ("exceptions");
3428                 var req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.NullReferenceException"));
3429                 req.Enable ();
3430
3431                 vm.Resume ();
3432
3433                 e = GetNextEvent ();
3434                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
3435                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
3436
3437                 var ex = (e as ExceptionEvent).Exception;
3438                 var tostring_method = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
3439                 ex.InvokeMethod (e.Thread, tostring_method, null, InvokeOptions.SingleThreaded);
3440         }
3441
3442         [Test]
3443         public void MemberInOtherDomain () {
3444                 vm.Detach ();
3445
3446                 Start (new string [] { "dtest-app.exe", "domain-test" });
3447
3448                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
3449
3450                 Event e = run_until ("domains_print_across");
3451
3452                 var frame = e.Thread.GetFrames ()[0];
3453                 var inOtherDomain = frame.GetArgument (0) as ObjectMirror;
3454                 var crossDomainField = (ObjectMirror) inOtherDomain.GetValue (inOtherDomain.Type.GetField("printMe"));
3455                 Assert.AreEqual ("SentinelClass", crossDomainField.Type.Name);
3456         }
3457
3458         [Test]
3459         public void Domains () {
3460                 vm.Detach ();
3461
3462                 Start (new string [] { "dtest-app.exe", "domain-test" });
3463
3464                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
3465
3466                 Event e = run_until ("domains");
3467
3468                 vm.Resume ();
3469                 
3470                 e = GetNextEvent ();
3471                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
3472
3473                 var domain = (e as AppDomainCreateEvent).Domain;
3474
3475                 // Check the object type
3476                 e = run_until ("domains_2");
3477                 var frame = e.Thread.GetFrames ()[0];
3478                 var o = frame.GetArgument (0) as ObjectMirror;
3479                 Assert.AreEqual ("CrossDomain", o.Type.Name);
3480
3481                 // Do a remoting invoke
3482                 var cross_domain_type = o.Type;
3483                 var v = o.InvokeMethod (e.Thread, cross_domain_type.GetMethod ("invoke_3"), null);
3484                 AssertValue (42, v);
3485
3486                 // Run until the callback in the domain
3487                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
3488                 Assert.IsNotNull (m);
3489                 vm.SetBreakpoint (m, 0);
3490
3491                 while (true) {
3492                         vm.Resume ();
3493                         e = GetNextEvent ();
3494                         if (e is BreakpointEvent)
3495                                 break;
3496                 }
3497
3498                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
3499
3500                 // d_method is from another domain
3501                 MethodMirror d_method = (e as BreakpointEvent).Method;
3502                 Assert.IsTrue (m != d_method);
3503                 Assert.AreEqual (domain, d_method.DeclaringType.Assembly.Domain);
3504
3505                 var frames = e.Thread.GetFrames ();
3506                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
3507                 Assert.AreEqual (domain, frames [0].Domain);
3508                 Assert.AreEqual ("invoke", frames [1].Method.Name);
3509                 Assert.AreEqual ("domains", frames [2].Method.Name);
3510                 Assert.AreEqual (vm.RootDomain, frames [2].Domain);
3511
3512                 // Test breakpoints on already JITted methods in other domains
3513                 m = entry_point.DeclaringType.GetMethod ("invoke_in_domain_2");
3514                 Assert.IsNotNull (m);
3515                 vm.SetBreakpoint (m, 0);
3516
3517                 while (true) {
3518                         vm.Resume ();
3519                         e = GetNextEvent ();
3520                         if (e is BreakpointEvent)
3521                                 break;
3522                 }
3523
3524                 Assert.AreEqual ("invoke_in_domain_2", (e as BreakpointEvent).Method.Name);
3525
3526                 // This is empty when receiving the AppDomainCreateEvent
3527                 Assert.AreEqual ("domain", domain.FriendlyName);
3528
3529                 // Run until the unload
3530                 while (true) {
3531                         vm.Resume ();
3532                         e = GetNextEvent ();
3533                         if (e is AssemblyUnloadEvent) {
3534                                 AssertThrows<Exception> (delegate () {
3535                                                 var assembly_obj = (e as AssemblyUnloadEvent).Assembly.GetAssemblyObject ();
3536                                         });
3537                                 continue;
3538                         } else {
3539                                 break;
3540                         }
3541                 }
3542                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
3543                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
3544
3545                 // Run past the unload
3546                 e = run_until ("domains_3");
3547
3548                 // Test access to unloaded types
3549                 // FIXME: Add an exception type for this
3550                 AssertThrows<Exception> (delegate {
3551                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
3552                         });
3553
3554                 // Check that .Domain is accessible for stack frames with native transitions
3555                 e = run_until ("called_from_invoke");
3556                 ThreadMirror.NativeTransitions = true;
3557                 foreach (var f in e.Thread.GetFrames ()) {
3558                         var dom = f.Domain;
3559                 }
3560         }
3561
3562         [Test]
3563         public void DynamicMethods () {
3564                 Event e = run_until ("dyn_call");
3565
3566                 var m = e.Thread.GetFrames ()[1].Method;
3567                 Assert.AreEqual ("dyn_method", m.Name);
3568
3569                 // Test access to IL
3570                 var body = m.GetMethodBody ();
3571
3572                 ILInstruction ins = body.Instructions [0];
3573                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
3574                 Assert.AreEqual ("FOO", ins.Operand);
3575         }
3576
3577         [Test]
3578         public void RefEmit () {
3579                 vm.Detach ();
3580
3581                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
3582
3583                 Event e = run_until ("ref_emit_call");
3584
3585                 var m = e.Thread.GetFrames ()[1].Method;
3586                 Assert.AreEqual ("ref_emit_method", m.Name);
3587
3588                 // Test access to IL
3589                 var body = m.GetMethodBody ();
3590
3591                 ILInstruction ins;
3592
3593                 ins = body.Instructions [0];
3594                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
3595                 Assert.AreEqual ("FOO", ins.Operand);
3596
3597                 ins = body.Instructions [1];
3598                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
3599                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
3600                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
3601         }
3602
3603         [Test]
3604         public void IsAttached () {
3605                 var f = entry_point.DeclaringType.GetField ("is_attached");
3606
3607                 Event e = run_until ("Main");
3608
3609                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
3610         }
3611
3612         [Test]
3613         public void StackTraceInNative () {
3614                 // Check that stack traces can be produced for threads in native code
3615                 vm.Detach ();
3616
3617                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
3618
3619                 var e = run_until ("frames_in_native");
3620
3621                 // FIXME: This is racy
3622                 vm.Resume ();
3623
3624                 Thread.Sleep (100);
3625
3626                 vm.Suspend ();
3627
3628                 StackFrame[] frames = e.Thread.GetFrames ();
3629
3630                 int frame_index = -1;
3631                 for (int i = 0; i < frames.Length; ++i) {
3632                         if (frames [i].Method.Name == "Sleep") {
3633                                 frame_index = i;
3634                                 break;
3635                         }
3636                 }
3637
3638                 Assert.IsTrue (frame_index != -1);
3639                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
3640                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
3641                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
3642
3643                 // Check that invokes are disabled for such threads
3644                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
3645
3646                 var m = t.GetMethod ("invoke_static_return_void");
3647                 AssertThrows<InvalidOperationException> (delegate {
3648                                 t.InvokeMethod (e.Thread, m, null);
3649                         });
3650
3651                 // Check that the frame info is invalidated
3652                 run_until ("frames_in_native_2");
3653
3654                 AssertThrows<InvalidStackFrameException> (delegate {
3655                                 Console.WriteLine (frames [frame_index].GetThis ());
3656                         });
3657         }
3658
3659         [Test]
3660         public void VirtualMachine_CreateEnumMirror () {
3661                 var e = run_until ("o1");
3662                 var frame = e.Thread.GetFrames () [0];
3663
3664                 object val = frame.GetThis ();
3665                 Assert.IsTrue (val is ObjectMirror);
3666                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
3667                 ObjectMirror o = (val as ObjectMirror);
3668
3669                 FieldInfoMirror field = o.Type.GetField ("field_enum");
3670                 Value f = o.GetValue (field);
3671                 TypeMirror enumType = (f as EnumMirror).Type;
3672
3673                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
3674                 f = o.GetValue (field);
3675                 Assert.AreEqual (1, (f as EnumMirror).Value);
3676
3677                 // Argument checking
3678                 AssertThrows<ArgumentNullException> (delegate () {
3679                                 vm.CreateEnumMirror (enumType, null);
3680                         });
3681
3682                 AssertThrows<ArgumentNullException> (delegate () {
3683                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
3684                         });
3685
3686                 // null value
3687                 AssertThrows<ArgumentException> (delegate () {
3688                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
3689                         });
3690
3691                 // value of a wrong type
3692                 AssertThrows<ArgumentException> (delegate () {
3693                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
3694                         });
3695         }
3696
3697         [Test]
3698         public void VirtualMachine_EnableEvents_Breakpoint () {
3699                 AssertThrows<ArgumentException> (delegate () {
3700                                 vm.EnableEvents (EventType.Breakpoint);
3701                         });
3702         }
3703
3704         [Test]
3705         public void SingleStepRegress654694 () {
3706                 int il_offset = -1;
3707
3708                 MethodMirror m = entry_point.DeclaringType.GetMethod ("ss_regress_654694");
3709                 foreach (Location l in m.Locations) {
3710                         if (l.ILOffset > 0 && il_offset == -1)
3711                                 il_offset = l.ILOffset;
3712                 }
3713
3714                 Event e = run_until ("ss_regress_654694");
3715
3716                 Assert.IsNotNull (m);
3717                 vm.SetBreakpoint (m, il_offset);
3718
3719                 vm.Resume ();
3720
3721                 e = GetNextEvent ();
3722                 Assert.IsTrue (e is BreakpointEvent);
3723
3724                 var req = create_step (e);
3725                 req.Depth = StepDepth.Over;
3726                 req.Size = StepSize.Line;
3727                 req.Enable ();
3728
3729                 vm.Resume ();
3730
3731                 e = GetNextEvent ();
3732                 Assert.IsTrue (e is StepEvent);
3733
3734                 req.Disable ();
3735         }
3736
3737         [Test]
3738         public void DebugBreak () {
3739                 vm.EnableEvents (EventType.UserBreak);
3740
3741                 run_until ("user");
3742
3743                 vm.Resume ();
3744                 var e = GetNextEvent ();
3745                 Assert.IsTrue (e is UserBreakEvent);
3746         }
3747
3748         [Test]
3749         public void DebugLog () {
3750                 vm.EnableEvents (EventType.UserLog);
3751
3752                 run_until ("user");
3753
3754                 vm.Resume ();
3755                 var e = GetNextEvent ();
3756                 Assert.IsTrue (e is UserLogEvent);
3757                 var le = e as UserLogEvent;
3758
3759                 Assert.AreEqual (5, le.Level);
3760                 Assert.AreEqual ("A", le.Category);
3761                 Assert.AreEqual ("B", le.Message);
3762         }
3763
3764         [Test]
3765         public void TypeGetMethodsByNameFlags () {
3766                 MethodMirror[] mm;
3767                 var assembly = entry_point.DeclaringType.Assembly;
3768                 var type = assembly.GetType ("Tests3");
3769
3770                 Assert.IsNotNull (type);
3771
3772                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Public, false);
3773                 Assert.AreEqual (1, mm.Length, "#1");
3774                 Assert.AreEqual ("M1", mm[0].Name, "#2");
3775
3776                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.NonPublic, false);
3777                 Assert.AreEqual (1, mm.Length, "#3");
3778                 Assert.AreEqual ("M2", mm[0].Name, "#4");
3779
3780                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public, false);
3781                 Assert.AreEqual (7, mm.Length, "#5"); //M3 plus Equals, GetHashCode, GetType, ToString, .ctor
3782
3783                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, false);
3784                 Assert.AreEqual (2, mm.Length, "#7");
3785
3786                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
3787                 Assert.AreEqual (1, mm.Length, "#9");
3788
3789                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
3790                 Assert.AreEqual (5, mm.Length, "#11");
3791
3792                 //Now with name
3793                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static | BindingFlags.Public, false);
3794                 Assert.AreEqual (1, mm.Length, "#12");
3795                 Assert.AreEqual ("M1", mm[0].Name, "#13");
3796
3797                 mm = type.GetMethodsByNameFlags ("m1", BindingFlags.Static | BindingFlags.Public, true);
3798                 Assert.AreEqual (1, mm.Length, "#14");
3799                 Assert.AreEqual ("M1", mm[0].Name, "#15");
3800
3801                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static  | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, false);
3802                 Assert.AreEqual (1, mm.Length, "#16");
3803                 Assert.AreEqual ("M1", mm[0].Name, "#17");
3804         }
3805
3806         [Test]
3807         [Category ("only88")]
3808         public void TypeLoadSourceFileFilter () {
3809                 Event e = run_until ("type_load");
3810
3811                 if (!vm.Version.AtLeast (2, 7))
3812                         return;
3813
3814                 string srcfile = (e as BreakpointEvent).Method.DeclaringType.GetSourceFiles (true)[0];
3815                 srcfile = srcfile.Replace ("dtest-app.cs", "TypeLoadClass.cs");
3816                 Assert.IsTrue (srcfile.Contains ("TypeLoadClass.cs"));
3817
3818                 var req = vm.CreateTypeLoadRequest ();
3819                 req.SourceFileFilter = new string [] { srcfile.ToUpper () };
3820                 req.Enable ();
3821
3822                 vm.Resume ();
3823                 e = GetNextEvent ();
3824                 Assert.IsTrue (e is TypeLoadEvent);
3825                 Assert.AreEqual ("TypeLoadClass", (e as TypeLoadEvent).Type.FullName);
3826         }
3827
3828         [Test]
3829         public void TypeLoadTypeNameFilter () {
3830                 Event e = run_until ("type_load");
3831
3832                 var req = vm.CreateTypeLoadRequest ();
3833                 req.TypeNameFilter = new string [] { "TypeLoadClass2" };
3834                 req.Enable ();
3835
3836                 vm.Resume ();
3837                 e = GetNextEvent ();
3838                 Assert.IsTrue (e is TypeLoadEvent);
3839                 Assert.AreEqual ("TypeLoadClass2", (e as TypeLoadEvent).Type.FullName);
3840         }
3841
3842         [Test]
3843         public void GetTypesForSourceFile () {
3844                 run_until ("user");
3845
3846                 var types = vm.GetTypesForSourceFile ("dtest-app.cs", false);
3847                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3848                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3849
3850                 types = vm.GetTypesForSourceFile ("DTEST-app.cs", true);
3851                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3852                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3853         }
3854
3855         [Test]
3856         public void GetTypesNamed () {
3857                 run_until ("user");
3858
3859                 var types = vm.GetTypes ("Tests", false);
3860                 Assert.AreEqual (1, types.Count);
3861                 Assert.AreEqual ("Tests", types [0].FullName);
3862
3863                 types = vm.GetTypes ("System.Exception", false);
3864                 Assert.AreEqual (1, types.Count);
3865                 Assert.AreEqual ("System.Exception", types [0].FullName);
3866         }
3867
3868         [Test]
3869         public void String_GetValue () {
3870                 // Embedded nulls
3871                 object val;
3872
3873                 // Reuse this test
3874                 var e = run_until ("arg2");
3875
3876                 var frame = e.Thread.GetFrames () [0];
3877
3878                 val = frame.GetArgument (6);
3879                 Assert.AreEqual ('\0'.ToString () + "A", (val as StringMirror).Value);
3880         }
3881
3882         [Test]
3883         public void String_GetChars () {
3884                 object val;
3885
3886                 // Reuse this test
3887                 var e = run_until ("arg2");
3888
3889                 var frame = e.Thread.GetFrames () [0];
3890
3891                 val = frame.GetArgument (0);
3892                 Assert.IsTrue (val is StringMirror);
3893                 AssertValue ("FOO", val);
3894                 var s = (val as StringMirror);
3895                 Assert.AreEqual (3, s.Length);
3896
3897                 var c = s.GetChars (0, 2);
3898                 Assert.AreEqual (2, c.Length);
3899                 Assert.AreEqual ('F', c [0]);
3900                 Assert.AreEqual ('O', c [1]);
3901
3902                 AssertThrows<ArgumentException> (delegate () {          
3903                                 s.GetChars (2, 2);
3904                         });
3905         }
3906
3907         [Test]
3908         public void GetInterfaces () {
3909                 var e = run_until ("arg2");
3910
3911                 var frame = e.Thread.GetFrames () [0];
3912
3913                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3914                 var ifaces = cl1.GetInterfaces ();
3915                 Assert.AreEqual (1, ifaces.Length);
3916                 Assert.AreEqual ("ITest", ifaces [0].Name);
3917
3918                 var cl2 = cl1.GetMethod ("Baz").ReturnType;
3919                 var ifaces2 = cl2.GetInterfaces ();
3920                 Assert.AreEqual (1, ifaces2.Length);
3921                 Assert.AreEqual ("ITest`1", ifaces2 [0].Name);
3922         }
3923
3924         [Test]
3925         public void GetInterfaceMap () {
3926                 var e = run_until ("arg2");
3927
3928                 var frame = e.Thread.GetFrames () [0];
3929
3930                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3931                 var iface = cl1.Assembly.GetType ("ITest");
3932                 var map = cl1.GetInterfaceMap (iface);
3933                 Assert.AreEqual (cl1, map.TargetType);
3934                 Assert.AreEqual (iface, map.InterfaceType);
3935                 Assert.AreEqual (2, map.InterfaceMethods.Length);
3936                 Assert.AreEqual (2, map.TargetMethods.Length);
3937         }
3938
3939         [Test]
3940         public void StackAlloc_Breakpoints_Regress2775 () {
3941                 // Check that breakpoints on arm don't overwrite stackalloc-ed memory
3942                 var e = run_until ("regress_2755");
3943
3944                 var frame = e.Thread.GetFrames () [0];
3945                 var m = e.Method;
3946                 // This breaks at the call site
3947                 vm.SetBreakpoint (m, m.Locations [2].ILOffset);
3948
3949                 vm.Resume ();
3950                 var e2 = GetNextEvent ();
3951                 Assert.IsTrue (e2 is BreakpointEvent);
3952
3953                 e = run_until ("regress_2755_3");
3954                 frame = e.Thread.GetFrames () [1];
3955                 var res = frame.GetValue (m.GetLocal ("sum"));
3956                 AssertValue (0, res);
3957         }
3958
3959         [Test]
3960         public void MethodInfo () {
3961                 Event e = run_until ("locals2");
3962
3963                 StackFrame frame = e.Thread.GetFrames () [0];
3964                 var m = frame.Method;
3965
3966                 Assert.IsTrue (m.IsGenericMethod);
3967                 Assert.IsFalse (m.IsGenericMethodDefinition);
3968
3969                 var args = m.GetGenericArguments ();
3970                 Assert.AreEqual (1, args.Length);
3971                 Assert.AreEqual ("String", args [0].Name);
3972
3973                 var gmd = m.GetGenericMethodDefinition ();
3974                 Assert.IsTrue (gmd.IsGenericMethod);
3975                 Assert.IsTrue (gmd.IsGenericMethodDefinition);
3976                 Assert.AreEqual (gmd, gmd.GetGenericMethodDefinition ());
3977
3978                 args = gmd.GetGenericArguments ();
3979                 Assert.AreEqual (1, args.Length);
3980                 Assert.AreEqual ("T", args [0].Name);
3981
3982                 var attrs = m.GetCustomAttributes (true);
3983                 Assert.AreEqual (1, attrs.Length);
3984                 Assert.AreEqual ("StateMachineAttribute", attrs [0].Constructor.DeclaringType.Name);
3985         }
3986
3987         [Test]
3988         public void UnhandledException () {
3989                 vm.Exit (0);
3990
3991                 Start (new string [] { "dtest-app.exe", "unhandled-exception" });
3992
3993                 var req = vm.CreateExceptionRequest (null, false, true);
3994                 req.Enable ();
3995
3996                 var e = run_until ("unhandled_exception");
3997                 vm.Resume ();
3998
3999                 var e2 = GetNextEvent ();
4000                 Assert.IsTrue (e2 is ExceptionEvent);
4001
4002                 vm.Exit (0);
4003                 vm = null;
4004         }
4005
4006         [Test]
4007         public void UnhandledException_2 () {
4008                 vm.Exit (0);
4009
4010                 Start (new string [] { "dtest-app.exe", "unhandled-exception-endinvoke" });
4011
4012                 var req = vm.CreateExceptionRequest (null, false, true);
4013                 req.Enable ();
4014
4015                 MethodMirror m = entry_point.DeclaringType.GetMethod ("unhandled_exception_endinvoke_2");
4016                 Assert.IsNotNull (m);
4017                 vm.SetBreakpoint (m, m.ILOffsets [0]);
4018
4019                 var e = run_until ("unhandled_exception_endinvoke");
4020                 vm.Resume ();
4021
4022                 var e2 = GetNextEvent ();
4023                 Assert.IsFalse (e2 is ExceptionEvent);
4024
4025                 vm.Exit (0);
4026                 vm = null;
4027         }
4028
4029         [Test]
4030         public void UnhandledExceptionUserCode () {
4031                 vm.Detach ();
4032
4033                 // Exceptions caught in non-user code are treated as unhandled
4034                 Start (new string [] { "dtest-app.exe", "unhandled-exception-user" });
4035
4036                 var req = vm.CreateExceptionRequest (null, false, true);
4037                 req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
4038                 req.Enable ();
4039
4040                 var e = run_until ("unhandled_exception_user");
4041                 vm.Resume ();
4042
4043                 var e2 = GetNextEvent ();
4044                 Assert.IsTrue (e2 is ExceptionEvent);
4045
4046                 vm.Exit (0);
4047                 vm = null;
4048         }
4049
4050         [Test]
4051         public void GCWhileSuspended () {
4052                 // Check that objects are kept alive during suspensions
4053                 Event e = run_until ("gc_suspend_1");
4054
4055                 MethodMirror m = entry_point.DeclaringType.GetMethod ("gc_suspend_invoke");
4056
4057                 var o = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
4058                 //Console.WriteLine (o);
4059
4060                 StackFrame frame = e.Thread.GetFrames () [0];
4061                 TypeMirror t = frame.Method.DeclaringType;
4062                 for (int i = 0; i < 10; ++i)
4063                         t.InvokeMethod (e.Thread, m, new Value [] { });
4064
4065                 // This throws an exception if the object is collected
4066                 long addr = o.Address;
4067
4068                 var o2 = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
4069                 Assert.IsNull (o2);
4070         }
4071
4072         [Test]
4073         public void MakeGenericMethod () {
4074                 Event e = run_until ("bp1");
4075
4076                 var intm = vm.RootDomain.GetCorrespondingType (typeof (int));
4077                 var stringm = vm.RootDomain.GetCorrespondingType (typeof (string));
4078                 var gm = entry_point.DeclaringType.GetMethod ("generic_method");
4079                 var res = gm.MakeGenericMethod (new TypeMirror [] { stringm });
4080                 var args = res.GetGenericArguments ();
4081                 Assert.AreEqual (1, args.Length);
4082                 Assert.AreEqual (stringm, args [0]);
4083
4084                 // Error checking
4085                 AssertThrows<ArgumentNullException> (delegate {
4086                                 gm.MakeGenericMethod (null);
4087                         });
4088                 AssertThrows<ArgumentNullException> (delegate {
4089                                 gm.MakeGenericMethod (new TypeMirror [] { null });
4090                         });
4091                 AssertThrows<ArgumentException> (delegate {
4092                                 gm.MakeGenericMethod (new TypeMirror [] { stringm, stringm });
4093                         });
4094                 AssertThrows<InvalidOperationException> (delegate {
4095                                 gm.MakeGenericMethod (new TypeMirror [] { intm });
4096                         });
4097                 AssertThrows<InvalidOperationException> (delegate {
4098                                 entry_point.DeclaringType.GetMethod ("Main").MakeGenericMethod (new TypeMirror [] { intm });
4099                         });
4100         }
4101
4102         [Test]
4103         public void InspectThreadSuspenedOnWaitOne () {
4104                 TearDown ();
4105                 Start (true, "dtest-app.exe", "wait-one" );
4106
4107                 ThreadMirror.NativeTransitions = true;
4108
4109                 var evt = run_until ("wait_one");
4110                 Assert.IsNotNull (evt, "#1");
4111
4112                 var thread = evt.Thread;
4113                 Assert.AreEqual (ThreadState.Running, thread.ThreadState, "#1.1");
4114
4115                 var frames = thread.GetFrames ();
4116                 Assert.IsNotNull (frames, "#2");
4117                 Assert.AreEqual (2, frames.Length, "#3");
4118                 Assert.AreEqual ("wait_one", frames [0].Method.Name, "#4");
4119                 Assert.AreEqual ("Main", frames [1].Method.Name, "#5");
4120
4121                 vm.Resume ();
4122
4123                 Thread.Sleep (500); //FIXME this is racy, maybe single step? or something?
4124
4125                 vm.Suspend ();
4126                 Assert.AreEqual (ThreadState.WaitSleepJoin, thread.ThreadState, "#6");
4127
4128                 frames = thread.GetFrames ();
4129                 Assert.AreEqual (8, frames.Length, "#7");
4130                 Assert.AreEqual ("WaitOne_internal", frames [0].Method.Name, "#8.0");
4131                 Assert.AreEqual ("WaitOneNative", frames [1].Method.Name, "#8.1");
4132                 Assert.AreEqual ("InternalWaitOne", frames [2].Method.Name, "#8.2");
4133                 Assert.AreEqual ("WaitOne", frames [3].Method.Name, "#8.3");
4134                 Assert.AreEqual ("WaitOne", frames [4].Method.Name, "#8.4");
4135                 Assert.AreEqual ("WaitOne", frames [5].Method.Name, "#8.5");
4136                 Assert.AreEqual ("wait_one", frames [6].Method.Name, "#8.6");
4137                 Assert.AreEqual ("Main", frames [7].Method.Name, "#8.7");
4138
4139                 var frame = frames [0];
4140                 Assert.IsTrue (frame.IsNativeTransition, "#11.1");
4141                 try {
4142                         frame.GetThis ();
4143                         Assert.Fail ("Known limitation - can't get info from m2n frames");
4144                 } catch (AbsentInformationException) {}
4145
4146                 frame = frames [3];
4147                 Assert.IsFalse (frame.IsNativeTransition, "#12.1");
4148                 var wait_one_this = frame.GetThis ();
4149                 Assert.IsNotNull (wait_one_this, "#12.2");
4150
4151                 frame = frames [6];
4152                 var locals = frame.GetVisibleVariables ();
4153                 Assert.AreEqual (1, locals.Count, "#13.1");
4154
4155                 var local_0 = frame.GetValue (locals [0]);
4156                 Assert.IsNotNull (local_0, "#13.2");
4157
4158                 Assert.AreEqual (wait_one_this, local_0, "#14.2");
4159         }
4160
4161         [Test]
4162         public void GetMethodBody () {
4163                 var bevent = run_until ("Main");
4164
4165                 var m = bevent.Method.DeclaringType.GetMethod ("get_IntProperty");
4166                 var body = m.GetMethodBody ();
4167                 foreach (var ins in body.Instructions) {
4168                         if (ins.OpCode == OpCodes.Ldfld) {
4169                                 var field = (FieldInfoMirror)ins.Operand;
4170                                 Assert.AreEqual ("field_i", field.Name);
4171                         }
4172                 }
4173         }
4174
4175         [Test]
4176         public void EvaluateMethod () {
4177                 var bevent = run_until ("evaluate_method_2");
4178
4179                 var m = bevent.Method.DeclaringType.GetMethod ("get_IntProperty");
4180
4181                 var this_obj = bevent.Thread.GetFrames ()[0].GetThis ();
4182                 var v = m.Evaluate (this_obj, null);
4183                 AssertValue (42, v);
4184         }
4185
4186         [Test]
4187         public void SetIP () {
4188                 var bevent = run_until ("set_ip_1");
4189
4190                 var invalid_loc = bevent.Thread.GetFrames ()[0].Location;
4191
4192                 var req = create_step (bevent);
4193                 var e = step_out ();
4194                 req.Disable ();
4195                 var frames = e.Thread.GetFrames ();
4196                 var locs = frames [0].Method.Locations;
4197
4198                 var next_loc = locs.First (l => (l.LineNumber == frames [0].Location.LineNumber + 3));
4199
4200                 e.Thread.SetIP (next_loc);
4201
4202                 /* Check that i ++; j = 5; was skipped */
4203                 bevent = run_until ("set_ip_2");
4204                 var f = bevent.Thread.GetFrames ()[1];
4205                 AssertValue (2, f.GetValue (f.Method.GetLocal ("i")));
4206                 AssertValue (0, f.GetValue (f.Method.GetLocal ("j")));
4207
4208                 // Error handling
4209                 AssertThrows<ArgumentNullException> (delegate {
4210                                 e.Thread.SetIP (null);
4211                         });
4212
4213                 AssertThrows<ArgumentException> (delegate {
4214                                 e.Thread.SetIP (invalid_loc);
4215                         });
4216         }
4217
4218         [Test]
4219         public void SetIPSingleStep () {
4220                 // Check that single stepping after set-ip steps from the new ip
4221                 var bevent = run_until ("set_ip_1");
4222
4223                 var invalid_loc = bevent.Thread.GetFrames ()[0].Location;
4224
4225                 var req = create_step (bevent);
4226                 req.Size = StepSize.Line;
4227                 var e = step_out ();
4228                 req.Disable ();
4229                 var frames = e.Thread.GetFrames ();
4230                 var locs = frames [0].Method.Locations;
4231                 var prev_loc = locs.First (l => (l.LineNumber == frames [0].Location.LineNumber - 1));
4232                 AssertValue (2, frames [0].GetValue (frames [0].Method.GetLocal ("i")));
4233
4234                 // Set back the ip to the first i ++; line
4235                 e.Thread.SetIP (prev_loc);
4236
4237                 e = step_over ();
4238                 var f = e.Thread.GetFrames ()[0];
4239                 AssertValue (3, f.GetValue (f.Method.GetLocal ("i")));
4240         }
4241
4242         [Test]
4243         public void NewInstanceNoCtor () {
4244                 var bevent = run_until ("Main");
4245
4246                 var stype = bevent.Method.DeclaringType.Assembly.GetType ("AStruct");
4247                 var obj = stype.NewInstance ();
4248                 Assert.IsTrue (obj is ObjectMirror);
4249                 Assert.AreEqual ("AStruct", (obj as ObjectMirror).Type.Name);
4250         }
4251
4252         [Test]
4253         public void StaticCtorFilterInCctor () {
4254                 // Check that single stepping when in a cctor only ignores
4255                 // other cctors, not the current one
4256                 var bevent = run_until ("step_filters");
4257
4258                 var assembly = entry_point.DeclaringType.Assembly;
4259                 var type = assembly.GetType ("Tests/ClassWithCctor");
4260                 var cctor = type.GetMethod (".cctor");
4261                 vm.SetBreakpoint (cctor, 0);
4262
4263                 vm.Resume ();
4264                 var e = GetNextEvent ();
4265                 Assert.IsTrue (e is BreakpointEvent);
4266
4267                 var req = create_step (e);
4268                 req.Filter = StepFilter.StaticCtor;
4269                 e = step_into ();
4270                 // Make sure we are still in the cctor
4271                 Assert.AreEqual (".cctor", e.Thread.GetFrames ()[0].Location.Method.Name);
4272         }
4273
4274         [Test]
4275         public void ThreadpoolIOsinglestep () {
4276                 TearDown ();
4277                 Start ("dtest-app.exe", "threadpool-io");
4278                 // This is a regression test for #42625.  It tests the
4279                 // interaction (particularly in coop GC) of the
4280                 // threadpool I/O mechanism and the soft debugger.
4281                 Event e = run_until ("threadpool_io");
4282                 // run until we sent the task half the bytes it
4283                 // expects, so that it blocks waiting for the rest.
4284                 e = run_until ("threadpool_bp");
4285                 var req = create_step (e);
4286                 e = step_out (); // leave threadpool_bp
4287                 e = step_out (); // leave threadpool_io
4288         }
4289
4290         [Test]
4291         // Uses a fixed port
4292         [Category("NotWorking")]
4293         public void Attach () {
4294                 vm.Exit (0);
4295
4296                 // Launch the app using server=y,suspend=n
4297                 var pi = CreateStartInfo (new string[] { "--debugger-agent=transport=dt_socket,address=127.0.0.1:10000,server=y,suspend=n", "dtest-app.exe", "attach" });
4298                 var process = Diag.Process.Start (pi);
4299
4300                 // Wait for the app to reach the Sleep () in attach ().
4301                 Thread.Sleep (1000);
4302                 var ep = new IPEndPoint (IPAddress.Loopback, 10000);
4303                 vm = VirtualMachineManager.Connect (ep);
4304
4305                 var load_req = vm.CreateAssemblyLoadRequest ();
4306                 load_req.Enable ();
4307                 vm.EnableEvents (EventType.TypeLoad);
4308
4309                 Event vmstart = GetNextEvent ();
4310                 Assert.AreEqual (EventType.VMStart, vmstart.EventType);
4311
4312                 // Get collected events
4313                 bool assembly_load_found = false;
4314                 bool type_load_found = false;
4315                 while (true) {
4316                         Event e = GetNextEvent ();
4317
4318                         // AssemblyLoad
4319                         if (e is AssemblyLoadEvent) {
4320                                 var assemblyload = e as AssemblyLoadEvent;
4321
4322                                 var amirror = assemblyload.Assembly;
4323
4324                                 if (amirror.GetName ().Name == "System.Transactions") {
4325                                         assembly_load_found = true;
4326                                         Assert.AreEqual ("domain", amirror.Domain.FriendlyName);
4327                                 }
4328
4329                                 if (amirror.GetName ().Name == "dtest-app")
4330                                         // Set a bp so we can break the event loop
4331                                         vm.SetBreakpoint (amirror.EntryPoint.DeclaringType.GetMethod ("attach_break"), 0);
4332                         }
4333                         if (e is TypeLoadEvent) {
4334                                 var typeload = e as TypeLoadEvent;
4335
4336                                 if (typeload.Type.Name == "GCSettings") {
4337                                         type_load_found = true;
4338                                         Assert.AreEqual ("domain", typeload.Type.Assembly.Domain.FriendlyName);
4339                                 }
4340                         }
4341
4342                         if (e is BreakpointEvent)
4343                                 break;
4344                 }
4345                 Assert.IsTrue (assembly_load_found);
4346                 Assert.IsTrue (type_load_found);
4347
4348                 vm.Exit (0);
4349                 vm = null;
4350         }
4351
4352 }
4353
4354 }