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