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