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