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