Merge pull request #600 from tr8dr/master
[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         Event GetNextEvent () {
46                 var es = vm.GetNextEventSet ();
47                 Assert.AreEqual (1, es.Events.Length);
48                 return es [0];
49         }
50
51         void Start (params string[] args) {
52                 Start (false, args);
53         }
54
55         void Start (bool forceExit, params string[] args) {
56                 this.forceExit = forceExit;
57
58                 if (!listening) {
59                         var pi = new Diag.ProcessStartInfo ();
60
61                         if (runtime != null)
62                                 pi.FileName = runtime;
63                         else
64                                 pi.FileName = "mono";
65                         pi.Arguments = String.Join (" ", args);
66                         vm = VirtualMachineManager.Launch (pi, new LaunchOptions { AgentArgs = agent_args });
67                 } else {
68                         var ep = new IPEndPoint (IPAddress.Any, 10000);
69                         Console.WriteLine ("Listening on " + ep + "...");
70                         vm = VirtualMachineManager.Listen (ep);
71                 }
72
73                 var load_req = vm.CreateAssemblyLoadRequest ();
74                 load_req.Enable ();
75
76                 Event vmstart = GetNextEvent ();
77                 Assert.AreEqual (EventType.VMStart, vmstart.EventType);
78
79                 vm.Resume ();
80
81                 entry_point = null;
82                 step_req = null;
83
84                 Event e;
85
86                 /* Find out the entry point */
87                 while (true) {
88                         e = GetNextEvent ();
89
90                         if (e is AssemblyLoadEvent) {
91                                 AssemblyLoadEvent ae = (AssemblyLoadEvent)e;
92                                 entry_point = ae.Assembly.EntryPoint;
93                                 if (entry_point != null)
94                                         break;
95                         }
96
97                         vm.Resume ();
98                 }
99
100                 load_req.Disable ();
101         }
102
103         BreakpointEvent run_until (string name) {
104                 // String
105                 MethodMirror m = entry_point.DeclaringType.GetMethod (name);
106                 Assert.IsNotNull (m);
107                 //Console.WriteLine ("X: " + name + " " + m.ILOffsets.Count + " " + m.Locations.Count);
108                 vm.SetBreakpoint (m, m.ILOffsets [0]);
109
110                 Event e = null;
111
112                 while (true) {
113                         vm.Resume ();
114                         e = GetNextEvent ();
115                         if (e is BreakpointEvent)
116                                 break;
117                 }
118
119                 Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
120                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
121
122                 return (e as BreakpointEvent);
123         }
124
125         Event single_step (ThreadMirror t) {
126                 var req = vm.CreateStepRequest (t);
127                 req.Enable ();
128
129                 vm.Resume ();
130                 Event e = GetNextEvent ();
131                 Assert.IsTrue (e is StepEvent);
132
133                 req.Disable ();
134
135                 return e;
136         }
137
138         void check_arg_val (StackFrame frame, int pos, Type type, object eval) {
139                 object val = frame.GetArgument (pos);
140                 Assert.IsTrue (val is PrimitiveValue);
141                 object v = (val as PrimitiveValue).Value;
142                 Assert.AreEqual (type, v.GetType ());
143                 if (eval is float)
144                         Assert.IsTrue (Math.Abs ((float)eval - (float)v) < 0.0001);
145                 else if (eval is double)
146                         Assert.IsTrue (Math.Abs ((double)eval - (double)v) < 0.0001);
147                 else
148                         Assert.AreEqual (eval, v);
149         }
150
151         void AssertValue (object expected, object val) {
152                 if (expected is string) {
153                         Assert.IsTrue (val is StringMirror);
154                         Assert.AreEqual (expected, (val as StringMirror).Value);
155                 } else if (val is StructMirror && (val as StructMirror).Type.Name == "IntPtr") {
156                         AssertValue (expected, (val as StructMirror).Fields [0]);
157                 } else {
158                         Assert.IsTrue (val is PrimitiveValue);
159                         Assert.AreEqual (expected, (val as PrimitiveValue).Value);
160                 }
161         }
162
163         [SetUp]
164         public void SetUp () {
165                 ThreadMirror.NativeTransitions = false;
166                 Start (new string [] { "dtest-app.exe" });
167         }
168
169         [TearDown]
170         public void TearDown () {
171                 if (vm == null)
172                         return;
173
174                 if (step_req != null)
175                         step_req.Disable ();
176
177                 vm.Resume ();
178                 if (forceExit)
179                         vm.Exit (0);
180
181                 while (true) {
182                         Event e = GetNextEvent ();
183
184                         if (e is VMDeathEvent)
185                                 break;
186
187                         vm.Resume ();
188                 }
189                 vm = null;
190         }
191
192         [Test]
193         public void SimpleBreakpoint () {
194                 Event e;
195
196                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp1");
197                 Assert.IsNotNull (m);
198
199                 vm.SetBreakpoint (m, 0);
200
201                 vm.Resume ();
202
203                 e = GetNextEvent ();
204                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
205                 Assert.IsTrue (e is BreakpointEvent);
206                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
207
208                 // Argument checking
209                 AssertThrows<ArgumentException> (delegate {
210                                 // Invalid IL offset
211                                 vm.SetBreakpoint (m, 2);
212                         });
213         }
214
215         [Test]
216         public void BreakpointsSameLocation () {
217                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp2");
218                 Assert.IsNotNull (m);
219
220                 vm.SetBreakpoint (m, 0);
221                 vm.SetBreakpoint (m, 0);
222
223                 vm.Resume ();
224
225                 var es = vm.GetNextEventSet ();
226                 Assert.AreEqual (2, es.Events.Length);
227                 Assert.IsTrue (es [0] is BreakpointEvent);
228                 Assert.AreEqual (m, (es [0] as BreakpointEvent).Method);
229
230                 Assert.IsTrue (es [1] is BreakpointEvent);
231                 Assert.AreEqual (m.Name, (es [1] as BreakpointEvent).Method.Name);
232         }
233
234         [Test]
235         public void BreakpointAlreadyJITted () {
236                 Event e = run_until ("bp1");
237
238                 /* Place a breakpoint on bp3 */
239                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp3");
240                 Assert.IsNotNull (m);
241                 vm.SetBreakpoint (m, 0);
242
243                 /* Same with generic instances */
244                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp7");
245                 Assert.IsNotNull (m2);
246                 vm.SetBreakpoint (m2, 0);
247
248                 vm.Resume ();
249
250                 e = GetNextEvent ();
251                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
252                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
253
254                 vm.Resume ();
255
256                 /* Non-shared instance */
257                 e = GetNextEvent ();
258                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
259                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
260
261                 vm.Resume ();
262
263                 /* Shared instance */
264                 e = GetNextEvent ();
265                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
266                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
267         }
268
269         [Test]
270         public void ClearBreakpoint () {
271                 Event e;
272
273                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
274                 Assert.IsNotNull (m);
275                 EventRequest req1 = vm.SetBreakpoint (m, 0);
276                 EventRequest req2 = vm.SetBreakpoint (m, 0);
277
278                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
279                 Assert.IsNotNull (m2);
280                 vm.SetBreakpoint (m2, 0);
281
282                 /* Run until bp4 */
283                 vm.Resume ();
284
285                 var es = vm.GetNextEventSet ();
286                 Assert.AreEqual (2, es.Events.Length);
287                 Assert.AreEqual (EventType.Breakpoint, es [0].EventType);
288                 Assert.AreEqual (m.Name, (es [0] as BreakpointEvent).Method.Name);
289                 Assert.AreEqual (EventType.Breakpoint, es [1].EventType);
290                 Assert.AreEqual (m.Name, (es [1] as BreakpointEvent).Method.Name);
291
292                 /* Clear one of them */
293                 req1.Disable ();
294
295                 vm.Resume ();
296
297                 e = GetNextEvent ();
298                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
299                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
300
301                 /* Clear the other */
302                 req2.Disable ();
303
304                 vm.Resume ();
305
306                 e = GetNextEvent ();
307                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
308                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
309         }
310
311         [Test]
312         public void ClearAllBreakpoints () {
313                 Event e;
314
315                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
316                 Assert.IsNotNull (m);
317                 vm.SetBreakpoint (m, 0);
318
319                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
320                 Assert.IsNotNull (m2);
321                 vm.SetBreakpoint (m2, 0);
322
323                 vm.ClearAllBreakpoints ();
324
325                 vm.Resume ();
326
327                 e = GetNextEvent ();
328                 Assert.IsTrue (!(e is BreakpointEvent));
329                 if (e is VMDeathEvent)
330                         vm = null;
331         }
332
333         [Test]
334         public void BreakpointOnGShared () {
335                 Event e;
336
337                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp6");
338                 Assert.IsNotNull (m);
339
340                 vm.SetBreakpoint (m, 0);
341
342                 vm.Resume ();
343
344                 e = GetNextEvent ();
345                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
346                 Assert.IsTrue (e is BreakpointEvent);
347                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
348
349                 // Breakpoint on an open generic method of a closed generic class (#3422)
350                 var frame = e.Thread.GetFrames ()[0];
351                 var ginst = frame.GetValue (frame.Method.GetLocal ("gc"));
352                 var m2 = (ginst as ObjectMirror).Type.GetMethod ("bp");
353                 vm.SetBreakpoint (m2, 0);
354
355                 vm.Resume ();
356
357                 e = GetNextEvent ();
358                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
359                 Assert.IsTrue (e is BreakpointEvent);
360                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
361         }
362
363         void assert_location (Event e, string method) {
364                 Assert.IsTrue (e is StepEvent);
365                 Assert.AreEqual (method, (e as StepEvent).Method.Name);
366         }
367
368         [Test]
369         public void SingleStepping () {
370                 Event e = run_until ("single_stepping");
371
372                 var req = vm.CreateStepRequest (e.Thread);
373                 req.Enable ();
374
375                 step_req = req;
376
377                 // Step over 'bool b = true'
378                 e = step_once ();
379                 assert_location (e, "single_stepping");
380
381                 // Skip nop
382                 step_once ();
383
384                 // Step into ss1
385                 e = step_once ();
386                 assert_location (e, "ss1");
387
388                 // Skip }
389                 e = step_once ();
390
391                 // Step out of ss1
392                 e = step_once ();
393                 assert_location (e, "single_stepping");
394
395                 // Change to step over
396                 req.Disable ();
397                 req.Depth = StepDepth.Over;
398                 req.Enable ();
399
400                 // Step over ss2
401                 e = step_once ();
402                 assert_location (e, "single_stepping");
403
404                 // Change to step into
405                 req.Disable ();
406                 req.Depth = StepDepth.Into;
407                 req.Enable ();
408
409                 // Step into ss3
410                 e = step_once ();
411                 assert_location (e, "ss3");
412
413                 // Change to step out
414                 req.Disable ();
415                 req.Depth = StepDepth.Out;
416                 req.Enable ();
417
418                 // Step back into single_stepping
419                 e = step_once ();
420                 assert_location (e, "single_stepping");
421
422                 // Change to step into
423                 req.Disable ();
424                 req.Depth = StepDepth.Into;
425                 req.Enable ();
426
427                 // Step into ss3_2 ()
428                 e = step_once ();
429                 assert_location (e, "ss3_2");
430
431                 // Change to step over
432                 req.Disable ();
433                 req.Depth = StepDepth.Over;
434                 req.Enable ();
435
436                 // Step over ss3_2_2 ()
437                 e = step_once ();
438                 assert_location (e, "ss3_2");
439
440                 // Recreate the request
441                 req.Disable ();
442                 req.Enable ();
443
444                 // Skip }
445                 e = step_once ();
446
447                 // Step back into single_stepping () with the new request
448                 e = step_once ();
449                 assert_location (e, "single_stepping");
450
451                 // Change to step into
452                 req.Disable ();
453                 req.Depth = StepDepth.Into;
454                 req.Enable ();
455
456                 // Step into ss4 ()
457                 e = step_once ();
458                 assert_location (e, "ss4");
459
460                 // Skip nop
461                 e = step_once ();
462
463                 // Change to StepSize.Line
464                 req.Disable ();
465                 req.Depth = StepDepth.Over;
466                 req.Size = StepSize.Line;
467                 req.Enable ();
468
469                 // Step over ss1 (); ss1 ();
470                 e = step_once ();
471
472                 // Step into ss2 ()
473                 req.Disable ();
474                 req.Depth = StepDepth.Into;
475                 req.Enable ();
476
477                 e = step_once ();
478                 assert_location (e, "ss2");
479
480                 req.Disable ();
481
482                 // Run until ss5
483                 e = run_until ("ss5");
484
485                 // Add an assembly filter
486                 req.AssemblyFilter = new AssemblyMirror [] { (e as BreakpointEvent).Method.DeclaringType.Assembly };
487                 req.Enable ();
488
489                 // Skip nop
490                 e = step_once ();
491
492                 // Step into is_even, skipping the linq stuff
493                 e = step_once ();
494                 assert_location (e, "is_even");
495
496                 // FIXME: Check that single stepping works with lock (obj)
497                 
498                 req.Disable ();
499
500                 // Run until ss6
501                 e = run_until ("ss6");
502
503                 req = vm.CreateStepRequest (e.Thread);
504                 req.Depth = StepDepth.Over;
505                 req.Enable ();
506
507                 // Check that single stepping works in out-of-line bblocks
508                 e = step_once ();
509                 e = step_once ();
510                 assert_location (e, "ss6");
511                 req.Disable ();
512
513                 // Check that a step over stops at an EH clause
514                 e = run_until ("ss7_2");
515                 req = vm.CreateStepRequest (e.Thread);
516                 req.Depth = StepDepth.Out;
517                 req.Enable ();
518                 e = step_once ();
519                 assert_location (e, "ss7");
520                 req.Disable ();
521                 req = vm.CreateStepRequest (e.Thread);
522                 req.Depth = StepDepth.Over;
523                 req.Enable ();
524                 e = step_once ();
525                 assert_location (e, "ss7");
526                 req.Disable ();
527         }
528
529         [Test]
530         public void MethodEntryExit () {
531                 run_until ("single_stepping");
532
533                 var req1 = vm.CreateMethodEntryRequest ();
534                 var req2 = vm.CreateMethodExitRequest ();
535
536                 req1.Enable ();
537                 req2.Enable ();
538
539                 vm.Resume ();
540                 Event e = GetNextEvent ();
541                 Assert.IsTrue (e is MethodEntryEvent);
542                 Assert.AreEqual ("ss1", (e as MethodEntryEvent).Method.Name);
543
544                 vm.Resume ();
545                 e = GetNextEvent ();
546                 Assert.IsTrue (e is MethodExitEvent);
547                 Assert.AreEqual ("ss1", (e as MethodExitEvent).Method.Name);
548
549                 req1.Disable ();
550                 req2.Disable ();
551         }
552
553         [Test]
554         public void CountFilter () {
555                 run_until ("single_stepping");
556
557                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("ss3");
558                 Assert.IsNotNull (m2);
559                 vm.SetBreakpoint (m2, 0);
560
561                 var req1 = vm.CreateMethodEntryRequest ();
562                 req1.Count = 2;
563                 req1.Enable ();
564
565                 // Enter ss2, ss1 is skipped
566                 vm.Resume ();
567                 Event e = GetNextEvent ();
568                 Assert.IsTrue (e is MethodEntryEvent);
569                 Assert.AreEqual ("ss2", (e as MethodEntryEvent).Method.Name);
570
571                 // Breakpoint on ss3, the entry event is no longer reported
572                 vm.Resume ();
573                 e = GetNextEvent ();
574                 Assert.IsTrue (e is BreakpointEvent);
575
576                 req1.Disable ();
577         }
578
579         [Test]
580         public void Arguments () {
581                 object val;
582
583                 var e = run_until ("arg1");
584
585                 StackFrame frame = e.Thread.GetFrames () [0];
586
587                 check_arg_val (frame, 0, typeof (sbyte), SByte.MaxValue - 5);
588                 check_arg_val (frame, 1, typeof (byte), Byte.MaxValue - 5);
589                 check_arg_val (frame, 2, typeof (bool), true);
590                 check_arg_val (frame, 3, typeof (short), Int16.MaxValue - 5);
591                 check_arg_val (frame, 4, typeof (ushort), UInt16.MaxValue - 5);
592                 check_arg_val (frame, 5, typeof (char), 'F');
593                 check_arg_val (frame, 6, typeof (int), Int32.MaxValue - 5);
594                 check_arg_val (frame, 7, typeof (uint), UInt32.MaxValue - 5);
595                 check_arg_val (frame, 8, typeof (long), Int64.MaxValue - 5);
596                 check_arg_val (frame, 9, typeof (ulong), UInt64.MaxValue - 5);
597                 check_arg_val (frame, 10, typeof (float), 1.2345f);
598                 check_arg_val (frame, 11, typeof (double), 6.78910);
599
600                 e = run_until ("arg2");
601
602                 frame = e.Thread.GetFrames () [0];
603
604                 // String
605                 val = frame.GetArgument (0);
606                 AssertValue ("FOO", val);
607                 Assert.AreEqual ("String", (val as ObjectMirror).Type.Name);
608
609                 // null
610                 val = frame.GetArgument (1);
611                 AssertValue (null, val);
612
613                 // object
614                 val = frame.GetArgument (2);
615                 AssertValue ("BLA", val);
616
617                 // byref
618                 val = frame.GetArgument (3);
619                 AssertValue (42, val);
620
621                 // generic instance
622                 val = frame.GetArgument (4);
623                 Assert.IsTrue (val is ObjectMirror);
624                 Assert.AreEqual ("GClass`1", (val as ObjectMirror).Type.Name);
625
626                 // System.Object
627                 val = frame.GetArgument (5);
628                 Assert.IsTrue (val is ObjectMirror);
629                 Assert.AreEqual ("Object", (val as ObjectMirror).Type.Name);
630
631                 // this on static methods
632                 val = frame.GetThis ();
633                 AssertValue (null, val);
634
635                 e = run_until ("arg3");
636
637                 frame = e.Thread.GetFrames () [0];
638
639                 // this
640                 val = frame.GetThis ();
641                 Assert.IsTrue (val is ObjectMirror);
642                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
643
644                 // objref in register
645                 val = frame.GetArgument (0);
646                 AssertValue ("BLA", val);
647         }
648
649         [Test]
650         public void Arrays () {
651                 object val;
652
653                 var e = run_until ("o2");
654
655                 StackFrame frame = e.Thread.GetFrames () [0];
656
657                 // String[]
658                 val = frame.GetArgument (0);
659                 Assert.IsTrue (val is ArrayMirror);
660                 ArrayMirror arr = val as ArrayMirror;
661                 Assert.AreEqual (2, arr.Length);
662                 AssertValue ("BAR", arr [0]);
663                 AssertValue ("BAZ", arr [1]);
664
665                 var vals = arr.GetValues (0, 2);
666                 Assert.AreEqual (2, vals.Count);
667                 AssertValue ("BAR", vals [0]);
668                 AssertValue ("BAZ", vals [1]);
669
670                 arr [0] = vm.RootDomain.CreateString ("ABC");
671                 AssertValue ("ABC", arr [0]);
672
673                 arr [0] = vm.CreateValue (null);
674                 AssertValue (null, arr [0]);
675
676                 arr.SetValues (0, new Value [] { vm.RootDomain.CreateString ("D1"), vm.RootDomain.CreateString ("D2") });
677                 AssertValue ("D1", arr [0]);
678                 AssertValue ("D2", arr [1]);
679
680                 // int
681                 val = frame.GetArgument (1);
682                 Assert.IsTrue (val is ArrayMirror);
683                 arr = val as ArrayMirror;
684                 Assert.AreEqual (2, arr.Length);
685                 AssertValue (42, arr [0]);
686                 AssertValue (43, arr [1]);
687
688                 // Argument checking
689                 AssertThrows<IndexOutOfRangeException> (delegate () {
690                                 val = arr [2];
691                         });
692
693                 AssertThrows<IndexOutOfRangeException> (delegate () {
694                                 val = arr [Int32.MinValue];
695                         });
696
697                 AssertThrows<IndexOutOfRangeException> (delegate () {
698                                 vals = arr.GetValues (0, 3);
699                         });
700
701                 AssertThrows<IndexOutOfRangeException> (delegate () {
702                                 arr [2] = vm.CreateValue (null);
703                         });
704
705                 AssertThrows<IndexOutOfRangeException> (delegate () {
706                                 arr [Int32.MinValue] = vm.CreateValue (null);
707                         });
708
709                 AssertThrows<IndexOutOfRangeException> (delegate () {
710                                 arr.SetValues (0, new Value [] { null, null, null });
711                         });
712
713                 // Multidim arrays
714                 val = frame.GetArgument (2);
715                 Assert.IsTrue (val is ArrayMirror);
716                 arr = val as ArrayMirror;
717                 Assert.AreEqual (2, arr.Rank);
718                 Assert.AreEqual (4, arr.Length);
719                 Assert.AreEqual (2, arr.GetLength (0));
720                 Assert.AreEqual (2, arr.GetLength (1));
721                 Assert.AreEqual (0, arr.GetLowerBound (0));
722                 Assert.AreEqual (0, arr.GetLowerBound (1));
723                 vals = arr.GetValues (0, 4);
724                 AssertValue (1, vals [0]);
725                 AssertValue (2, vals [1]);
726                 AssertValue (3, vals [2]);
727                 AssertValue (4, vals [3]);
728
729                 val = frame.GetArgument (3);
730                 Assert.IsTrue (val is ArrayMirror);
731                 arr = val as ArrayMirror;
732                 Assert.AreEqual (2, arr.Rank);
733                 Assert.AreEqual (4, arr.Length);
734                 Assert.AreEqual (2, arr.GetLength (0));
735                 Assert.AreEqual (2, arr.GetLength (1));
736                 Assert.AreEqual (1, arr.GetLowerBound (0));
737                 Assert.AreEqual (3, arr.GetLowerBound (1));
738
739                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
740                                 arr.GetLength (-1);
741                         });
742                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
743                                 arr.GetLength (2);
744                         });
745
746                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
747                                 arr.GetLowerBound (-1);
748                         });
749                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
750                                 arr.GetLowerBound (2);
751                         });
752
753                 // arrays treated as generic collections
754                 val = frame.GetArgument (4);
755                 Assert.IsTrue (val is ArrayMirror);
756                 arr = val as ArrayMirror;
757         }
758
759         [Test]
760         public void Object_GetValue () {
761                 var e = run_until ("o1");
762                 var frame = e.Thread.GetFrames () [0];
763
764                 object val = frame.GetThis ();
765                 Assert.IsTrue (val is ObjectMirror);
766                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
767                 ObjectMirror o = (val as ObjectMirror);
768
769                 TypeMirror t = o.Type;
770
771                 // object fields
772                 object f = o.GetValue (t.GetField ("field_i"));
773                 AssertValue (42, f);
774                 f = o.GetValue (t.GetField ("field_s"));
775                 AssertValue ("S", f);
776                 f = o.GetValue (t.GetField ("field_enum"));
777                 Assert.IsTrue (f is EnumMirror);
778                 Assert.AreEqual (1, (f as EnumMirror).Value);
779                 Assert.AreEqual ("B", (f as EnumMirror).StringValue);
780
781                 // Inherited object fields
782                 TypeMirror parent = t.BaseType;
783                 f = o.GetValue (parent.GetField ("base_field_i"));
784                 AssertValue (43, f);
785                 f = o.GetValue (parent.GetField ("base_field_s"));
786                 AssertValue ("T", f);
787
788                 // Static fields
789                 f = o.GetValue (o.Type.GetField ("static_i"));
790                 AssertValue (55, f);
791
792                 // generic instances
793                 ObjectMirror o2 = frame.GetValue (frame.Method.GetParameters ()[1]) as ObjectMirror;
794                 Assert.AreEqual ("GClass`1", o2.Type.Name);
795                 TypeMirror t2 = o2.Type;
796                 f = o2.GetValue (t2.GetField ("field"));
797                 AssertValue (42, f);
798
799                 ObjectMirror o3 = frame.GetValue (frame.Method.GetParameters ()[2]) as ObjectMirror;
800                 Assert.AreEqual ("GClass`1", o3.Type.Name);
801                 TypeMirror t3 = o3.Type;
802                 f = o3.GetValue (t3.GetField ("field"));
803                 AssertValue ("FOO", f);
804
805                 // Argument checking
806                 AssertThrows<ArgumentNullException> (delegate () {
807                         o.GetValue (null);
808                         });
809         }
810
811         [Test]
812         public void Object_GetValues () {
813                 var e = run_until ("o1");
814                 var frame = e.Thread.GetFrames () [0];
815
816                 object val = frame.GetThis ();
817                 Assert.IsTrue (val is ObjectMirror);
818                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
819                 ObjectMirror o = (val as ObjectMirror);
820
821                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
822
823                 TypeMirror t = o.Type;
824
825                 object[] vals = o.GetValues (new FieldInfoMirror [] { t.GetField ("field_i"), t.GetField ("field_s") });
826                 object f = vals [0];
827                 AssertValue (42, f);
828                 f = vals [1];
829                 AssertValue ("S", f);
830
831                 // Argument checking
832                 AssertThrows<ArgumentNullException> (delegate () {
833                         o.GetValues (null);
834                         });
835
836                 AssertThrows<ArgumentNullException> (delegate () {
837                         o.GetValues (new FieldInfoMirror [] { null });
838                         });
839
840                 // field of another class
841                 AssertThrows<ArgumentException> (delegate () {
842                                 o.GetValue (val2.Type.GetField ("field_j"));
843                         });
844         }
845
846         void TestSetValue (ObjectMirror o, string field_name, object val) {
847                 if (val is string)
848                         o.SetValue (o.Type.GetField (field_name), vm.RootDomain.CreateString ((string)val));
849                 else
850                         o.SetValue (o.Type.GetField (field_name), vm.CreateValue (val));
851                 Value f = o.GetValue (o.Type.GetField (field_name));
852                 AssertValue (val, f);
853         }
854
855         [Test]
856         public void Object_SetValues () {
857                 var e = run_until ("o1");
858                 var frame = e.Thread.GetFrames () [0];
859
860                 object val = frame.GetThis ();
861                 Assert.IsTrue (val is ObjectMirror);
862                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
863                 ObjectMirror o = (val as ObjectMirror);
864
865                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
866
867                 TestSetValue (o, "field_i", 22);
868                 TestSetValue (o, "field_bool1", false);
869                 TestSetValue (o, "field_bool2", true);
870                 TestSetValue (o, "field_char", 'B');
871                 TestSetValue (o, "field_byte", (byte)129);
872                 TestSetValue (o, "field_sbyte", (sbyte)-33);
873                 TestSetValue (o, "field_short", (short)(Int16.MaxValue - 5));
874                 TestSetValue (o, "field_ushort", (ushort)(UInt16.MaxValue - 5));
875                 TestSetValue (o, "field_long", Int64.MaxValue - 5);
876                 TestSetValue (o, "field_ulong", (ulong)(UInt64.MaxValue - 5));
877                 TestSetValue (o, "field_float", 6.28f);
878                 TestSetValue (o, "field_double", 6.28);
879                 TestSetValue (o, "static_i", 23);
880                 TestSetValue (o, "field_s", "CDEF");
881
882                 Value f;
883
884                 // intptrs
885                 f = o.GetValue (o.Type.GetField ("field_intptr"));
886                 Assert.IsInstanceOfType (typeof (StructMirror), f);
887                 AssertValue (Int32.MaxValue - 5, (f as StructMirror).Fields [0]);
888
889                 // enums
890                 FieldInfoMirror field = o.Type.GetField ("field_enum");
891                 f = o.GetValue (field);
892                 (f as EnumMirror).Value = 5;
893                 o.SetValue (field, f);
894                 f = o.GetValue (field);
895                 Assert.AreEqual (5, (f as EnumMirror).Value);
896
897                 // null
898                 o.SetValue (o.Type.GetField ("field_s"), vm.CreateValue (null));
899                 f = o.GetValue (o.Type.GetField ("field_s"));
900                 AssertValue (null, f);
901
902                 // vtype instances
903                 field = o.Type.GetField ("generic_field_struct");
904                 f = o.GetValue (field);
905                 o.SetValue (field, f);
906
907                 // nullables
908                 field = o.Type.GetField ("field_nullable");
909                 f = o.GetValue (field);
910                 AssertValue (0, (f as StructMirror).Fields [0]);
911                 AssertValue (false, (f as StructMirror).Fields [1]);
912                 o.SetValue (field, vm.CreateValue (6));
913                 f = o.GetValue (field);
914                 AssertValue (6, (f as StructMirror).Fields [0]);
915                 AssertValue (true, (f as StructMirror).Fields [1]);
916                 o.SetValue (field, vm.CreateValue (null));
917                 f = o.GetValue (field);
918                 AssertValue (0, (f as StructMirror).Fields [0]);
919                 AssertValue (false, (f as StructMirror).Fields [1]);
920
921                 // Argument checking
922                 AssertThrows<ArgumentNullException> (delegate () {
923                                 o.SetValues (null, new Value [0]);
924                         });
925
926                 AssertThrows<ArgumentNullException> (delegate () {
927                                 o.SetValues (new FieldInfoMirror [0], null);
928                         });
929
930                 AssertThrows<ArgumentNullException> (delegate () {
931                                 o.SetValues (new FieldInfoMirror [] { null }, new Value [1] { null });
932                         });
933
934                 // vtype with a wrong type
935                 AssertThrows<ArgumentException> (delegate () {
936                                 o.SetValue (o.Type.GetField ("field_struct"), o.GetValue (o.Type.GetField ("field_enum")));
937                         });
938
939                 // reference type not assignment compatible
940                 AssertThrows<ArgumentException> (delegate () {
941                                 o.SetValue (o.Type.GetField ("field_class"), o);
942                         });
943
944                 // field of another class
945                 AssertThrows<ArgumentException> (delegate () {
946                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
947                         });
948         }
949
950         [Test]
951         public void Type_SetValue () {
952                 var e = run_until ("o1");
953                 var frame = e.Thread.GetFrames () [0];
954                 Value f;
955
956                 object val = frame.GetThis ();
957                 Assert.IsTrue (val is ObjectMirror);
958                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
959                 ObjectMirror o = (val as ObjectMirror);
960
961                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
962
963                 o.Type.SetValue (o.Type.GetField ("static_i"), vm.CreateValue (55));
964                 f = o.Type.GetValue (o.Type.GetField ("static_i"));
965                 AssertValue (55, f);
966
967                 o.Type.SetValue (o.Type.GetField ("static_s"), vm.RootDomain.CreateString ("B"));
968                 f = o.Type.GetValue (o.Type.GetField ("static_s"));
969                 AssertValue ("B", f);
970
971                 // Argument checking
972                 AssertThrows<ArgumentNullException> (delegate () {
973                                 o.Type.SetValue (null, vm.CreateValue (0));
974                         });
975
976                 AssertThrows<ArgumentNullException> (delegate () {
977                                 o.Type.SetValue (o.Type.GetField ("static_i"), null);
978                         });
979
980                 // field of another class
981                 AssertThrows<ArgumentException> (delegate () {
982                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
983                         });
984         }
985
986         [Test]
987         public void TypeInfo () {
988                 Event e = run_until ("ti2");
989                 StackFrame frame = e.Thread.GetFrames () [0];
990
991                 TypeMirror t;
992
993                 // Array types
994                 t = frame.Method.GetParameters ()[0].ParameterType;
995
996                 Assert.AreEqual ("String[]", t.Name);
997                 Assert.AreEqual ("string[]", t.CSharpName);
998                 Assert.AreEqual ("Array", t.BaseType.Name);
999                 Assert.AreEqual (true, t.HasElementType);
1000                 Assert.AreEqual (true, t.IsArray);
1001                 Assert.AreEqual (1, t.GetArrayRank ());
1002                 Assert.AreEqual ("String", t.GetElementType ().Name);
1003
1004                 t = frame.Method.GetParameters ()[2].ParameterType;
1005
1006                 Assert.AreEqual ("Int32[,]", t.Name);
1007                 // FIXME:
1008                 //Assert.AreEqual ("int[,]", t.CSharpName);
1009                 Assert.AreEqual ("Array", t.BaseType.Name);
1010                 Assert.AreEqual (true, t.HasElementType);
1011                 Assert.AreEqual (true, t.IsArray);
1012                 Assert.AreEqual (2, t.GetArrayRank ());
1013                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
1014
1015                 // Byref types
1016                 t = frame.Method.GetParameters ()[3].ParameterType;
1017                 // FIXME:
1018                 //Assert.AreEqual ("Int32&", t.Name);
1019                 //Assert.AreEqual (true, t.IsByRef);
1020                 //Assert.AreEqual (true, t.HasElementType);
1021
1022                 // Pointer types
1023                 t = frame.Method.GetParameters ()[4].ParameterType;
1024                 // FIXME:
1025                 //Assert.AreEqual ("Int32*", t.Name);
1026                 Assert.AreEqual (true, t.IsPointer);
1027                 Assert.AreEqual (true, t.HasElementType);
1028                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
1029                 Assert.AreEqual (false, t.IsPrimitive);
1030
1031                 // primitive types 
1032                 t = frame.Method.GetParameters ()[5].ParameterType;
1033                 Assert.AreEqual (true, t.IsPrimitive);
1034
1035                 // value types
1036                 t = frame.Method.GetParameters ()[6].ParameterType;
1037                 Assert.AreEqual ("AStruct", t.Name);
1038                 Assert.AreEqual (false, t.IsPrimitive);
1039                 Assert.AreEqual (true, t.IsValueType);
1040                 Assert.AreEqual (false, t.IsClass);
1041
1042                 // reference types
1043                 t = frame.Method.GetParameters ()[7].ParameterType;
1044                 Assert.AreEqual ("Tests", t.Name);
1045                 var nested = (from nt in t.GetNestedTypes () where nt.IsNestedPublic select nt).ToArray ();
1046                 Assert.AreEqual (1, nested.Length);
1047                 Assert.AreEqual ("NestedClass", nested [0].Name);
1048                 Assert.IsTrue (t.BaseType.IsAssignableFrom (t));
1049                 Assert.IsTrue (!t.IsAssignableFrom (t.BaseType));
1050
1051                 // generic instances
1052                 t = frame.Method.GetParameters ()[9].ParameterType;
1053                 Assert.AreEqual ("GClass`1", t.Name);
1054                 Assert.IsTrue (t.IsGenericType);
1055                 Assert.IsFalse (t.IsGenericTypeDefinition);
1056
1057                 var args = t.GetGenericArguments ();
1058                 Assert.AreEqual (1, args.Length);
1059                 Assert.AreEqual ("Int32", args [0].Name);
1060
1061                 // generic type definitions
1062                 var gtd = t.GetGenericTypeDefinition ();
1063                 Assert.AreEqual ("GClass`1", gtd.Name);
1064                 Assert.IsTrue (gtd.IsGenericType);
1065                 Assert.IsTrue (gtd.IsGenericTypeDefinition);
1066                 Assert.AreEqual (gtd, gtd.GetGenericTypeDefinition ());
1067
1068                 args = gtd.GetGenericArguments ();
1069                 Assert.AreEqual (1, args.Length);
1070                 Assert.AreEqual ("T", args [0].Name);
1071
1072                 // enums
1073                 t = frame.Method.GetParameters ()[10].ParameterType;
1074                 Assert.AreEqual ("AnEnum", t.Name);
1075                 Assert.IsTrue (t.IsEnum);
1076                 Assert.AreEqual ("Int32", t.EnumUnderlyingType.Name);
1077
1078                 // properties
1079                 t = frame.Method.GetParameters ()[7].ParameterType;
1080
1081                 var props = t.GetProperties ();
1082                 Assert.AreEqual (3, props.Length);
1083                 foreach (PropertyInfoMirror prop in props) {
1084                         ParameterInfoMirror[] indexes = prop.GetIndexParameters ();
1085
1086                         if (prop.Name == "IntProperty") {
1087                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1088                                 Assert.AreEqual ("get_IntProperty", prop.GetGetMethod ().Name);
1089                                 Assert.AreEqual ("set_IntProperty", prop.GetSetMethod ().Name);
1090                                 Assert.AreEqual (0, indexes.Length);
1091                         } else if (prop.Name == "ReadOnlyProperty") {
1092                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1093                                 Assert.AreEqual ("get_ReadOnlyProperty", prop.GetGetMethod ().Name);
1094                                 Assert.AreEqual (null, prop.GetSetMethod ());
1095                                 Assert.AreEqual (0, indexes.Length);
1096                         } else if (prop.Name == "IndexedProperty") {
1097                                 Assert.AreEqual (1, indexes.Length);
1098                                 Assert.AreEqual ("Int32", indexes [0].ParameterType.Name);
1099                         }
1100                 }
1101
1102                 // custom attributes
1103                 t = frame.Method.GetParameters ()[8].ParameterType;
1104                 Assert.AreEqual ("Tests2", t.Name);
1105                 var attrs = t.GetCustomAttributes (true);
1106                 Assert.AreEqual (3, attrs.Length);
1107                 foreach (var attr in attrs) {
1108                         if (attr.Constructor.DeclaringType.Name == "DebuggerDisplayAttribute") {
1109                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1110                                 Assert.AreEqual ("Tests", attr.ConstructorArguments [0].Value);
1111                                 Assert.AreEqual (2, attr.NamedArguments.Count);
1112                                 Assert.AreEqual ("Name", attr.NamedArguments [0].Property.Name);
1113                                 Assert.AreEqual ("FOO", attr.NamedArguments [0].TypedValue.Value);
1114                                 Assert.AreEqual ("Target", attr.NamedArguments [1].Property.Name);
1115                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.NamedArguments [1].TypedValue.Value);
1116                                 Assert.AreEqual ("Int32", (attr.NamedArguments [1].TypedValue.Value as TypeMirror).Name);
1117                         } else if (attr.Constructor.DeclaringType.Name == "DebuggerTypeProxyAttribute") {
1118                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1119                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.ConstructorArguments [0].Value);
1120                                 Assert.AreEqual ("Tests", (attr.ConstructorArguments [0].Value as TypeMirror).Name);
1121                         } else if (attr.Constructor.DeclaringType.Name == "BAttribute") {
1122                                 Assert.AreEqual (2, attr.NamedArguments.Count);
1123                                 Assert.AreEqual ("afield", attr.NamedArguments [0].Field.Name);
1124                                 Assert.AreEqual ("bfield", attr.NamedArguments [1].Field.Name);
1125                         } else {
1126                                 Assert.Fail (attr.Constructor.DeclaringType.Name);
1127                         }
1128                 }
1129
1130                 var assembly = entry_point.DeclaringType.Assembly;
1131                 var type = assembly.GetType ("Tests4");
1132                 Assert.IsFalse (type.IsInitialized);
1133         }
1134
1135         [Test]
1136         public void FieldInfo () {
1137                 Event e = run_until ("ti2");
1138                 StackFrame frame = e.Thread.GetFrames () [0];
1139
1140                 TypeMirror t;
1141
1142                 t = frame.Method.GetParameters ()[8].ParameterType;
1143                 Assert.AreEqual ("Tests2", t.Name);
1144
1145                 var fi = t.GetField ("field_j");
1146                 var attrs = fi.GetCustomAttributes (true);
1147                 Assert.AreEqual (1, attrs.Length);
1148                 var attr = attrs [0];
1149                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1150                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1151                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1152                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1153         }
1154
1155         [Test]
1156         public void PropertyInfo () {
1157                 Event e = run_until ("ti2");
1158                 StackFrame frame = e.Thread.GetFrames () [0];
1159
1160                 TypeMirror t;
1161
1162                 t = frame.Method.GetParameters ()[8].ParameterType;
1163                 Assert.AreEqual ("Tests2", t.Name);
1164
1165                 var pi = t.GetProperty ("AProperty");
1166                 var attrs = pi.GetCustomAttributes (true);
1167                 Assert.AreEqual (1, attrs.Length);
1168                 var attr = attrs [0];
1169                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1170                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1171                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1172                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1173         }
1174
1175         [Test]
1176         [Category ("only5")]
1177         public void Type_GetValue () {
1178                 Event e = run_until ("o1");
1179                 StackFrame frame = e.Thread.GetFrames () [0];
1180
1181                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1182
1183                 TypeMirror t = o.Type;
1184
1185                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1186
1187                 // static fields
1188                 object f = t.GetValue (o.Type.GetField ("static_i"));
1189                 AssertValue (55, f);
1190
1191                 f = t.GetValue (o.Type.GetField ("static_s"));
1192                 AssertValue ("A", f);
1193
1194                 // literal static fields
1195                 f = t.GetValue (o.Type.GetField ("literal_i"));
1196                 AssertValue (56, f);
1197
1198                 f = t.GetValue (o.Type.GetField ("literal_s"));
1199                 AssertValue ("B", f);
1200
1201                 // Inherited static fields
1202                 TypeMirror parent = t.BaseType;
1203                 f = t.GetValue (parent.GetField ("base_static_i"));
1204                 AssertValue (57, f);
1205
1206                 f = t.GetValue (parent.GetField ("base_static_s"));
1207                 AssertValue ("C", f);
1208
1209                 // thread static field
1210                 f = t.GetValue (t.GetField ("tls_i"), e.Thread);
1211                 AssertValue (42, f);
1212
1213                 // Argument checking
1214                 AssertThrows<ArgumentNullException> (delegate () {
1215                         t.GetValue (null);
1216                         });
1217
1218                 // instance fields
1219                 AssertThrows<ArgumentException> (delegate () {
1220                         t.GetValue (o.Type.GetField ("field_i"));
1221                         });
1222
1223                 // field on another type
1224                 AssertThrows<ArgumentException> (delegate () {
1225                                 t.GetValue (val2.Type.GetField ("static_field_j"));
1226                         });
1227
1228                 // special static field
1229                 AssertThrows<ArgumentException> (delegate () {
1230                                 t.GetValue (t.GetField ("tls_i"));
1231                         });
1232         }
1233
1234         [Test]
1235         public void Type_GetValues () {
1236                 Event e = run_until ("o1");
1237                 StackFrame frame = e.Thread.GetFrames () [0];
1238
1239                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1240
1241                 TypeMirror t = o.Type;
1242
1243                 // static fields
1244                 object[] vals = t.GetValues (new FieldInfoMirror [] { t.GetField ("static_i"), t.GetField ("static_s") });
1245                 object f = vals [0];
1246                 AssertValue (55, f);
1247
1248                 f = vals [1];
1249                 AssertValue ("A", f);
1250
1251                 // Argument checking
1252                 AssertThrows<ArgumentNullException> (delegate () {
1253                         t.GetValues (null);
1254                         });
1255
1256                 AssertThrows<ArgumentNullException> (delegate () {
1257                         t.GetValues (new FieldInfoMirror [] { null });
1258                         });
1259         }
1260
1261         [Test]
1262         public void ObjRefs () {
1263                 Event e = run_until ("objrefs1");
1264                 StackFrame frame = e.Thread.GetFrames () [0];
1265
1266                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1267                 ObjectMirror child = o.GetValue (o.Type.GetField ("child")) as ObjectMirror;
1268
1269                 Assert.IsTrue (child.Address != 0);
1270
1271                 // Check that object references are internalized correctly
1272                 Assert.AreEqual (o, frame.GetThis ());
1273
1274                 run_until ("objrefs2");
1275
1276                 // child should be gc'd now
1277                 // This is not deterministic
1278                 //Assert.IsTrue (child.IsCollected);
1279
1280                 /*
1281                  * No longer works since Type is read eagerly
1282                  */
1283                 /*
1284                 AssertThrows<ObjectCollectedException> (delegate () {
1285                         TypeMirror t = child.Type;
1286                         });
1287                 */
1288                 /*
1289                 AssertThrows<ObjectCollectedException> (delegate () {
1290                                 long addr = child.Address;
1291                         });
1292                 */
1293         }
1294
1295         [Test]
1296         public void Type_GetObject () {
1297                 Event e = run_until ("o1");
1298                 StackFrame frame = e.Thread.GetFrames () [0];
1299
1300                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1301
1302                 TypeMirror t = o.Type;
1303
1304                 Assert.AreEqual ("MonoType", t.GetTypeObject ().Type.Name);
1305         }
1306
1307         [Test]
1308         public void VTypes () {
1309                 Event e = run_until ("vtypes1");
1310                 StackFrame frame = e.Thread.GetFrames () [0];
1311
1312                 // vtypes as fields
1313                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1314                 var obj = o.GetValue (o.Type.GetField ("field_struct"));
1315                 Assert.IsTrue (obj is StructMirror);
1316                 var s = obj as StructMirror;
1317                 Assert.AreEqual ("AStruct", s.Type.Name);
1318                 AssertValue (42, s ["i"]);
1319                 obj = s ["s"];
1320                 AssertValue ("S", obj);
1321                 AssertValue (43, s ["k"]);
1322                 obj = o.GetValue (o.Type.GetField ("field_boxed_struct"));
1323                 Assert.IsTrue (obj is StructMirror);
1324                 s = obj as StructMirror;
1325                 Assert.AreEqual ("AStruct", s.Type.Name);
1326                 AssertValue (42, s ["i"]);
1327
1328                 // vtypes as arguments
1329                 s = frame.GetArgument (0) as StructMirror;
1330                 AssertValue (44, s ["i"]);
1331                 obj = s ["s"];
1332                 AssertValue ("T", obj);
1333                 AssertValue (45, s ["k"]);
1334
1335                 // vtypes as array entries
1336                 var arr = frame.GetArgument (1) as ArrayMirror;
1337                 obj = arr [0];
1338                 Assert.IsTrue (obj is StructMirror);
1339                 s = obj as StructMirror;
1340                 AssertValue (1, s ["i"]);
1341                 AssertValue ("S1", s ["s"]);
1342                 obj = arr [1];
1343                 Assert.IsTrue (obj is StructMirror);
1344                 s = obj as StructMirror;
1345                 AssertValue (2, s ["i"]);
1346                 AssertValue ("S2", s ["s"]);
1347
1348                 // Argument checking
1349                 s = frame.GetArgument (0) as StructMirror;
1350                 AssertThrows<ArgumentException> (delegate () {
1351                                 obj = s ["FOO"];
1352                         });
1353
1354                 // generic vtype instances
1355                 o = frame.GetThis () as ObjectMirror;
1356                 obj = o.GetValue (o.Type.GetField ("generic_field_struct"));
1357                 Assert.IsTrue (obj is StructMirror);
1358                 s = obj as StructMirror;
1359                 Assert.AreEqual ("GStruct`1", s.Type.Name);
1360                 AssertValue (42, s ["i"]);
1361
1362                 // this on vtype methods
1363                 e = run_until ("vtypes2");
1364                 
1365                 // Skip nop
1366                 e = single_step (e.Thread);
1367
1368                 e = single_step (e.Thread);
1369
1370                 frame = e.Thread.GetFrames () [0];
1371
1372                 Assert.AreEqual ("foo", (e as StepEvent).Method.Name);
1373                 obj = frame.GetThis ();
1374
1375                 Assert.IsTrue (obj is StructMirror);
1376                 s = obj as StructMirror;
1377                 AssertValue (44, s ["i"]);
1378                 AssertValue ("T", s ["s"]);
1379                 AssertValue (45, s ["k"]);
1380
1381                 // this on static vtype methods
1382                 e = run_until ("vtypes3");
1383
1384                 // Skip nop
1385                 e = single_step (e.Thread);
1386
1387                 e = single_step (e.Thread);
1388
1389                 frame = e.Thread.GetFrames () [0];
1390
1391                 Assert.AreEqual ("static_foo", (e as StepEvent).Method.Name);
1392                 obj = frame.GetThis ();
1393                 AssertValue (null, obj);
1394         }
1395
1396         [Test]
1397         public void AssemblyInfo () {
1398                 Event e = run_until ("single_stepping");
1399
1400                 StackFrame frame = e.Thread.GetFrames () [0];
1401
1402                 var aname = frame.Method.DeclaringType.Assembly.GetName ();
1403                 Assert.AreEqual ("dtest-app, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", aname.ToString ());
1404
1405                 ModuleMirror m = frame.Method.DeclaringType.Module;
1406
1407                 Assert.AreEqual ("dtest-app.exe", m.Name);
1408                 Assert.AreEqual ("dtest-app.exe", m.ScopeName);
1409                 Assert.IsTrue (m.FullyQualifiedName.IndexOf ("dtest-app.exe") != -1);
1410                 Guid guid = m.ModuleVersionId;
1411                 Assert.AreEqual (frame.Method.DeclaringType.Assembly, m.Assembly);
1412                 Assert.AreEqual (frame.Method.DeclaringType.Assembly.ManifestModule, m);
1413
1414                 // This is no longer true on 4.0
1415                 //Assert.AreEqual ("Assembly", frame.Method.DeclaringType.Assembly.GetAssemblyObject ().Type.Name);
1416
1417                 TypeMirror t = vm.RootDomain.Corlib.GetType ("System.Diagnostics.DebuggerDisplayAttribute");
1418                 Assert.AreEqual ("DebuggerDisplayAttribute", t.Name);
1419         }
1420
1421         [Test]
1422         public void LocalsInfo () {
1423                 Event e = run_until ("locals2");
1424
1425                 StackFrame frame = e.Thread.GetFrames () [0];
1426
1427                 var locals = frame.Method.GetLocals ();
1428                 Assert.AreEqual (7, locals.Length);
1429                 for (int i = 0; i < 7; ++i) {
1430                         if (locals [i].Name == "args") {
1431                                 Assert.IsTrue (locals [i].IsArg);
1432                                 Assert.AreEqual ("String[]", locals [i].Type.Name);
1433                         } else if (locals [i].Name == "arg") {
1434                                 Assert.IsTrue (locals [i].IsArg);
1435                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1436                         } else if (locals [i].Name == "i") {
1437                                 Assert.IsFalse (locals [i].IsArg);
1438                                 Assert.AreEqual ("Int64", locals [i].Type.Name);
1439                         } else if (locals [i].Name == "j") {
1440                                 Assert.IsFalse (locals [i].IsArg);
1441                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1442                         } else if (locals [i].Name == "s") {
1443                                 Assert.IsFalse (locals [i].IsArg);
1444                                 Assert.AreEqual ("String", locals [i].Type.Name);
1445                         } else if (locals [i].Name == "t") {
1446                                 // gshared
1447                                 Assert.IsTrue (locals [i].IsArg);
1448                                 Assert.AreEqual ("String", locals [i].Type.Name);
1449                         } else if (locals [i].Name == "rs") {
1450                                 Assert.IsTrue (locals [i].IsArg);
1451                                 Assert.AreEqual ("String", locals [i].Type.Name);
1452                         } else {
1453                                 Assert.Fail ();
1454                         }
1455                 }
1456         }
1457
1458         Event step_once () {
1459                 vm.Resume ();
1460                 var e = GetNextEvent ();
1461                 Assert.IsTrue (e is StepEvent);
1462                 return e;
1463         }
1464
1465         [Test]
1466         public void Locals () {
1467                 var be = run_until ("locals1");
1468
1469                 StackFrame frame = be.Thread.GetFrames () [0];
1470                 MethodMirror m1 = frame.Method;
1471
1472                 // Compiler generated byref local
1473                 foreach (var l in m1.GetLocals ()) {
1474                         // The byval flag is hidden from the type
1475                         if (l.Name != "ri" && l.Type.Name == "Double")
1476                                 AssertValue (null, frame.GetValue (l));
1477                 }
1478
1479                 be = run_until ("locals2");
1480
1481                 frame = be.Thread.GetFrames () [0];
1482
1483                 object val = frame.GetValue (frame.Method.GetLocal ("i"));
1484                 AssertValue (0, val);
1485
1486                 var req = vm.CreateStepRequest (be.Thread);
1487                 req.Enable ();
1488                 step_req = req;
1489
1490                 // Skip nop
1491                 step_once ();
1492
1493                 // Execute i = 42
1494                 var e = step_once ();
1495                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1496
1497                 // Execute s = "AB";
1498                 e = step_once ();
1499                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1500
1501                 frame = e.Thread.GetFrames () [0];
1502
1503                 val = frame.GetValue (frame.Method.GetLocal ("i"));
1504                 AssertValue (42, val);
1505
1506                 LocalVariable[] locals = frame.Method.GetLocals ();
1507                 var vals = frame.GetValues (locals);
1508                 Assert.AreEqual (locals.Length, vals.Length);
1509                 for (int i = 0; i < locals.Length; ++i) {
1510                         if (locals [i].Name == "i")
1511                                 AssertValue (42, vals [i]);
1512                         if (locals [i].Name == "s")
1513                                 AssertValue ("AB", vals [i]);
1514                         if (locals [i].Name == "t")
1515                                 AssertValue ("ABC", vals [i]);
1516                 }
1517
1518                 // Argument checking
1519
1520                 // GetValue () null
1521                 AssertThrows<ArgumentNullException> (delegate () {
1522                                 frame.GetValue ((LocalVariable)null);
1523                         });
1524                 // GetValue () local from another method
1525                 AssertThrows<ArgumentException> (delegate () {
1526                                 frame.GetValue (m1.GetLocal ("foo"));
1527                         });
1528
1529                 // GetValue () null
1530                 AssertThrows<ArgumentNullException> (delegate () {
1531                                 frame.GetValue ((ParameterInfoMirror)null);
1532                         });
1533                 // GetValue () local from another method
1534                 AssertThrows<ArgumentException> (delegate () {
1535                                 frame.GetValue (m1.GetParameters ()[0]);
1536                         });
1537
1538                 // GetValues () null
1539                 AssertThrows<ArgumentNullException> (delegate () {
1540                                 frame.GetValues (null);
1541                         });
1542                 // GetValues () embedded null
1543                 AssertThrows<ArgumentNullException> (delegate () {
1544                                 frame.GetValues (new LocalVariable [] { null });
1545                         });
1546                 // GetValues () local from another method
1547                 AssertThrows<ArgumentException> (delegate () {
1548                                 frame.GetValues (new LocalVariable [] { m1.GetLocal ("foo") });
1549                         });
1550                 // return value
1551                 AssertThrows<ArgumentException> (delegate () {
1552                                 val = frame.GetValue (frame.Method.ReturnParameter);
1553                         });
1554
1555                 // invalid stack frames
1556                 vm.Resume ();
1557                 e = GetNextEvent ();
1558                 Assert.IsTrue (e is StepEvent);
1559                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1560
1561                 AssertThrows<InvalidStackFrameException> (delegate () {
1562                                 frame.GetValue (frame.Method.GetLocal ("i"));
1563                         });
1564
1565                 req.Disable ();
1566
1567                 // gsharedvt
1568                 be = run_until ("locals7");
1569
1570                 req = vm.CreateStepRequest (be.Thread);
1571                 req.Enable ();
1572                 step_req = req;
1573
1574                 // Skip nop
1575                 e = step_once ();
1576
1577                 // Test that locals are initialized
1578                 frame = e.Thread.GetFrames () [0];
1579                 val = frame.GetValue (frame.Method.GetLocal ("t"));
1580                 AssertValue (0, val);
1581
1582                 // Execute t = arg
1583                 e = step_once ();
1584                 Assert.AreEqual ("locals7", (e as StepEvent).Method.Name);
1585
1586                 // Execute t2 = t
1587                 e = step_once ();
1588                 Assert.AreEqual ("locals7", (e as StepEvent).Method.Name);
1589
1590                 frame = e.Thread.GetFrames () [0];
1591                 val = frame.GetValue (frame.Method.GetParameters ()[0]);
1592                 AssertValue (22, val);
1593                 val = frame.GetValue (frame.Method.GetLocal ("t"));
1594                 AssertValue (22, val);
1595                 val = frame.GetValue (frame.Method.GetLocal ("t2"));
1596                 AssertValue (22, val);
1597         }
1598
1599         [Test]
1600         public void GetVisibleVariables () {
1601                 Event e = run_until ("locals4");
1602
1603                 // First scope
1604                 var locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1605                 Assert.AreEqual (2, locals.Count);
1606                 var loc = locals.First (l => l.Name == "i");
1607                 Assert.AreEqual ("Int64", loc.Type.Name);
1608                 loc = locals.First (l => l.Name == "s");
1609                 Assert.AreEqual ("String", loc.Type.Name);
1610
1611                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1612                 Assert.AreEqual ("i", loc.Name);
1613                 Assert.AreEqual ("Int64", loc.Type.Name);
1614
1615                 e = run_until ("locals5");
1616
1617                 // Second scope
1618                 locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1619                 Assert.AreEqual (2, locals.Count);
1620                 loc = locals.First (l => l.Name == "i");
1621                 Assert.AreEqual ("String", loc.Type.Name);
1622                 loc = locals.First (l => l.Name == "s");
1623                 Assert.AreEqual ("String", loc.Type.Name);
1624
1625                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1626                 Assert.AreEqual ("i", loc.Name);
1627                 Assert.AreEqual ("String", loc.Type.Name);
1628
1629                 // Variable in another scope
1630                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("j");
1631                 Assert.IsNull (loc);
1632         }
1633
1634         [Test]
1635         public void Exit () {
1636                 run_until ("Main");
1637
1638                 vm.Exit (5);
1639
1640                 var e = GetNextEvent ();
1641                 Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
1642
1643                 var p = vm.Process;
1644                 /* Could be a remote vm with no process */
1645                 if (p != null) {
1646                         p.WaitForExit ();
1647                         Assert.AreEqual (5, p.ExitCode);
1648
1649                         // error handling
1650                         AssertThrows<VMDisconnectedException> (delegate () {
1651                                         vm.Resume ();
1652                                 });
1653                 }
1654
1655                 vm = null;
1656         }
1657
1658         [Test]
1659         public void Dispose () {
1660                 run_until ("Main");
1661
1662                 vm.Detach ();
1663
1664                 var e = GetNextEvent ();
1665                 Assert.IsInstanceOfType (typeof (VMDisconnectEvent), e);
1666
1667                 var p = vm.Process;
1668                 /* Could be a remote vm with no process */
1669                 if (p != null) {
1670                         p.WaitForExit ();
1671                         Assert.AreEqual (3, p.ExitCode);
1672
1673                         // error handling
1674                         AssertThrows<VMDisconnectedException> (delegate () {
1675                                         vm.Resume ();
1676                                 });
1677                 }
1678
1679                 vm = null;
1680         }
1681
1682         [Test]
1683         public void ColumnNumbers () {
1684                 Event e = run_until ("line_numbers");
1685
1686                 // FIXME: Merge this with LineNumbers () when its fixed
1687
1688                 step_req = vm.CreateStepRequest (e.Thread);
1689                 step_req.Depth = StepDepth.Into;
1690                 step_req.Enable ();
1691
1692                 Location l;
1693                 
1694                 vm.Resume ();
1695
1696                 e = GetNextEvent ();
1697                 Assert.IsTrue (e is StepEvent);
1698
1699                 l = e.Thread.GetFrames ()[0].Location;
1700
1701                 Assert.AreEqual (3, l.ColumnNumber);
1702
1703                 step_req.Disable ();
1704         }
1705
1706         [Test]
1707         // Broken by mcs+runtime changes (#5438)
1708         [Category("NotWorking")]
1709         public void LineNumbers () {
1710                 Event e = run_until ("line_numbers");
1711
1712                 step_req = vm.CreateStepRequest (e.Thread);
1713                 step_req.Depth = StepDepth.Into;
1714                 step_req.Enable ();
1715
1716                 Location l;
1717                 
1718                 vm.Resume ();
1719
1720                 e = GetNextEvent ();
1721                 Assert.IsTrue (e is StepEvent);
1722
1723                 l = e.Thread.GetFrames ()[0].Location;
1724
1725                 Assert.IsTrue (l.SourceFile.IndexOf ("dtest-app.cs") != -1);
1726                 Assert.AreEqual ("ln1", l.Method.Name);
1727
1728                 // Check hash
1729                 using (FileStream fs = new FileStream (l.SourceFile, FileMode.Open, FileAccess.Read)) {
1730                         MD5 md5 = MD5.Create ();
1731                         var hash = md5.ComputeHash (fs);
1732
1733                         for (int i = 0; i < 16; ++i)
1734                                 Assert.AreEqual (hash [i], l.SourceFileHash [i]);
1735                 }
1736                 
1737                 int line_base = l.LineNumber;
1738
1739                 vm.Resume ();
1740                 e = GetNextEvent ();
1741                 Assert.IsTrue (e is StepEvent);
1742                 l = e.Thread.GetFrames ()[0].Location;
1743                 Assert.AreEqual ("ln2", l.Method.Name);
1744                 Assert.AreEqual (line_base + 6, l.LineNumber);
1745
1746                 vm.Resume ();
1747                 e = GetNextEvent ();
1748                 Assert.IsTrue (e is StepEvent);
1749                 l = e.Thread.GetFrames ()[0].Location;
1750                 Assert.AreEqual ("ln1", l.Method.Name);
1751                 Assert.AreEqual (line_base + 1, l.LineNumber);
1752
1753                 vm.Resume ();
1754                 e = GetNextEvent ();
1755                 Assert.IsTrue (e is StepEvent);
1756                 l = e.Thread.GetFrames ()[0].Location;
1757                 Assert.AreEqual ("ln3", l.Method.Name);
1758                 Assert.AreEqual (line_base + 11, l.LineNumber);
1759
1760                 vm.Resume ();
1761                 e = GetNextEvent ();
1762                 Assert.IsTrue (e is StepEvent);
1763                 l = e.Thread.GetFrames ()[0].Location;
1764                 Assert.AreEqual ("ln3", l.Method.Name);
1765                 Assert.IsTrue (l.SourceFile.EndsWith ("FOO"));
1766                 Assert.AreEqual (55, l.LineNumber);
1767
1768                 vm.Resume ();
1769                 e = GetNextEvent ();
1770                 Assert.IsTrue (e is StepEvent);
1771                 l = e.Thread.GetFrames ()[0].Location;
1772                 Assert.AreEqual ("ln1", l.Method.Name);
1773                 Assert.AreEqual (line_base + 2, l.LineNumber);
1774
1775                 // GetSourceFiles ()
1776                 string[] sources = l.Method.DeclaringType.GetSourceFiles ();
1777                 Assert.AreEqual (2, sources.Length);
1778                 Assert.AreEqual ("dtest-app.cs", sources [0]);
1779                 Assert.AreEqual ("FOO", sources [1]);
1780
1781                 sources = l.Method.DeclaringType.GetSourceFiles (true);
1782                 Assert.AreEqual (2, sources.Length);
1783                 Assert.IsTrue (sources [0].EndsWith ("dtest-app.cs"));
1784                 Assert.IsTrue (sources [1].EndsWith ("FOO"));
1785         }
1786
1787         [Test]
1788         public void Suspend () {
1789                 vm.Detach ();
1790
1791                 Start (new string [] { "dtest-app.exe", "suspend-test" });
1792
1793                 Event e = run_until ("suspend");
1794
1795                 ThreadMirror main = e.Thread;
1796
1797                 vm.Resume ();
1798
1799                 Thread.Sleep (100);
1800
1801                 vm.Suspend ();
1802
1803                 // The debuggee should be suspended while it is running the infinite loop
1804                 // in suspend ()
1805                 StackFrame frame = main.GetFrames ()[0];
1806                 Assert.AreEqual ("suspend", frame.Method.Name);
1807
1808                 vm.Resume ();
1809
1810                 // resuming when not suspended
1811                 AssertThrows<InvalidOperationException> (delegate () {
1812                                 vm.Resume ();
1813                         });
1814
1815                 vm.Exit (0);
1816
1817                 vm = null;
1818         }
1819
1820         [Test]
1821         public void AssemblyLoad () {
1822                 Event e = run_until ("assembly_load");
1823
1824                 var load_req = vm.CreateAssemblyLoadRequest ();
1825                 load_req.Enable ();
1826
1827                 vm.Resume ();
1828
1829                 e = GetNextEvent ();
1830                 Assert.IsInstanceOfType (typeof (AssemblyLoadEvent), e);
1831                 Assert.IsTrue ((e as AssemblyLoadEvent).Assembly.Location.EndsWith ("System.dll"));
1832
1833                 var frames = e.Thread.GetFrames ();
1834                 Assert.IsTrue (frames.Length > 0);
1835                 Assert.AreEqual ("assembly_load", frames [0].Method.Name);
1836         }
1837
1838         [Test]
1839         public void CreateValue () {
1840                 PrimitiveValue v;
1841
1842                 v = vm.CreateValue (1);
1843                 Assert.AreEqual (vm, v.VirtualMachine);
1844                 Assert.AreEqual (1, v.Value);
1845
1846                 v = vm.CreateValue (null);
1847                 Assert.AreEqual (vm, v.VirtualMachine);
1848                 Assert.AreEqual (null, v.Value);
1849
1850                 // Argument checking
1851                 AssertThrows <ArgumentException> (delegate () {
1852                                 v = vm.CreateValue ("FOO");
1853                         });
1854         }
1855
1856         [Test]
1857         public void CreateString () {
1858                 StringMirror s = vm.RootDomain.CreateString ("ABC");
1859
1860                 Assert.AreEqual (vm, s.VirtualMachine);
1861                 Assert.AreEqual ("ABC", s.Value);
1862                 Assert.AreEqual (vm.RootDomain, s.Domain);
1863
1864                 // Long strings
1865                 StringBuilder sb = new StringBuilder ();
1866                 for (int i = 0; i < 1024; ++i)
1867                         sb.Append ('A');
1868                 s = vm.RootDomain.CreateString (sb.ToString ());
1869
1870                 // Argument checking
1871                 AssertThrows <ArgumentNullException> (delegate () {
1872                                 s = vm.RootDomain.CreateString (null);
1873                         });
1874         }
1875
1876         [Test]
1877         public void CreateBoxedValue () {
1878                 ObjectMirror o = vm.RootDomain.CreateBoxedValue (new PrimitiveValue (vm, 42));
1879
1880                 Assert.AreEqual ("Int32", o.Type.Name);
1881                 //AssertValue (42, m.GetValue (o.Type.GetField ("m_value")));
1882
1883                 // Argument checking
1884                 AssertThrows <ArgumentNullException> (delegate () {
1885                                 vm.RootDomain.CreateBoxedValue (null);
1886                         });
1887
1888                 AssertThrows <ArgumentException> (delegate () {
1889                                 vm.RootDomain.CreateBoxedValue (o);
1890                         });
1891         }
1892
1893         [Test]
1894         public void Invoke () {
1895                 Event e = run_until ("invoke1");
1896
1897                 StackFrame frame = e.Thread.GetFrames () [0];
1898
1899                 TypeMirror t = frame.Method.DeclaringType;
1900                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
1901
1902                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
1903
1904                 MethodMirror m;
1905                 Value v;
1906
1907                 // return void
1908                 m = t.GetMethod ("invoke_return_void");
1909                 v = this_obj.InvokeMethod (e.Thread, m, null);
1910                 Assert.IsNull (v);
1911
1912                 // return ref
1913                 m = t.GetMethod ("invoke_return_ref");
1914                 v = this_obj.InvokeMethod (e.Thread, m, null);
1915                 AssertValue ("ABC", v);
1916
1917                 // return null
1918                 m = t.GetMethod ("invoke_return_null");
1919                 v = this_obj.InvokeMethod (e.Thread, m, null);
1920                 AssertValue (null, v);
1921
1922                 // return primitive
1923                 m = t.GetMethod ("invoke_return_primitive");
1924                 v = this_obj.InvokeMethod (e.Thread, m, null);
1925                 AssertValue (42, v);
1926
1927                 // return nullable
1928                 m = t.GetMethod ("invoke_return_nullable");
1929                 v = this_obj.InvokeMethod (e.Thread, m, null);
1930                 Assert.IsInstanceOfType (typeof (StructMirror), v);
1931                 var s = v as StructMirror;
1932                 AssertValue (42, s.Fields [0]);
1933                 AssertValue (true, s.Fields [1]);
1934
1935                 // pass nullable as this
1936                 //m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
1937                 m = s.Type.GetMethod ("ToString");
1938                 v = s.InvokeMethod (e.Thread, m, null);
1939
1940                 // return nullable null
1941                 m = t.GetMethod ("invoke_return_nullable_null");
1942                 v = this_obj.InvokeMethod (e.Thread, m, null);
1943                 Assert.IsInstanceOfType (typeof (StructMirror), v);
1944                 s = v as StructMirror;
1945                 AssertValue (0, s.Fields [0]);
1946                 AssertValue (false, s.Fields [1]);
1947
1948                 // pass nullable as this
1949                 //m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
1950                 m = s.Type.GetMethod ("ToString");
1951                 v = s.InvokeMethod (e.Thread, m, null);
1952
1953                 // pass primitive
1954                 m = t.GetMethod ("invoke_pass_primitive");
1955                 Value[] args = new Value [] {
1956                         vm.CreateValue ((byte)Byte.MaxValue),
1957                         vm.CreateValue ((sbyte)SByte.MaxValue),
1958                         vm.CreateValue ((short)1),
1959                         vm.CreateValue ((ushort)1),
1960                         vm.CreateValue ((int)1),
1961                         vm.CreateValue ((uint)1),
1962                         vm.CreateValue ((long)1),
1963                         vm.CreateValue ((ulong)1),
1964                         vm.CreateValue ('A'),
1965                         vm.CreateValue (true),
1966                         vm.CreateValue (3.14f),
1967                         vm.CreateValue (3.14) };
1968
1969                 v = this_obj.InvokeMethod (e.Thread, m, args);
1970                 AssertValue ((int)Byte.MaxValue + (int)SByte.MaxValue + 1 + 1 + 1 + 1 + 1 + 1 + 'A' + 1 + 3 + 3, v);
1971
1972                 // pass ref
1973                 m = t.GetMethod ("invoke_pass_ref");
1974                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1975                 AssertValue ("ABC", v);
1976
1977                 // pass null
1978                 m = t.GetMethod ("invoke_pass_ref");
1979                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (null) });
1980                 AssertValue (null, v);
1981
1982                 // static
1983                 m = t.GetMethod ("invoke_static_pass_ref");
1984                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1985                 AssertValue ("ABC", v);
1986
1987                 // static invoked using ObjectMirror.InvokeMethod
1988                 m = t.GetMethod ("invoke_static_pass_ref");
1989                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1990                 AssertValue ("ABC", v);
1991
1992                 // method which throws an exception
1993                 try {
1994                         m = t.GetMethod ("invoke_throws");
1995                         v = this_obj.InvokeMethod (e.Thread, m, null);
1996                         Assert.Fail ();
1997                 } catch (InvocationException ex) {
1998                         Assert.AreEqual ("Exception", ex.Exception.Type.Name);
1999                 }
2000
2001                 // newobj
2002                 m = t.GetMethod (".ctor");
2003                 v = t.InvokeMethod (e.Thread, m, null);
2004                 Assert.IsInstanceOfType (typeof (ObjectMirror), v);
2005                 Assert.AreEqual ("Tests", (v as ObjectMirror).Type.Name);
2006
2007                 // Argument checking
2008                 
2009                 // null thread
2010                 AssertThrows<ArgumentNullException> (delegate {
2011                                 m = t.GetMethod ("invoke_pass_ref");
2012                                 v = this_obj.InvokeMethod (null, m, new Value [] { vm.CreateValue (null) });                            
2013                         });
2014
2015                 // null method
2016                 AssertThrows<ArgumentNullException> (delegate {
2017                                 v = this_obj.InvokeMethod (e.Thread, null, new Value [] { vm.CreateValue (null) });                             
2018                         });
2019
2020                 // invalid number of arguments
2021                 m = t.GetMethod ("invoke_pass_ref");
2022                 AssertThrows<ArgumentException> (delegate {
2023                                 v = this_obj.InvokeMethod (e.Thread, m, null);
2024                         });
2025
2026                 // invalid type of argument (ref != primitive)
2027                 m = t.GetMethod ("invoke_pass_ref");
2028                 AssertThrows<ArgumentException> (delegate {
2029                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2030                         });
2031
2032                 // invalid type of argument (primitive != primitive)
2033                 m = t.GetMethod ("invoke_pass_primitive_2");
2034                 AssertThrows<ArgumentException> (delegate {
2035                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2036                         });
2037
2038                 // invoking a non-static method as static
2039                 m = t.GetMethod ("invoke_pass_ref");
2040                 AssertThrows<ArgumentException> (delegate {
2041                                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2042                         });
2043
2044                 // invoking a method defined in another class
2045                 m = t2.GetMethod ("invoke");
2046                 AssertThrows<ArgumentException> (delegate {
2047                                 v = this_obj.InvokeMethod (e.Thread, m, null);
2048                         });
2049         }
2050
2051         [Test]
2052         public void InvokeVType () {
2053                 Event e = run_until ("invoke1");
2054
2055                 StackFrame frame = e.Thread.GetFrames () [0];
2056
2057                 var s = frame.GetArgument (1) as StructMirror;
2058
2059                 TypeMirror t = s.Type;
2060
2061                 MethodMirror m;
2062                 Value v;
2063
2064                 // Pass struct as this, receive int
2065                 m = t.GetMethod ("invoke_return_int");
2066                 v = s.InvokeMethod (e.Thread, m, null);
2067                 AssertValue (42, v);
2068
2069                 // Pass struct as this, receive intptr
2070                 m = t.GetMethod ("invoke_return_intptr");
2071                 v = s.InvokeMethod (e.Thread, m, null);
2072                 AssertValue (43, v);
2073
2074                 // Static method
2075                 m = t.GetMethod ("invoke_static");
2076                 v = t.InvokeMethod (e.Thread, m, null);
2077                 AssertValue (5, v);
2078
2079                 // Pass generic struct as this
2080                 s = frame.GetArgument (2) as StructMirror;
2081                 t = s.Type;
2082                 m = t.GetMethod ("invoke_return_int");
2083                 v = s.InvokeMethod (e.Thread, m, null);
2084                 AssertValue (42, v);
2085         }
2086
2087         [Test]
2088         public void BreakpointDuringInvoke () {
2089                 Event e = run_until ("invoke1");
2090
2091                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
2092                 Assert.IsNotNull (m);
2093                 vm.SetBreakpoint (m, 0);
2094
2095                 StackFrame frame = e.Thread.GetFrames () [0];
2096                 var o = frame.GetThis () as ObjectMirror;
2097
2098                 bool failed = false;
2099
2100                 bool finished = false;
2101                 object wait = new object ();
2102
2103                 // Have to invoke in a separate thread as the invoke is suspended until we
2104                 // resume after the breakpoint
2105                 Thread t = new Thread (delegate () {
2106                                 try {
2107                                         o.InvokeMethod (e.Thread, m, null);
2108                                 } catch {
2109                                         failed = true;
2110                                 }
2111                                 lock (wait) {
2112                                         finished = true;
2113                                         Monitor.Pulse (wait);
2114                                 }
2115                         });
2116
2117                 t.Start ();
2118
2119                 StackFrame invoke_frame = null;
2120
2121                 try {
2122                         e = GetNextEvent ();
2123                         Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
2124                         // Check stack trace support and invokes
2125                         var frames = e.Thread.GetFrames ();
2126                         invoke_frame = frames [0];
2127                         Assert.AreEqual ("invoke2", frames [0].Method.Name);
2128                         Assert.IsTrue (frames [0].IsDebuggerInvoke);
2129                         Assert.AreEqual ("invoke1", frames [1].Method.Name);
2130                 } finally {
2131                         vm.Resume ();
2132                 }
2133
2134                 lock (wait) {
2135                         if (!finished)
2136                                 Monitor.Wait (wait);
2137                 }
2138
2139                 // Check that the invoke frames are no longer valid
2140                 AssertThrows<InvalidStackFrameException> (delegate {
2141                                 invoke_frame.GetThis ();
2142                         });
2143
2144                 // Check InvokeOptions.DisableBreakpoints flag
2145                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2146         }
2147
2148         [Test]
2149         public void DisabledExceptionDuringInvoke () {
2150                 Event e = run_until ("invoke_ex");
2151
2152                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_ex_inner");
2153
2154                 StackFrame frame = e.Thread.GetFrames () [0];
2155                 var o = frame.GetThis () as ObjectMirror;
2156
2157                 var req = vm.CreateExceptionRequest (null);
2158                 req.Enable ();
2159
2160                 // Check InvokeOptions.DisableBreakpoints flag
2161                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2162
2163                 req.Disable ();
2164         }
2165
2166         [Test]
2167         public void InvokeSingleThreaded () {
2168                 vm.Detach ();
2169
2170                 Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
2171
2172                 Event e = run_until ("invoke_single_threaded_2");
2173
2174                 StackFrame f = e.Thread.GetFrames ()[0];
2175
2176                 var obj = f.GetThis () as ObjectMirror;
2177
2178                 // Check that the counter value incremented by the other thread does not increase
2179                 // during the invoke.
2180                 object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2181
2182                 var m = obj.Type.GetMethod ("invoke_return_void");
2183                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2184
2185             object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2186
2187                 Assert.AreEqual ((int)counter1, (int)counter2);
2188
2189                 // Test multiple invokes done in succession
2190                 m = obj.Type.GetMethod ("invoke_return_void");
2191                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2192
2193                 // Test events during single-threaded invokes
2194                 vm.EnableEvents (EventType.TypeLoad);
2195                 m = obj.Type.GetMethod ("invoke_type_load");
2196                 obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
2197                                 vm.Resume ();
2198                         }, null);
2199
2200                 e = GetNextEvent ();
2201                 Assert.AreEqual (EventType.TypeLoad, e.EventType);
2202         }
2203
2204         List<Value> invoke_results;
2205
2206         [Test]
2207         public void InvokeMultiple () {
2208                 Event e = run_until ("invoke1");
2209
2210                 StackFrame frame = e.Thread.GetFrames () [0];
2211
2212                 TypeMirror t = frame.Method.DeclaringType;
2213                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2214
2215                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2216
2217                 var methods = new MethodMirror [2];
2218                 methods [0] = t.GetMethod ("invoke_return_ref");
2219                 methods [1] = t.GetMethod ("invoke_return_primitive");
2220
2221                 invoke_results = new List<Value> ();
2222
2223                 var r = this_obj.BeginInvokeMultiple (e.Thread, methods, null, InvokeOptions.SingleThreaded, invoke_multiple_cb, this_obj);
2224                 WaitHandle.WaitAll (new WaitHandle[] { r.AsyncWaitHandle });
2225                 this_obj.EndInvokeMultiple (r);
2226                 // The callback might still be running
2227                 while (invoke_results.Count < 2) {
2228                         Thread.Sleep (100);
2229                 }
2230                 AssertValue ("ABC", invoke_results [0]);
2231                 AssertValue (42, invoke_results [1]);
2232         }
2233
2234         void invoke_multiple_cb (IAsyncResult ar) {
2235                 ObjectMirror this_obj = (ObjectMirror)ar.AsyncState;
2236
2237                 var res = this_obj.EndInvokeMethod (ar);
2238                 lock (invoke_results)
2239                         invoke_results.Add (res);
2240         }
2241
2242         [Test]
2243         public void GetThreads () {
2244                 vm.GetThreads ();
2245         }
2246
2247         [Test]
2248         public void Threads () {
2249                 Event e = run_until ("threads");
2250
2251                 Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
2252
2253                 Assert.IsTrue (e.Thread.ThreadId > 0);
2254
2255                 Assert.AreEqual (e.Thread.TID, e.Thread.TID);
2256
2257                 vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
2258
2259                 vm.Resume ();
2260
2261                 e = GetNextEvent ();
2262                 Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
2263                 var state = e.Thread.ThreadState;
2264                 Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
2265
2266                 vm.Resume ();
2267
2268                 e = GetNextEvent ();
2269                 Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
2270                 Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
2271         }
2272
2273         [Test]
2274         public void Frame_SetValue () {
2275                 Event e = run_until ("locals2");
2276
2277                 StackFrame frame = e.Thread.GetFrames () [0];
2278
2279                 // primitive
2280                 var l = frame.Method.GetLocal ("i");
2281                 frame.SetValue (l, vm.CreateValue ((long)55));
2282                 AssertValue (55, frame.GetValue (l));
2283
2284                 // reference
2285                 l = frame.Method.GetLocal ("s");
2286                 frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
2287                 AssertValue ("DEF", frame.GetValue (l));
2288
2289                 // argument as local
2290                 l = frame.Method.GetLocal ("arg");
2291                 frame.SetValue (l, vm.CreateValue (6));
2292                 AssertValue (6, frame.GetValue (l));
2293
2294                 // argument
2295                 var p = frame.Method.GetParameters ()[1];
2296                 frame.SetValue (p, vm.CreateValue (7));
2297                 AssertValue (7, frame.GetValue (p));
2298
2299                 // gshared
2300                 p = frame.Method.GetParameters ()[2];
2301                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF"));
2302                 AssertValue ("DEF", frame.GetValue (p));
2303
2304                 // byref
2305                 p = frame.Method.GetParameters ()[3];
2306                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF2"));
2307                 AssertValue ("DEF2", frame.GetValue (p));
2308
2309                 // argument checking
2310
2311                 // variable null
2312                 AssertThrows<ArgumentNullException> (delegate () {
2313                                 frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
2314                         });
2315
2316                 // value null
2317                 AssertThrows<ArgumentNullException> (delegate () {
2318                                 l = frame.Method.GetLocal ("i");
2319                                 frame.SetValue (l, null);
2320                         });
2321
2322                 // value of invalid type
2323                 AssertThrows<ArgumentException> (delegate () {
2324                                 l = frame.Method.GetLocal ("i");
2325                                 frame.SetValue (l, vm.CreateValue (55));
2326                         });
2327         }
2328
2329         [Test]
2330         [Category ("only")]
2331         public void Frame_SetValue_Registers () {
2332                 Event e = run_until ("locals6_1");
2333
2334                 StackFrame frame = e.Thread.GetFrames () [1];
2335
2336                 // Set 'j' to 99
2337                 var l = frame.Method.GetLocal ("j");
2338                 frame.SetValue (l, vm.CreateValue (99));
2339                 AssertValue (99, frame.GetValue (l));
2340
2341                 // Check it during execution
2342                 e = run_until ("locals6_2");
2343                 frame = e.Thread.GetFrames () [0];
2344                 AssertValue (99, frame.GetValue (frame.Method.GetParameters ()[0]));
2345
2346                 // Set it while in a frame which clobbers its register
2347                 e = run_until ("locals6_3");
2348                 frame = e.Thread.GetFrames () [1];
2349                 frame.SetValue (l, vm.CreateValue (100));
2350                 AssertValue (100, frame.GetValue (l));
2351
2352                 // Check it during execution
2353                 e = run_until ("locals6_4");
2354                 frame = e.Thread.GetFrames () [0];
2355                 AssertValue (100, frame.GetValue (frame.Method.GetParameters ()[0]));
2356
2357                 // Signed byte value
2358                 e = run_until ("locals6_5");
2359                 frame = e.Thread.GetFrames () [1];
2360                 var l2 = frame.Method.GetLocal ("sb");
2361                 frame.SetValue (l2, vm.CreateValue ((sbyte)-99));
2362                 AssertValue (-99, frame.GetValue (l2));
2363
2364                 // Check it during execution
2365                 e = run_until ("locals6_6");
2366                 frame = e.Thread.GetFrames () [0];
2367                 AssertValue (-99, frame.GetValue (frame.Method.GetParameters ()[0]));
2368         }
2369
2370         [Test]
2371         public void InvokeRegress () {
2372                 Event e = run_until ("invoke1");
2373
2374                 StackFrame frame = e.Thread.GetFrames () [0];
2375
2376                 TypeMirror t = frame.Method.DeclaringType;
2377                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2378
2379                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2380
2381                 MethodMirror m;
2382                 Value v;
2383
2384                 // do an invoke
2385                 m = t.GetMethod ("invoke_return_void");
2386                 v = this_obj.InvokeMethod (e.Thread, m, null);
2387                 Assert.IsNull (v);
2388
2389                 // Check that the stack frames remain valid during the invoke
2390                 Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
2391
2392                 // do another invoke
2393                 m = t.GetMethod ("invoke_return_void");
2394                 v = this_obj.InvokeMethod (e.Thread, m, null);
2395                 Assert.IsNull (v);
2396
2397                 // Try a single step after the invoke
2398                 var req = vm.CreateStepRequest (e.Thread);
2399                 req.Depth = StepDepth.Into;
2400                 req.Size = StepSize.Line;
2401                 req.Enable ();
2402
2403                 step_req = req;
2404
2405                 // Skip nop
2406                 step_once ();
2407
2408                 // Step into invoke2
2409                 vm.Resume ();
2410                 e = GetNextEvent ();
2411                 Assert.IsTrue (e is StepEvent);
2412                 Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
2413
2414                 req.Disable ();
2415
2416                 frame = e.Thread.GetFrames () [0];
2417         }
2418
2419         [Test]
2420         public void Exceptions () {
2421                 Event e = run_until ("exceptions");
2422                 var req = vm.CreateExceptionRequest (null);
2423                 req.Enable ();
2424
2425                 vm.Resume ();
2426
2427                 e = GetNextEvent ();
2428                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2429                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2430
2431                 var frames = e.Thread.GetFrames ();
2432                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2433                 req.Disable ();
2434
2435                 // exception type filter
2436
2437                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
2438                 req.Enable ();
2439
2440                 // Skip the throwing of the second OverflowException       
2441                 vm.Resume ();
2442
2443                 e = GetNextEvent ();
2444                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2445                 Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
2446                 req.Disable ();
2447
2448                 // exception type filter for subclasses
2449                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
2450                 req.Enable ();
2451
2452                 vm.Resume ();
2453
2454                 e = GetNextEvent ();
2455                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2456                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2457                 req.Disable ();
2458
2459                 // Implicit exceptions
2460                 req = vm.CreateExceptionRequest (null);
2461                 req.Enable ();
2462
2463                 vm.Resume ();
2464
2465                 e = GetNextEvent ();
2466                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2467                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2468                 req.Disable ();
2469
2470                 // Single stepping after an exception
2471                 req = vm.CreateExceptionRequest (null);
2472                 req.Enable ();
2473
2474                 vm.Resume ();
2475
2476                 e = GetNextEvent ();
2477                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2478                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
2479                 frames = e.Thread.GetFrames ();
2480                 Assert.AreEqual ("exceptions2", frames [0].Method.Name);
2481                 req.Disable ();
2482
2483                 var sreq = vm.CreateStepRequest (e.Thread);
2484                 sreq.Depth = StepDepth.Over;
2485                 sreq.Size = StepSize.Line;
2486                 sreq.Enable ();
2487
2488                 vm.Resume ();
2489                 e = GetNextEvent ();
2490                 Assert.IsInstanceOfType (typeof (StepEvent), e);
2491                 frames = e.Thread.GetFrames ();
2492                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2493                 sreq.Disable ();
2494
2495                 // Argument checking
2496                 AssertThrows<ArgumentException> (delegate {
2497                                 vm.CreateExceptionRequest (e.Thread.Type);
2498                         });
2499         }
2500
2501         [Test]
2502         public void ExceptionFilter () {
2503                 Event e = run_until ("exception_filter");
2504
2505                 MethodMirror m = entry_point.DeclaringType.GetMethod ("exception_filter_filter");
2506                 Assert.IsNotNull (m);
2507
2508                 vm.SetBreakpoint (m, 0);
2509
2510                 vm.Resume ();
2511
2512                 e = GetNextEvent ();
2513                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
2514                 Assert.IsTrue (e is BreakpointEvent);
2515                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
2516
2517                 var frames = e.Thread.GetFrames ();
2518
2519                 Assert.IsTrue (frames [0].Location.SourceFile.IndexOf ("dtest-app.cs") != -1);
2520                 Assert.AreEqual ("exception_filter_filter", frames [0].Location.Method.Name);
2521
2522                 Assert.AreEqual (0, frames [1].Location.Method.MetadataToken);
2523                 Assert.AreEqual (0x0f, frames [1].Location.ILOffset);
2524
2525                 Assert.AreEqual ("exception_filter_method", frames [2].Location.Method.Name);
2526                 Assert.AreEqual (0x06, frames [2].Location.ILOffset);
2527
2528                 Assert.AreEqual (0, frames [3].Location.Method.MetadataToken, 0);
2529                 Assert.AreEqual (0, frames [3].Location.ILOffset);
2530
2531                 Assert.AreEqual ("exception_filter", frames [4].Location.Method.Name);
2532         }
2533
2534         [Test]
2535         public void ExceptionFilter2 () {
2536                 vm.Detach ();
2537
2538                 Start (new string [] { "dtest-excfilter.exe" });
2539
2540                 MethodMirror filter_method = entry_point.DeclaringType.GetMethod ("Filter");
2541                 Assert.IsNotNull (filter_method);
2542
2543                 MethodMirror test_method = entry_point.DeclaringType.GetMethod ("Test");
2544                 Assert.IsNotNull (test_method);
2545
2546                 vm.SetBreakpoint (filter_method, 0);
2547
2548                 vm.Resume ();
2549
2550                 var e = GetNextEvent ();
2551                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
2552                 Assert.IsTrue (e is BreakpointEvent);
2553                 Assert.AreEqual (filter_method.Name, (e as BreakpointEvent).Method.Name);
2554
2555                 var frames = e.Thread.GetFrames ();
2556
2557                 Assert.AreEqual (4, frames.Count ());
2558
2559                 Assert.AreEqual (filter_method.Name, frames [0].Location.Method.Name);
2560                 Assert.AreEqual (20, frames [0].Location.LineNumber);
2561                 Assert.AreEqual (0, frames [0].Location.ILOffset);
2562
2563                 Assert.AreEqual (test_method.Name, frames [1].Location.Method.Name);
2564                 Assert.AreEqual (37, frames [1].Location.LineNumber);
2565                 Assert.AreEqual (0x0b, frames [1].Location.ILOffset);
2566
2567                 Assert.AreEqual (test_method.Name, frames [2].Location.Method.Name);
2568                 Assert.AreEqual (33, frames [2].Location.LineNumber);
2569                 Assert.AreEqual (0x05, frames [2].Location.ILOffset);
2570
2571                 Assert.AreEqual (entry_point.Name, frames [3].Location.Method.Name);
2572                 Assert.AreEqual (14, frames [3].Location.LineNumber);
2573                 Assert.AreEqual (0x00, frames [3].Location.ILOffset);
2574
2575                 vm.Exit (0);
2576
2577                 vm = null;
2578         }
2579
2580         [Test]
2581         public void EventSets () {
2582                 //
2583                 // Create two filter which both match the same exception
2584                 //
2585                 Event e = run_until ("exceptions");
2586
2587                 var req = vm.CreateExceptionRequest (null);
2588                 req.Enable ();
2589
2590                 var req2 = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.OverflowException"));
2591                 req2.Enable ();
2592
2593                 vm.Resume ();
2594
2595                 var es = vm.GetNextEventSet ();
2596                 Assert.AreEqual (2, es.Events.Length);
2597
2598                 e = es [0];
2599                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2600                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2601
2602                 e = es [1];
2603                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2604                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2605
2606                 req.Disable ();
2607                 req2.Disable ();
2608         }
2609
2610         //
2611         // Test single threaded invokes during processing of nullref exceptions.
2612         // These won't work if the exception handling is done from the sigsegv signal
2613         // handler, since the sigsegv signal is disabled until control returns from the
2614         // signal handler.
2615         //
2616         [Test]
2617         [Category ("only3")]
2618         public void NullRefExceptionAndSingleThreadedInvoke () {
2619                 Event e = run_until ("exceptions");
2620                 var req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.NullReferenceException"));
2621                 req.Enable ();
2622
2623                 vm.Resume ();
2624
2625                 e = GetNextEvent ();
2626                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2627                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2628
2629                 var ex = (e as ExceptionEvent).Exception;
2630                 var tostring_method = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2631                 ex.InvokeMethod (e.Thread, tostring_method, null, InvokeOptions.SingleThreaded);
2632         }
2633
2634         [Test]
2635         public void Domains () {
2636                 vm.Detach ();
2637
2638                 Start (new string [] { "dtest-app.exe", "domain-test" });
2639
2640                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
2641
2642                 Event e = run_until ("domains");
2643
2644                 vm.Resume ();
2645                 
2646                 e = GetNextEvent ();
2647                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
2648
2649                 var domain = (e as AppDomainCreateEvent).Domain;
2650
2651                 // Check the object type
2652                 e = run_until ("domains_2");
2653                 var frame = e.Thread.GetFrames ()[0];
2654                 var o = frame.GetArgument (0) as ObjectMirror;
2655                 Assert.AreEqual ("CrossDomain", o.Type.Name);
2656
2657                 // Do a remoting invoke
2658                 var cross_domain_type = o.Type;
2659                 var v = o.InvokeMethod (e.Thread, cross_domain_type.GetMethod ("invoke_3"), null);
2660                 AssertValue (42, v);
2661
2662                 // Run until the callback in the domain
2663                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
2664                 Assert.IsNotNull (m);
2665                 vm.SetBreakpoint (m, 0);
2666
2667                 while (true) {
2668                         vm.Resume ();
2669                         e = GetNextEvent ();
2670                         if (e is BreakpointEvent)
2671                                 break;
2672                 }
2673
2674                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
2675
2676                 // d_method is from another domain
2677                 MethodMirror d_method = (e as BreakpointEvent).Method;
2678                 Assert.IsTrue (m != d_method);
2679
2680                 var frames = e.Thread.GetFrames ();
2681                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
2682                 Assert.AreEqual ("invoke", frames [1].Method.Name);
2683                 Assert.AreEqual ("domains", frames [2].Method.Name);
2684
2685                 // Test breakpoints on already JITted methods in other domains
2686                 m = entry_point.DeclaringType.GetMethod ("invoke_in_domain_2");
2687                 Assert.IsNotNull (m);
2688                 vm.SetBreakpoint (m, 0);
2689
2690                 while (true) {
2691                         vm.Resume ();
2692                         e = GetNextEvent ();
2693                         if (e is BreakpointEvent)
2694                                 break;
2695                 }
2696
2697                 Assert.AreEqual ("invoke_in_domain_2", (e as BreakpointEvent).Method.Name);
2698
2699                 // This is empty when receiving the AppDomainCreateEvent
2700                 Assert.AreEqual ("domain", domain.FriendlyName);
2701
2702                 // Run until the unload
2703                 while (true) {
2704                         vm.Resume ();
2705                         e = GetNextEvent ();
2706                         if (e is AssemblyUnloadEvent) {
2707                                 continue;
2708                         } else {
2709                                 break;
2710                         }
2711                 }
2712                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
2713                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
2714
2715                 // Run past the unload
2716                 e = run_until ("domains_3");
2717
2718                 // Test access to unloaded types
2719                 // FIXME: Add an exception type for this
2720                 AssertThrows<Exception> (delegate {
2721                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
2722                         });
2723         }
2724
2725         [Test]
2726         public void DynamicMethods () {
2727                 Event e = run_until ("dyn_call");
2728
2729                 var m = e.Thread.GetFrames ()[1].Method;
2730                 Assert.AreEqual ("dyn_method", m.Name);
2731
2732                 // Test access to IL
2733                 var body = m.GetMethodBody ();
2734
2735                 ILInstruction ins = body.Instructions [0];
2736                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2737                 Assert.AreEqual ("FOO", ins.Operand);
2738         }
2739
2740         [Test]
2741         public void RefEmit () {
2742                 vm.Detach ();
2743
2744                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
2745
2746                 Event e = run_until ("ref_emit_call");
2747
2748                 var m = e.Thread.GetFrames ()[1].Method;
2749                 Assert.AreEqual ("ref_emit_method", m.Name);
2750
2751                 // Test access to IL
2752                 var body = m.GetMethodBody ();
2753
2754                 ILInstruction ins;
2755
2756                 ins = body.Instructions [0];
2757                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2758                 Assert.AreEqual ("FOO", ins.Operand);
2759
2760                 ins = body.Instructions [1];
2761                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
2762                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
2763                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
2764         }
2765
2766         [Test]
2767         public void IsAttached () {
2768                 var f = entry_point.DeclaringType.GetField ("is_attached");
2769
2770                 Event e = run_until ("Main");
2771
2772                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
2773         }
2774
2775         [Test]
2776         public void StackTraceInNative () {
2777                 // Check that stack traces can be produced for threads in native code
2778                 vm.Detach ();
2779
2780                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
2781
2782                 var e = run_until ("frames_in_native");
2783
2784                 // FIXME: This is racy
2785                 vm.Resume ();
2786
2787                 Thread.Sleep (100);
2788
2789                 vm.Suspend ();
2790
2791                 StackFrame[] frames = e.Thread.GetFrames ();
2792
2793                 int frame_index = -1;
2794                 for (int i = 0; i < frames.Length; ++i) {
2795                         if (frames [i].Method.Name == "Sleep") {
2796                                 frame_index = i;
2797                                 break;
2798                         }
2799                 }
2800
2801                 Assert.IsTrue (frame_index != -1);
2802                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
2803                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
2804                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
2805
2806                 // Check that invokes are disabled for such threads
2807                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
2808
2809                 var m = t.GetMethod ("invoke_static_return_void");
2810                 AssertThrows<InvalidOperationException> (delegate {
2811                                 t.InvokeMethod (e.Thread, m, null);
2812                         });
2813
2814                 // Check that the frame info is invalidated
2815                 run_until ("frames_in_native_2");
2816
2817                 AssertThrows<InvalidStackFrameException> (delegate {
2818                                 Console.WriteLine (frames [frame_index].GetThis ());
2819                         });
2820         }
2821
2822         [Test]
2823         public void VirtualMachine_CreateEnumMirror () {
2824                 var e = run_until ("o1");
2825                 var frame = e.Thread.GetFrames () [0];
2826
2827                 object val = frame.GetThis ();
2828                 Assert.IsTrue (val is ObjectMirror);
2829                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
2830                 ObjectMirror o = (val as ObjectMirror);
2831
2832                 FieldInfoMirror field = o.Type.GetField ("field_enum");
2833                 Value f = o.GetValue (field);
2834                 TypeMirror enumType = (f as EnumMirror).Type;
2835
2836                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
2837                 f = o.GetValue (field);
2838                 Assert.AreEqual (1, (f as EnumMirror).Value);
2839
2840                 // Argument checking
2841                 AssertThrows<ArgumentNullException> (delegate () {
2842                                 vm.CreateEnumMirror (enumType, null);
2843                         });
2844
2845                 AssertThrows<ArgumentNullException> (delegate () {
2846                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
2847                         });
2848
2849                 // null value
2850                 AssertThrows<ArgumentException> (delegate () {
2851                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
2852                         });
2853
2854                 // value of a wrong type
2855                 AssertThrows<ArgumentException> (delegate () {
2856                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
2857                         });
2858         }
2859
2860         [Test]
2861         public void VirtualMachine_EnableEvents_Breakpoint () {
2862                 AssertThrows<ArgumentException> (delegate () {
2863                                 vm.EnableEvents (EventType.Breakpoint);
2864                         });
2865         }
2866
2867         [Test]
2868         public void SingleStepRegress654694 () {
2869                 int il_offset = -1;
2870
2871                 MethodMirror m = entry_point.DeclaringType.GetMethod ("ss_regress_654694");
2872                 foreach (Location l in m.Locations) {
2873                         if (l.ILOffset > 0 && il_offset == -1)
2874                                 il_offset = l.ILOffset;
2875                 }
2876
2877                 Event e = run_until ("ss_regress_654694");
2878
2879                 Assert.IsNotNull (m);
2880                 vm.SetBreakpoint (m, il_offset);
2881
2882                 vm.Resume ();
2883
2884                 e = GetNextEvent ();
2885                 Assert.IsTrue (e is BreakpointEvent);
2886
2887                 var req = vm.CreateStepRequest (e.Thread);
2888                 req.Depth = StepDepth.Over;
2889                 req.Size = StepSize.Line;
2890                 req.Enable ();
2891
2892                 vm.Resume ();
2893
2894                 e = GetNextEvent ();
2895                 Assert.IsTrue (e is StepEvent);
2896
2897                 req.Disable ();
2898         }
2899
2900         [Test]
2901         public void DebugBreak () {
2902                 vm.EnableEvents (EventType.UserBreak);
2903
2904                 run_until ("user");
2905
2906                 vm.Resume ();
2907                 var e = GetNextEvent ();
2908                 Assert.IsTrue (e is UserBreakEvent);
2909         }
2910
2911         [Test]
2912         public void DebugLog () {
2913                 vm.EnableEvents (EventType.UserLog);
2914
2915                 run_until ("user");
2916
2917                 vm.Resume ();
2918                 var e = GetNextEvent ();
2919                 Assert.IsTrue (e is UserLogEvent);
2920                 var le = e as UserLogEvent;
2921
2922                 Assert.AreEqual (5, le.Level);
2923                 Assert.AreEqual ("A", le.Category);
2924                 Assert.AreEqual ("B", le.Message);
2925         }
2926
2927         [Test]
2928         public void TypeGetMethodsByNameFlags () {
2929                 MethodMirror[] mm;
2930                 var assembly = entry_point.DeclaringType.Assembly;
2931                 var type = assembly.GetType ("Tests3");
2932
2933                 Assert.IsNotNull (type);
2934
2935                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Public, false);
2936                 Assert.AreEqual (1, mm.Length, "#1");
2937                 Assert.AreEqual ("M1", mm[0].Name, "#2");
2938
2939                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.NonPublic, false);
2940                 Assert.AreEqual (1, mm.Length, "#3");
2941                 Assert.AreEqual ("M2", mm[0].Name, "#4");
2942
2943                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public, false);
2944                 Assert.AreEqual (7, mm.Length, "#5"); //M3 plus Equals, GetHashCode, GetType, ToString, .ctor
2945
2946                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, false);
2947                 Assert.AreEqual (2, mm.Length, "#7");
2948
2949                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
2950                 Assert.AreEqual (1, mm.Length, "#9");
2951
2952                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
2953                 Assert.AreEqual (5, mm.Length, "#11");
2954
2955                 //Now with name
2956                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static | BindingFlags.Public, false);
2957                 Assert.AreEqual (1, mm.Length, "#12");
2958                 Assert.AreEqual ("M1", mm[0].Name, "#13");
2959
2960                 mm = type.GetMethodsByNameFlags ("m1", BindingFlags.Static | BindingFlags.Public, true);
2961                 Assert.AreEqual (1, mm.Length, "#14");
2962                 Assert.AreEqual ("M1", mm[0].Name, "#15");
2963
2964                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static  | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, false);
2965                 Assert.AreEqual (1, mm.Length, "#16");
2966                 Assert.AreEqual ("M1", mm[0].Name, "#17");
2967         }
2968
2969         [Test]
2970         [Category ("only88")]
2971         public void TypeLoadSourceFileFilter () {
2972                 Event e = run_until ("type_load");
2973
2974                 if (!vm.Version.AtLeast (2, 7))
2975                         return;
2976
2977                 string srcfile = (e as BreakpointEvent).Method.DeclaringType.GetSourceFiles (true)[0];
2978
2979                 var req = vm.CreateTypeLoadRequest ();
2980                 req.SourceFileFilter = new string [] { srcfile.ToUpper () };
2981                 req.Enable ();
2982
2983                 vm.Resume ();
2984                 e = GetNextEvent ();
2985                 Assert.IsTrue (e is TypeLoadEvent);
2986                 Assert.AreEqual ("TypeLoadClass", (e as TypeLoadEvent).Type.FullName);
2987         }
2988
2989         [Test]
2990         public void TypeLoadTypeNameFilter () {
2991                 Event e = run_until ("type_load");
2992
2993                 var req = vm.CreateTypeLoadRequest ();
2994                 req.TypeNameFilter = new string [] { "TypeLoadClass2" };
2995                 req.Enable ();
2996
2997                 vm.Resume ();
2998                 e = GetNextEvent ();
2999                 Assert.IsTrue (e is TypeLoadEvent);
3000                 Assert.AreEqual ("TypeLoadClass2", (e as TypeLoadEvent).Type.FullName);
3001         }
3002
3003         [Test]
3004         public void GetTypesForSourceFile () {
3005                 run_until ("user");
3006
3007                 var types = vm.GetTypesForSourceFile ("dtest-app.cs", false);
3008                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3009                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3010
3011                 types = vm.GetTypesForSourceFile ("DTEST-app.cs", true);
3012                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3013                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3014         }
3015
3016         [Test]
3017         public void GetTypesNamed () {
3018                 run_until ("user");
3019
3020                 var types = vm.GetTypes ("Tests", false);
3021                 Assert.AreEqual (1, types.Count);
3022                 Assert.AreEqual ("Tests", types [0].FullName);
3023
3024                 types = vm.GetTypes ("System.Exception", false);
3025                 Assert.AreEqual (1, types.Count);
3026                 Assert.AreEqual ("System.Exception", types [0].FullName);
3027         }
3028
3029         [Test]
3030         public void String_GetChars () {
3031                 object val;
3032
3033                 // Reuse this test
3034                 var e = run_until ("arg2");
3035
3036                 var frame = e.Thread.GetFrames () [0];
3037
3038                 val = frame.GetArgument (0);
3039                 Assert.IsTrue (val is StringMirror);
3040                 AssertValue ("FOO", val);
3041                 var s = (val as StringMirror);
3042                 Assert.AreEqual (3, s.Length);
3043
3044                 var c = s.GetChars (0, 2);
3045                 Assert.AreEqual (2, c.Length);
3046                 Assert.AreEqual ('F', c [0]);
3047                 Assert.AreEqual ('O', c [1]);
3048
3049                 AssertThrows<ArgumentException> (delegate () {          
3050                                 s.GetChars (2, 2);
3051                         });
3052         }
3053
3054         [Test]
3055         public void GetInterfaces () {
3056                 var e = run_until ("arg2");
3057
3058                 var frame = e.Thread.GetFrames () [0];
3059
3060                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3061                 var ifaces = cl1.GetInterfaces ();
3062                 Assert.AreEqual (1, ifaces.Length);
3063                 Assert.AreEqual ("ITest", ifaces [0].Name);
3064
3065                 var cl2 = cl1.GetMethod ("Baz").ReturnType;
3066                 var ifaces2 = cl2.GetInterfaces ();
3067                 Assert.AreEqual (1, ifaces2.Length);
3068                 Assert.AreEqual ("ITest`1", ifaces2 [0].Name);
3069         }
3070
3071         [Test]
3072         public void GetInterfaceMap () {
3073                 var e = run_until ("arg2");
3074
3075                 var frame = e.Thread.GetFrames () [0];
3076
3077                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3078                 var iface = cl1.Assembly.GetType ("ITest");
3079                 var map = cl1.GetInterfaceMap (iface);
3080                 Assert.AreEqual (cl1, map.TargetType);
3081                 Assert.AreEqual (iface, map.InterfaceType);
3082                 Assert.AreEqual (2, map.InterfaceMethods.Length);
3083                 Assert.AreEqual (2, map.TargetMethods.Length);
3084         }
3085
3086         [Test]
3087         public void StackAlloc_Breakpoints_Regress2775 () {
3088                 // Check that breakpoints on arm don't overwrite stackalloc-ed memory
3089                 var e = run_until ("regress_2755");
3090
3091                 var frame = e.Thread.GetFrames () [0];
3092                 var m = e.Method;
3093                 // This breaks at the call site
3094                 vm.SetBreakpoint (m, m.Locations [2].ILOffset);
3095
3096                 vm.Resume ();
3097                 var e2 = GetNextEvent ();
3098                 Assert.IsTrue (e2 is BreakpointEvent);
3099
3100                 e = run_until ("regress_2755_3");
3101                 frame = e.Thread.GetFrames () [1];
3102                 var res = frame.GetValue (m.GetLocal ("sum"));
3103                 AssertValue (0, res);
3104         }
3105
3106         [Test]
3107         public void MethodInfo () {
3108                 Event e = run_until ("locals2");
3109
3110                 StackFrame frame = e.Thread.GetFrames () [0];
3111                 var m = frame.Method;
3112
3113                 Assert.IsTrue (m.IsGenericMethod);
3114                 Assert.IsFalse (m.IsGenericMethodDefinition);
3115
3116                 var args = m.GetGenericArguments ();
3117                 Assert.AreEqual (1, args.Length);
3118                 Assert.AreEqual ("String", args [0].Name);
3119
3120                 var gmd = m.GetGenericMethodDefinition ();
3121                 Assert.IsTrue (gmd.IsGenericMethod);
3122                 Assert.IsTrue (gmd.IsGenericMethodDefinition);
3123                 Assert.AreEqual (gmd, gmd.GetGenericMethodDefinition ());
3124
3125                 args = gmd.GetGenericArguments ();
3126                 Assert.AreEqual (1, args.Length);
3127                 Assert.AreEqual ("T", args [0].Name);
3128
3129                 var attrs = m.GetCustomAttributes (true);
3130                 Assert.AreEqual (1, attrs.Length);
3131                 Assert.AreEqual ("StateMachineAttribute", attrs [0].Constructor.DeclaringType.Name);
3132         }
3133
3134         [Test]
3135         public void UnhandledException () {
3136                 vm.Exit (0);
3137
3138                 Start (new string [] { "dtest-app.exe", "unhandled-exception" });
3139
3140                 var req = vm.CreateExceptionRequest (null, false, true);
3141                 req.Enable ();
3142
3143                 var e = run_until ("unhandled_exception");
3144                 vm.Resume ();
3145
3146                 var e2 = GetNextEvent ();
3147                 Assert.IsTrue (e2 is ExceptionEvent);
3148
3149                 vm.Exit (0);
3150                 vm = null;
3151         }
3152
3153         [Test]
3154         public void UnhandledException_2 () {
3155                 vm.Exit (0);
3156
3157                 Start (new string [] { "dtest-app.exe", "unhandled-exception-endinvoke" });
3158
3159                 var req = vm.CreateExceptionRequest (null, false, true);
3160                 req.Enable ();
3161
3162                 MethodMirror m = entry_point.DeclaringType.GetMethod ("unhandled_exception_endinvoke_2");
3163                 Assert.IsNotNull (m);
3164                 vm.SetBreakpoint (m, m.ILOffsets [0]);
3165
3166                 var e = run_until ("unhandled_exception_endinvoke");
3167                 vm.Resume ();
3168
3169                 var e2 = GetNextEvent ();
3170                 Assert.IsFalse (e2 is ExceptionEvent);
3171
3172                 vm.Exit (0);
3173                 vm = null;
3174         }
3175
3176 #if NET_4_5
3177         [Test]
3178         public void UnhandledExceptionUserCode () {
3179                 vm.Detach ();
3180
3181                 // Exceptions caught in non-user code are treated as unhandled
3182                 Start (new string [] { "dtest-app.exe", "unhandled-exception-user" });
3183
3184                 var req = vm.CreateExceptionRequest (null, false, true);
3185                 req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
3186                 req.Enable ();
3187
3188                 var e = run_until ("unhandled_exception_user");
3189                 vm.Resume ();
3190
3191                 var e2 = GetNextEvent ();
3192                 Assert.IsTrue (e2 is ExceptionEvent);
3193
3194                 vm.Exit (0);
3195                 vm = null;
3196         }
3197 #endif
3198
3199         [Test]
3200         public void GCWhileSuspended () {
3201                 // Check that objects are kept alive during suspensions
3202                 Event e = run_until ("gc_suspend_1");
3203
3204                 MethodMirror m = entry_point.DeclaringType.GetMethod ("gc_suspend_invoke");
3205
3206                 var o = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3207                 //Console.WriteLine (o);
3208
3209                 StackFrame frame = e.Thread.GetFrames () [0];
3210                 TypeMirror t = frame.Method.DeclaringType;
3211                 for (int i = 0; i < 10; ++i)
3212                         t.InvokeMethod (e.Thread, m, new Value [] { });
3213
3214                 // This throws an exception if the object is collected
3215                 long addr = o.Address;
3216
3217                 var o2 = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3218                 Assert.IsNull (o2);
3219         }
3220
3221         [Test]
3222         public void MakeGenericMethod () {
3223                 Event e = run_until ("bp1");
3224
3225                 var intm = vm.RootDomain.GetCorrespondingType (typeof (int));
3226                 var stringm = vm.RootDomain.GetCorrespondingType (typeof (string));
3227                 var gm = entry_point.DeclaringType.GetMethod ("generic_method");
3228                 var res = gm.MakeGenericMethod (new TypeMirror [] { stringm });
3229                 var args = res.GetGenericArguments ();
3230                 Assert.AreEqual (1, args.Length);
3231                 Assert.AreEqual (stringm, args [0]);
3232
3233                 // Error checking
3234                 AssertThrows<ArgumentNullException> (delegate {
3235                                 gm.MakeGenericMethod (null);
3236                         });
3237                 AssertThrows<ArgumentNullException> (delegate {
3238                                 gm.MakeGenericMethod (new TypeMirror [] { null });
3239                         });
3240                 AssertThrows<ArgumentException> (delegate {
3241                                 gm.MakeGenericMethod (new TypeMirror [] { stringm, stringm });
3242                         });
3243                 AssertThrows<InvalidOperationException> (delegate {
3244                                 gm.MakeGenericMethod (new TypeMirror [] { intm });
3245                         });
3246                 AssertThrows<InvalidOperationException> (delegate {
3247                                 entry_point.DeclaringType.GetMethod ("Main").MakeGenericMethod (new TypeMirror [] { intm });
3248                         });
3249         }
3250
3251         [Test]
3252         public void InspectThreadSuspenedOnWaitOne () {
3253                 TearDown ();
3254                 Start (true, "dtest-app.exe", "wait-one" );
3255
3256                 ThreadMirror.NativeTransitions = true;
3257
3258                 var evt = run_until ("wait_one");
3259                 Assert.IsNotNull (evt, "#1");
3260
3261                 var thread = evt.Thread;
3262                 Assert.AreEqual (ThreadState.Running, thread.ThreadState, "#1.1");
3263
3264                 var frames = thread.GetFrames ();
3265                 Assert.IsNotNull (frames, "#2");
3266                 Assert.AreEqual (2, frames.Length, "#3");
3267                 Assert.AreEqual ("wait_one", frames [0].Method.Name, "#4");
3268                 Assert.AreEqual ("Main", frames [1].Method.Name, "#5");
3269
3270                 vm.Resume ();
3271
3272                 Thread.Sleep (500); //FIXME this is racy, maybe single step? or something?
3273
3274                 vm.Suspend ();
3275                 Assert.AreEqual (ThreadState.WaitSleepJoin, thread.ThreadState, "#6");
3276
3277                 frames = thread.GetFrames ();
3278                 Assert.AreEqual (4, frames.Length, "#7");
3279                 Assert.AreEqual ("WaitOne_internal", frames [0].Method.Name, "#8");
3280                 Assert.AreEqual ("WaitOne", frames [1].Method.Name, "#8.1");
3281                 Assert.AreEqual ("wait_one", frames [2].Method.Name, "#9");
3282                 Assert.AreEqual ("Main", frames [3].Method.Name, "#10");
3283
3284
3285                 var frame = frames [0];
3286                 Assert.IsTrue (frame.IsNativeTransition, "#11.1");
3287                 try {
3288                         frame.GetThis ();
3289                         Assert.Fail ("Known limitation - can't get info from m2n frames");
3290                 } catch (AbsentInformationException) {}
3291
3292                 frame = frames [1];
3293                 Assert.IsFalse (frame.IsNativeTransition, "#12.1");
3294                 var wait_one_this = frame.GetThis ();
3295                 Assert.IsNotNull (wait_one_this, "#12.2");
3296
3297                 frame = frames [2];
3298                 var locals = frame.GetVisibleVariables ();
3299                 Assert.AreEqual (1, locals.Count, "#13.1");
3300
3301                 var local_0 = frame.GetValue (locals [0]);
3302                 Assert.IsNotNull (local_0, "#13.2");
3303
3304                 Assert.AreEqual (wait_one_this, local_0, "#14.2");
3305         }
3306 }
3307
3308 }