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