Merge pull request #3809 from lateralusX/jlorenss/win-api-family-support-cleanup
[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                                 continue;
3349                         } else {
3350                                 break;
3351                         }
3352                 }
3353                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
3354                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
3355
3356                 // Run past the unload
3357                 e = run_until ("domains_3");
3358
3359                 // Test access to unloaded types
3360                 // FIXME: Add an exception type for this
3361                 AssertThrows<Exception> (delegate {
3362                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
3363                         });
3364
3365                 // Check that .Domain is accessible for stack frames with native transitions
3366                 e = run_until ("called_from_invoke");
3367                 ThreadMirror.NativeTransitions = true;
3368                 foreach (var f in e.Thread.GetFrames ()) {
3369                         var dom = f.Domain;
3370                 }
3371         }
3372
3373         [Test]
3374         public void DynamicMethods () {
3375                 Event e = run_until ("dyn_call");
3376
3377                 var m = e.Thread.GetFrames ()[1].Method;
3378                 Assert.AreEqual ("dyn_method", m.Name);
3379
3380                 // Test access to IL
3381                 var body = m.GetMethodBody ();
3382
3383                 ILInstruction ins = body.Instructions [0];
3384                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
3385                 Assert.AreEqual ("FOO", ins.Operand);
3386         }
3387
3388         [Test]
3389         public void RefEmit () {
3390                 vm.Detach ();
3391
3392                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
3393
3394                 Event e = run_until ("ref_emit_call");
3395
3396                 var m = e.Thread.GetFrames ()[1].Method;
3397                 Assert.AreEqual ("ref_emit_method", m.Name);
3398
3399                 // Test access to IL
3400                 var body = m.GetMethodBody ();
3401
3402                 ILInstruction ins;
3403
3404                 ins = body.Instructions [0];
3405                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
3406                 Assert.AreEqual ("FOO", ins.Operand);
3407
3408                 ins = body.Instructions [1];
3409                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
3410                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
3411                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
3412         }
3413
3414         [Test]
3415         public void IsAttached () {
3416                 var f = entry_point.DeclaringType.GetField ("is_attached");
3417
3418                 Event e = run_until ("Main");
3419
3420                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
3421         }
3422
3423         [Test]
3424         public void StackTraceInNative () {
3425                 // Check that stack traces can be produced for threads in native code
3426                 vm.Detach ();
3427
3428                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
3429
3430                 var e = run_until ("frames_in_native");
3431
3432                 // FIXME: This is racy
3433                 vm.Resume ();
3434
3435                 Thread.Sleep (100);
3436
3437                 vm.Suspend ();
3438
3439                 StackFrame[] frames = e.Thread.GetFrames ();
3440
3441                 int frame_index = -1;
3442                 for (int i = 0; i < frames.Length; ++i) {
3443                         if (frames [i].Method.Name == "Sleep") {
3444                                 frame_index = i;
3445                                 break;
3446                         }
3447                 }
3448
3449                 Assert.IsTrue (frame_index != -1);
3450                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
3451                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
3452                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
3453
3454                 // Check that invokes are disabled for such threads
3455                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
3456
3457                 var m = t.GetMethod ("invoke_static_return_void");
3458                 AssertThrows<InvalidOperationException> (delegate {
3459                                 t.InvokeMethod (e.Thread, m, null);
3460                         });
3461
3462                 // Check that the frame info is invalidated
3463                 run_until ("frames_in_native_2");
3464
3465                 AssertThrows<InvalidStackFrameException> (delegate {
3466                                 Console.WriteLine (frames [frame_index].GetThis ());
3467                         });
3468         }
3469
3470         [Test]
3471         public void VirtualMachine_CreateEnumMirror () {
3472                 var e = run_until ("o1");
3473                 var frame = e.Thread.GetFrames () [0];
3474
3475                 object val = frame.GetThis ();
3476                 Assert.IsTrue (val is ObjectMirror);
3477                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
3478                 ObjectMirror o = (val as ObjectMirror);
3479
3480                 FieldInfoMirror field = o.Type.GetField ("field_enum");
3481                 Value f = o.GetValue (field);
3482                 TypeMirror enumType = (f as EnumMirror).Type;
3483
3484                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
3485                 f = o.GetValue (field);
3486                 Assert.AreEqual (1, (f as EnumMirror).Value);
3487
3488                 // Argument checking
3489                 AssertThrows<ArgumentNullException> (delegate () {
3490                                 vm.CreateEnumMirror (enumType, null);
3491                         });
3492
3493                 AssertThrows<ArgumentNullException> (delegate () {
3494                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
3495                         });
3496
3497                 // null value
3498                 AssertThrows<ArgumentException> (delegate () {
3499                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
3500                         });
3501
3502                 // value of a wrong type
3503                 AssertThrows<ArgumentException> (delegate () {
3504                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
3505                         });
3506         }
3507
3508         [Test]
3509         public void VirtualMachine_EnableEvents_Breakpoint () {
3510                 AssertThrows<ArgumentException> (delegate () {
3511                                 vm.EnableEvents (EventType.Breakpoint);
3512                         });
3513         }
3514
3515         [Test]
3516         public void SingleStepRegress654694 () {
3517                 int il_offset = -1;
3518
3519                 MethodMirror m = entry_point.DeclaringType.GetMethod ("ss_regress_654694");
3520                 foreach (Location l in m.Locations) {
3521                         if (l.ILOffset > 0 && il_offset == -1)
3522                                 il_offset = l.ILOffset;
3523                 }
3524
3525                 Event e = run_until ("ss_regress_654694");
3526
3527                 Assert.IsNotNull (m);
3528                 vm.SetBreakpoint (m, il_offset);
3529
3530                 vm.Resume ();
3531
3532                 e = GetNextEvent ();
3533                 Assert.IsTrue (e is BreakpointEvent);
3534
3535                 var req = create_step (e);
3536                 req.Depth = StepDepth.Over;
3537                 req.Size = StepSize.Line;
3538                 req.Enable ();
3539
3540                 vm.Resume ();
3541
3542                 e = GetNextEvent ();
3543                 Assert.IsTrue (e is StepEvent);
3544
3545                 req.Disable ();
3546         }
3547
3548         [Test]
3549         public void DebugBreak () {
3550                 vm.EnableEvents (EventType.UserBreak);
3551
3552                 run_until ("user");
3553
3554                 vm.Resume ();
3555                 var e = GetNextEvent ();
3556                 Assert.IsTrue (e is UserBreakEvent);
3557         }
3558
3559         [Test]
3560         public void DebugLog () {
3561                 vm.EnableEvents (EventType.UserLog);
3562
3563                 run_until ("user");
3564
3565                 vm.Resume ();
3566                 var e = GetNextEvent ();
3567                 Assert.IsTrue (e is UserLogEvent);
3568                 var le = e as UserLogEvent;
3569
3570                 Assert.AreEqual (5, le.Level);
3571                 Assert.AreEqual ("A", le.Category);
3572                 Assert.AreEqual ("B", le.Message);
3573         }
3574
3575         [Test]
3576         public void TypeGetMethodsByNameFlags () {
3577                 MethodMirror[] mm;
3578                 var assembly = entry_point.DeclaringType.Assembly;
3579                 var type = assembly.GetType ("Tests3");
3580
3581                 Assert.IsNotNull (type);
3582
3583                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Public, false);
3584                 Assert.AreEqual (1, mm.Length, "#1");
3585                 Assert.AreEqual ("M1", mm[0].Name, "#2");
3586
3587                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.NonPublic, false);
3588                 Assert.AreEqual (1, mm.Length, "#3");
3589                 Assert.AreEqual ("M2", mm[0].Name, "#4");
3590
3591                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public, false);
3592                 Assert.AreEqual (7, mm.Length, "#5"); //M3 plus Equals, GetHashCode, GetType, ToString, .ctor
3593
3594                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, false);
3595                 Assert.AreEqual (2, mm.Length, "#7");
3596
3597                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
3598                 Assert.AreEqual (1, mm.Length, "#9");
3599
3600                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
3601                 Assert.AreEqual (5, mm.Length, "#11");
3602
3603                 //Now with name
3604                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static | BindingFlags.Public, false);
3605                 Assert.AreEqual (1, mm.Length, "#12");
3606                 Assert.AreEqual ("M1", mm[0].Name, "#13");
3607
3608                 mm = type.GetMethodsByNameFlags ("m1", BindingFlags.Static | BindingFlags.Public, true);
3609                 Assert.AreEqual (1, mm.Length, "#14");
3610                 Assert.AreEqual ("M1", mm[0].Name, "#15");
3611
3612                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static  | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, false);
3613                 Assert.AreEqual (1, mm.Length, "#16");
3614                 Assert.AreEqual ("M1", mm[0].Name, "#17");
3615         }
3616
3617         [Test]
3618         [Category ("only88")]
3619         public void TypeLoadSourceFileFilter () {
3620                 Event e = run_until ("type_load");
3621
3622                 if (!vm.Version.AtLeast (2, 7))
3623                         return;
3624
3625                 string srcfile = (e as BreakpointEvent).Method.DeclaringType.GetSourceFiles (true)[0];
3626                 srcfile = srcfile.Replace ("dtest-app.cs", "TypeLoadClass.cs");
3627                 Assert.IsTrue (srcfile.Contains ("TypeLoadClass.cs"));
3628
3629                 var req = vm.CreateTypeLoadRequest ();
3630                 req.SourceFileFilter = new string [] { srcfile.ToUpper () };
3631                 req.Enable ();
3632
3633                 vm.Resume ();
3634                 e = GetNextEvent ();
3635                 Assert.IsTrue (e is TypeLoadEvent);
3636                 Assert.AreEqual ("TypeLoadClass", (e as TypeLoadEvent).Type.FullName);
3637         }
3638
3639         [Test]
3640         public void TypeLoadTypeNameFilter () {
3641                 Event e = run_until ("type_load");
3642
3643                 var req = vm.CreateTypeLoadRequest ();
3644                 req.TypeNameFilter = new string [] { "TypeLoadClass2" };
3645                 req.Enable ();
3646
3647                 vm.Resume ();
3648                 e = GetNextEvent ();
3649                 Assert.IsTrue (e is TypeLoadEvent);
3650                 Assert.AreEqual ("TypeLoadClass2", (e as TypeLoadEvent).Type.FullName);
3651         }
3652
3653         [Test]
3654         public void GetTypesForSourceFile () {
3655                 run_until ("user");
3656
3657                 var types = vm.GetTypesForSourceFile ("dtest-app.cs", false);
3658                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3659                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3660
3661                 types = vm.GetTypesForSourceFile ("DTEST-app.cs", true);
3662                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3663                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3664         }
3665
3666         [Test]
3667         public void GetTypesNamed () {
3668                 run_until ("user");
3669
3670                 var types = vm.GetTypes ("Tests", false);
3671                 Assert.AreEqual (1, types.Count);
3672                 Assert.AreEqual ("Tests", types [0].FullName);
3673
3674                 types = vm.GetTypes ("System.Exception", false);
3675                 Assert.AreEqual (1, types.Count);
3676                 Assert.AreEqual ("System.Exception", types [0].FullName);
3677         }
3678
3679         [Test]
3680         public void String_GetValue () {
3681                 // Embedded nulls
3682                 object val;
3683
3684                 // Reuse this test
3685                 var e = run_until ("arg2");
3686
3687                 var frame = e.Thread.GetFrames () [0];
3688
3689                 val = frame.GetArgument (6);
3690                 Assert.AreEqual ('\0'.ToString () + "A", (val as StringMirror).Value);
3691         }
3692
3693         [Test]
3694         public void String_GetChars () {
3695                 object val;
3696
3697                 // Reuse this test
3698                 var e = run_until ("arg2");
3699
3700                 var frame = e.Thread.GetFrames () [0];
3701
3702                 val = frame.GetArgument (0);
3703                 Assert.IsTrue (val is StringMirror);
3704                 AssertValue ("FOO", val);
3705                 var s = (val as StringMirror);
3706                 Assert.AreEqual (3, s.Length);
3707
3708                 var c = s.GetChars (0, 2);
3709                 Assert.AreEqual (2, c.Length);
3710                 Assert.AreEqual ('F', c [0]);
3711                 Assert.AreEqual ('O', c [1]);
3712
3713                 AssertThrows<ArgumentException> (delegate () {          
3714                                 s.GetChars (2, 2);
3715                         });
3716         }
3717
3718         [Test]
3719         public void GetInterfaces () {
3720                 var e = run_until ("arg2");
3721
3722                 var frame = e.Thread.GetFrames () [0];
3723
3724                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3725                 var ifaces = cl1.GetInterfaces ();
3726                 Assert.AreEqual (1, ifaces.Length);
3727                 Assert.AreEqual ("ITest", ifaces [0].Name);
3728
3729                 var cl2 = cl1.GetMethod ("Baz").ReturnType;
3730                 var ifaces2 = cl2.GetInterfaces ();
3731                 Assert.AreEqual (1, ifaces2.Length);
3732                 Assert.AreEqual ("ITest`1", ifaces2 [0].Name);
3733         }
3734
3735         [Test]
3736         public void GetInterfaceMap () {
3737                 var e = run_until ("arg2");
3738
3739                 var frame = e.Thread.GetFrames () [0];
3740
3741                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3742                 var iface = cl1.Assembly.GetType ("ITest");
3743                 var map = cl1.GetInterfaceMap (iface);
3744                 Assert.AreEqual (cl1, map.TargetType);
3745                 Assert.AreEqual (iface, map.InterfaceType);
3746                 Assert.AreEqual (2, map.InterfaceMethods.Length);
3747                 Assert.AreEqual (2, map.TargetMethods.Length);
3748         }
3749
3750         [Test]
3751         public void StackAlloc_Breakpoints_Regress2775 () {
3752                 // Check that breakpoints on arm don't overwrite stackalloc-ed memory
3753                 var e = run_until ("regress_2755");
3754
3755                 var frame = e.Thread.GetFrames () [0];
3756                 var m = e.Method;
3757                 // This breaks at the call site
3758                 vm.SetBreakpoint (m, m.Locations [2].ILOffset);
3759
3760                 vm.Resume ();
3761                 var e2 = GetNextEvent ();
3762                 Assert.IsTrue (e2 is BreakpointEvent);
3763
3764                 e = run_until ("regress_2755_3");
3765                 frame = e.Thread.GetFrames () [1];
3766                 var res = frame.GetValue (m.GetLocal ("sum"));
3767                 AssertValue (0, res);
3768         }
3769
3770         [Test]
3771         public void MethodInfo () {
3772                 Event e = run_until ("locals2");
3773
3774                 StackFrame frame = e.Thread.GetFrames () [0];
3775                 var m = frame.Method;
3776
3777                 Assert.IsTrue (m.IsGenericMethod);
3778                 Assert.IsFalse (m.IsGenericMethodDefinition);
3779
3780                 var args = m.GetGenericArguments ();
3781                 Assert.AreEqual (1, args.Length);
3782                 Assert.AreEqual ("String", args [0].Name);
3783
3784                 var gmd = m.GetGenericMethodDefinition ();
3785                 Assert.IsTrue (gmd.IsGenericMethod);
3786                 Assert.IsTrue (gmd.IsGenericMethodDefinition);
3787                 Assert.AreEqual (gmd, gmd.GetGenericMethodDefinition ());
3788
3789                 args = gmd.GetGenericArguments ();
3790                 Assert.AreEqual (1, args.Length);
3791                 Assert.AreEqual ("T", args [0].Name);
3792
3793                 var attrs = m.GetCustomAttributes (true);
3794                 Assert.AreEqual (1, attrs.Length);
3795                 Assert.AreEqual ("StateMachineAttribute", attrs [0].Constructor.DeclaringType.Name);
3796         }
3797
3798         [Test]
3799         public void UnhandledException () {
3800                 vm.Exit (0);
3801
3802                 Start (new string [] { "dtest-app.exe", "unhandled-exception" });
3803
3804                 var req = vm.CreateExceptionRequest (null, false, true);
3805                 req.Enable ();
3806
3807                 var e = run_until ("unhandled_exception");
3808                 vm.Resume ();
3809
3810                 var e2 = GetNextEvent ();
3811                 Assert.IsTrue (e2 is ExceptionEvent);
3812
3813                 vm.Exit (0);
3814                 vm = null;
3815         }
3816
3817         [Test]
3818         public void UnhandledException_2 () {
3819                 vm.Exit (0);
3820
3821                 Start (new string [] { "dtest-app.exe", "unhandled-exception-endinvoke" });
3822
3823                 var req = vm.CreateExceptionRequest (null, false, true);
3824                 req.Enable ();
3825
3826                 MethodMirror m = entry_point.DeclaringType.GetMethod ("unhandled_exception_endinvoke_2");
3827                 Assert.IsNotNull (m);
3828                 vm.SetBreakpoint (m, m.ILOffsets [0]);
3829
3830                 var e = run_until ("unhandled_exception_endinvoke");
3831                 vm.Resume ();
3832
3833                 var e2 = GetNextEvent ();
3834                 Assert.IsFalse (e2 is ExceptionEvent);
3835
3836                 vm.Exit (0);
3837                 vm = null;
3838         }
3839
3840         [Test]
3841         public void UnhandledExceptionUserCode () {
3842                 vm.Detach ();
3843
3844                 // Exceptions caught in non-user code are treated as unhandled
3845                 Start (new string [] { "dtest-app.exe", "unhandled-exception-user" });
3846
3847                 var req = vm.CreateExceptionRequest (null, false, true);
3848                 req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
3849                 req.Enable ();
3850
3851                 var e = run_until ("unhandled_exception_user");
3852                 vm.Resume ();
3853
3854                 var e2 = GetNextEvent ();
3855                 Assert.IsTrue (e2 is ExceptionEvent);
3856
3857                 vm.Exit (0);
3858                 vm = null;
3859         }
3860
3861         [Test]
3862         public void GCWhileSuspended () {
3863                 // Check that objects are kept alive during suspensions
3864                 Event e = run_until ("gc_suspend_1");
3865
3866                 MethodMirror m = entry_point.DeclaringType.GetMethod ("gc_suspend_invoke");
3867
3868                 var o = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3869                 //Console.WriteLine (o);
3870
3871                 StackFrame frame = e.Thread.GetFrames () [0];
3872                 TypeMirror t = frame.Method.DeclaringType;
3873                 for (int i = 0; i < 10; ++i)
3874                         t.InvokeMethod (e.Thread, m, new Value [] { });
3875
3876                 // This throws an exception if the object is collected
3877                 long addr = o.Address;
3878
3879                 var o2 = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3880                 Assert.IsNull (o2);
3881         }
3882
3883         [Test]
3884         public void MakeGenericMethod () {
3885                 Event e = run_until ("bp1");
3886
3887                 var intm = vm.RootDomain.GetCorrespondingType (typeof (int));
3888                 var stringm = vm.RootDomain.GetCorrespondingType (typeof (string));
3889                 var gm = entry_point.DeclaringType.GetMethod ("generic_method");
3890                 var res = gm.MakeGenericMethod (new TypeMirror [] { stringm });
3891                 var args = res.GetGenericArguments ();
3892                 Assert.AreEqual (1, args.Length);
3893                 Assert.AreEqual (stringm, args [0]);
3894
3895                 // Error checking
3896                 AssertThrows<ArgumentNullException> (delegate {
3897                                 gm.MakeGenericMethod (null);
3898                         });
3899                 AssertThrows<ArgumentNullException> (delegate {
3900                                 gm.MakeGenericMethod (new TypeMirror [] { null });
3901                         });
3902                 AssertThrows<ArgumentException> (delegate {
3903                                 gm.MakeGenericMethod (new TypeMirror [] { stringm, stringm });
3904                         });
3905                 AssertThrows<InvalidOperationException> (delegate {
3906                                 gm.MakeGenericMethod (new TypeMirror [] { intm });
3907                         });
3908                 AssertThrows<InvalidOperationException> (delegate {
3909                                 entry_point.DeclaringType.GetMethod ("Main").MakeGenericMethod (new TypeMirror [] { intm });
3910                         });
3911         }
3912
3913         [Test]
3914         public void InspectThreadSuspenedOnWaitOne () {
3915                 TearDown ();
3916                 Start (true, "dtest-app.exe", "wait-one" );
3917
3918                 ThreadMirror.NativeTransitions = true;
3919
3920                 var evt = run_until ("wait_one");
3921                 Assert.IsNotNull (evt, "#1");
3922
3923                 var thread = evt.Thread;
3924                 Assert.AreEqual (ThreadState.Running, thread.ThreadState, "#1.1");
3925
3926                 var frames = thread.GetFrames ();
3927                 Assert.IsNotNull (frames, "#2");
3928                 Assert.AreEqual (2, frames.Length, "#3");
3929                 Assert.AreEqual ("wait_one", frames [0].Method.Name, "#4");
3930                 Assert.AreEqual ("Main", frames [1].Method.Name, "#5");
3931
3932                 vm.Resume ();
3933
3934                 Thread.Sleep (500); //FIXME this is racy, maybe single step? or something?
3935
3936                 vm.Suspend ();
3937                 Assert.AreEqual (ThreadState.WaitSleepJoin, thread.ThreadState, "#6");
3938
3939                 frames = thread.GetFrames ();
3940                 Assert.AreEqual (8, frames.Length, "#7");
3941                 Assert.AreEqual ("WaitOne_internal", frames [0].Method.Name, "#8.0");
3942                 Assert.AreEqual ("WaitOneNative", frames [1].Method.Name, "#8.1");
3943                 Assert.AreEqual ("InternalWaitOne", frames [2].Method.Name, "#8.2");
3944                 Assert.AreEqual ("WaitOne", frames [3].Method.Name, "#8.3");
3945                 Assert.AreEqual ("WaitOne", frames [4].Method.Name, "#8.4");
3946                 Assert.AreEqual ("WaitOne", frames [5].Method.Name, "#8.5");
3947                 Assert.AreEqual ("wait_one", frames [6].Method.Name, "#8.6");
3948                 Assert.AreEqual ("Main", frames [7].Method.Name, "#8.7");
3949
3950                 var frame = frames [0];
3951                 Assert.IsTrue (frame.IsNativeTransition, "#11.1");
3952                 try {
3953                         frame.GetThis ();
3954                         Assert.Fail ("Known limitation - can't get info from m2n frames");
3955                 } catch (AbsentInformationException) {}
3956
3957                 frame = frames [3];
3958                 Assert.IsFalse (frame.IsNativeTransition, "#12.1");
3959                 var wait_one_this = frame.GetThis ();
3960                 Assert.IsNotNull (wait_one_this, "#12.2");
3961
3962                 frame = frames [6];
3963                 var locals = frame.GetVisibleVariables ();
3964                 Assert.AreEqual (1, locals.Count, "#13.1");
3965
3966                 var local_0 = frame.GetValue (locals [0]);
3967                 Assert.IsNotNull (local_0, "#13.2");
3968
3969                 Assert.AreEqual (wait_one_this, local_0, "#14.2");
3970         }
3971
3972         [Test]
3973         public void GetMethodBody () {
3974                 var bevent = run_until ("Main");
3975
3976                 var m = bevent.Method.DeclaringType.GetMethod ("get_IntProperty");
3977                 var body = m.GetMethodBody ();
3978                 foreach (var ins in body.Instructions) {
3979                         if (ins.OpCode == OpCodes.Ldfld) {
3980                                 var field = (FieldInfoMirror)ins.Operand;
3981                                 Assert.AreEqual ("field_i", field.Name);
3982                         }
3983                 }
3984         }
3985
3986         [Test]
3987         public void EvaluateMethod () {
3988                 var bevent = run_until ("evaluate_method_2");
3989
3990                 var m = bevent.Method.DeclaringType.GetMethod ("get_IntProperty");
3991
3992                 var this_obj = bevent.Thread.GetFrames ()[0].GetThis ();
3993                 var v = m.Evaluate (this_obj, null);
3994                 AssertValue (42, v);
3995         }
3996
3997         [Test]
3998         public void SetIP () {
3999                 var bevent = run_until ("set_ip_1");
4000
4001                 var invalid_loc = bevent.Thread.GetFrames ()[0].Location;
4002
4003                 var req = create_step (bevent);
4004                 var e = step_out ();
4005                 req.Disable ();
4006                 var frames = e.Thread.GetFrames ();
4007                 var locs = frames [0].Method.Locations;
4008                 var next_loc = locs.First (l => (l.LineNumber == frames [0].Location.LineNumber + 2));
4009
4010                 e.Thread.SetIP (next_loc);
4011
4012                 /* Check that i ++; j = 5; was skipped */
4013                 bevent = run_until ("set_ip_2");
4014                 var f = bevent.Thread.GetFrames ()[1];
4015                 AssertValue (2, f.GetValue (f.Method.GetLocal ("i")));
4016                 AssertValue (0, f.GetValue (f.Method.GetLocal ("j")));
4017
4018                 // Error handling
4019                 AssertThrows<ArgumentNullException> (delegate {
4020                                 e.Thread.SetIP (null);
4021                         });
4022
4023                 AssertThrows<ArgumentException> (delegate {
4024                                 e.Thread.SetIP (invalid_loc);
4025                         });
4026         }
4027
4028         [Test]
4029         public void SetIPSingleStep () {
4030                 // Check that single stepping after set-ip steps from the new ip
4031                 var bevent = run_until ("set_ip_1");
4032
4033                 var invalid_loc = bevent.Thread.GetFrames ()[0].Location;
4034
4035                 var req = create_step (bevent);
4036                 req.Size = StepSize.Line;
4037                 var e = step_out ();
4038                 req.Disable ();
4039                 var frames = e.Thread.GetFrames ();
4040                 var locs = frames [0].Method.Locations;
4041                 var prev_loc = locs.First (l => (l.LineNumber == frames [0].Location.LineNumber - 3));
4042                 AssertValue (2, frames [0].GetValue (frames [0].Method.GetLocal ("i")));
4043
4044                 // Set back the ip to the first i ++; line
4045                 e.Thread.SetIP (prev_loc);
4046
4047                 e = step_over ();
4048                 var f = e.Thread.GetFrames ()[0];
4049                 AssertValue (3, f.GetValue (f.Method.GetLocal ("i")));
4050         }
4051
4052         [Test]
4053         public void NewInstanceNoCtor () {
4054                 var bevent = run_until ("Main");
4055
4056                 var stype = bevent.Method.DeclaringType.Assembly.GetType ("AStruct");
4057                 var obj = stype.NewInstance ();
4058                 Assert.IsTrue (obj is ObjectMirror);
4059                 Assert.AreEqual ("AStruct", (obj as ObjectMirror).Type.Name);
4060         }
4061
4062         [Test]
4063         public void StaticCtorFilterInCctor () {
4064                 // Check that single stepping when in a cctor only ignores
4065                 // other cctors, not the current one
4066                 var bevent = run_until ("step_filters");
4067
4068                 var assembly = entry_point.DeclaringType.Assembly;
4069                 var type = assembly.GetType ("Tests/ClassWithCctor");
4070                 var cctor = type.GetMethod (".cctor");
4071                 vm.SetBreakpoint (cctor, 0);
4072
4073                 vm.Resume ();
4074                 var e = vm.GetNextEvent ();
4075                 Assert.IsTrue (e is BreakpointEvent);
4076
4077                 var req = create_step (e);
4078                 req.Filter = StepFilter.StaticCtor;
4079                 e = step_into ();
4080                 // Make sure we are still in the cctor
4081                 Assert.AreEqual (".cctor", e.Thread.GetFrames ()[0].Location.Method.Name);
4082         }
4083
4084         [Test]
4085         public void ThreadpoolIOsinglestep () {
4086                 TearDown ();
4087                 Start ("dtest-app.exe", "threadpool-io");
4088                 // This is a regression test for #42625.  It tests the
4089                 // interaction (particularly in coop GC) of the
4090                 // threadpool I/O mechanism and the soft debugger.
4091                 Event e = run_until ("threadpool_io");
4092                 // run until we sent the task half the bytes it
4093                 // expects, so that it blocks waiting for the rest.
4094                 e = run_until ("threadpool_bp");
4095                 var req = create_step (e);
4096                 e = step_out (); // leave threadpool_bp
4097                 e = step_out (); // leave threadpool_io
4098         }
4099 }
4100
4101 }