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