SqlBulkCopy Implementation
[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                 var req = 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                 req.Disable ();
120
121                 Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
122                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
123
124                 return (e as BreakpointEvent);
125         }
126
127         Event single_step (ThreadMirror t) {
128                 var req = vm.CreateStepRequest (t);
129                 req.Enable ();
130
131                 vm.Resume ();
132                 Event e = GetNextEvent ();
133                 Assert.IsTrue (e is StepEvent);
134
135                 req.Disable ();
136
137                 return e;
138         }
139
140         Event step_until (ThreadMirror t, string method_name) {
141                 Event e;
142                 while (true) {
143                         e = single_step (t);
144                         if ((e as StepEvent).Method.Name == method_name)
145                                 break;
146                 }
147                 return e;
148         }
149
150         void check_arg_val (StackFrame frame, int pos, Type type, object eval) {
151                 object val = frame.GetArgument (pos);
152                 Assert.IsTrue (val is PrimitiveValue);
153                 object v = (val as PrimitiveValue).Value;
154                 Assert.AreEqual (type, v.GetType ());
155                 if (eval is float)
156                         Assert.IsTrue (Math.Abs ((float)eval - (float)v) < 0.0001);
157                 else if (eval is double)
158                         Assert.IsTrue (Math.Abs ((double)eval - (double)v) < 0.0001);
159                 else
160                         Assert.AreEqual (eval, v);
161         }
162
163         void AssertValue (object expected, object val) {
164                 if (expected is string) {
165                         Assert.IsTrue (val is StringMirror);
166                         Assert.AreEqual (expected, (val as StringMirror).Value);
167                 } else if (val is StructMirror && (val as StructMirror).Type.Name == "IntPtr") {
168                         AssertValue (expected, (val as StructMirror).Fields [0]);
169                 } else {
170                         Assert.IsTrue (val is PrimitiveValue);
171                         Assert.AreEqual (expected, (val as PrimitiveValue).Value);
172                 }
173         }
174
175         [SetUp]
176         public void SetUp () {
177                 ThreadMirror.NativeTransitions = false;
178                 Start (new string [] { "dtest-app.exe" });
179         }
180
181         [TearDown]
182         public void TearDown () {
183                 if (vm == null)
184                         return;
185
186                 if (step_req != null)
187                         step_req.Disable ();
188
189                 vm.Resume ();
190                 if (forceExit)
191                         vm.Exit (0);
192
193                 while (true) {
194                         Event e = GetNextEvent ();
195
196                         if (e is VMDeathEvent)
197                                 break;
198
199                         vm.Resume ();
200                 }
201                 vm = null;
202         }
203
204         [Test]
205         public void SimpleBreakpoint () {
206                 Event e;
207
208                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp1");
209                 Assert.IsNotNull (m);
210
211                 vm.SetBreakpoint (m, 0);
212
213                 vm.Resume ();
214
215                 e = GetNextEvent ();
216                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
217                 Assert.IsTrue (e is BreakpointEvent);
218                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
219
220                 // Argument checking
221                 AssertThrows<ArgumentException> (delegate {
222                                 // Invalid IL offset
223                                 vm.SetBreakpoint (m, 2);
224                         });
225         }
226
227         [Test]
228         public void BreakpointsSameLocation () {
229                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp2");
230                 Assert.IsNotNull (m);
231
232                 vm.SetBreakpoint (m, 0);
233                 vm.SetBreakpoint (m, 0);
234
235                 vm.Resume ();
236
237                 var es = vm.GetNextEventSet ();
238                 Assert.AreEqual (2, es.Events.Length);
239                 Assert.IsTrue (es [0] is BreakpointEvent);
240                 Assert.AreEqual (m, (es [0] as BreakpointEvent).Method);
241
242                 Assert.IsTrue (es [1] is BreakpointEvent);
243                 Assert.AreEqual (m.Name, (es [1] as BreakpointEvent).Method.Name);
244         }
245
246         [Test]
247         public void BreakpointAlreadyJITted () {
248                 Event e = run_until ("bp1");
249
250                 /* Place a breakpoint on bp3 */
251                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp3");
252                 Assert.IsNotNull (m);
253                 vm.SetBreakpoint (m, 0);
254
255                 /* Same with generic instances */
256                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp7");
257                 Assert.IsNotNull (m2);
258                 vm.SetBreakpoint (m2, 0);
259
260                 vm.Resume ();
261
262                 e = GetNextEvent ();
263                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
264                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
265
266                 vm.Resume ();
267
268                 /* Non-shared instance */
269                 e = GetNextEvent ();
270                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
271                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
272
273                 vm.Resume ();
274
275                 /* Shared instance */
276                 e = GetNextEvent ();
277                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
278                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
279         }
280
281         [Test]
282         public void ClearBreakpoint () {
283                 Event e;
284
285                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
286                 Assert.IsNotNull (m);
287                 EventRequest req1 = vm.SetBreakpoint (m, 0);
288                 EventRequest req2 = vm.SetBreakpoint (m, 0);
289
290                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
291                 Assert.IsNotNull (m2);
292                 vm.SetBreakpoint (m2, 0);
293
294                 /* Run until bp4 */
295                 vm.Resume ();
296
297                 var es = vm.GetNextEventSet ();
298                 Assert.AreEqual (2, es.Events.Length);
299                 Assert.AreEqual (EventType.Breakpoint, es [0].EventType);
300                 Assert.AreEqual (m.Name, (es [0] as BreakpointEvent).Method.Name);
301                 Assert.AreEqual (EventType.Breakpoint, es [1].EventType);
302                 Assert.AreEqual (m.Name, (es [1] as BreakpointEvent).Method.Name);
303
304                 /* Clear one of them */
305                 req1.Disable ();
306
307                 vm.Resume ();
308
309                 e = GetNextEvent ();
310                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
311                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
312
313                 /* Clear the other */
314                 req2.Disable ();
315
316                 vm.Resume ();
317
318                 e = GetNextEvent ();
319                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
320                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
321         }
322
323         [Test]
324         public void ClearAllBreakpoints () {
325                 Event e;
326
327                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
328                 Assert.IsNotNull (m);
329                 vm.SetBreakpoint (m, 0);
330
331                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
332                 Assert.IsNotNull (m2);
333                 vm.SetBreakpoint (m2, 0);
334
335                 vm.ClearAllBreakpoints ();
336
337                 vm.Resume ();
338
339                 e = GetNextEvent ();
340                 Assert.IsTrue (!(e is BreakpointEvent));
341                 if (e is VMDeathEvent)
342                         vm = null;
343         }
344
345         [Test]
346         public void BreakpointOnGShared () {
347                 Event e;
348
349                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp6");
350                 Assert.IsNotNull (m);
351
352                 vm.SetBreakpoint (m, 0);
353
354                 vm.Resume ();
355
356                 e = GetNextEvent ();
357                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
358                 Assert.IsTrue (e is BreakpointEvent);
359                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
360
361                 // Breakpoint on an open generic method of a closed generic class (#3422)
362                 var frame = e.Thread.GetFrames ()[0];
363                 var ginst = frame.GetValue (frame.Method.GetLocal ("gc"));
364                 var m2 = (ginst as ObjectMirror).Type.GetMethod ("bp");
365                 vm.SetBreakpoint (m2, 0);
366
367                 vm.Resume ();
368
369                 e = GetNextEvent ();
370                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
371                 Assert.IsTrue (e is BreakpointEvent);
372                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
373         }
374
375         void assert_location (Event e, string method) {
376                 Assert.IsTrue (e is StepEvent);
377                 Assert.AreEqual (method, (e as StepEvent).Method.Name);
378         }
379
380         StepEventRequest create_step (Event e) {
381                 var req = vm.CreateStepRequest (e.Thread);
382                 step_req = req;
383                 return req;
384         }
385
386         [Test]
387         public void SingleStepping () {
388                 Event e = run_until ("single_stepping");
389
390                 var req = create_step (e);
391                 req.Enable ();
392
393                 // Step over 'bool b = true'
394                 e = step_once ();
395                 assert_location (e, "single_stepping");
396
397                 // Skip nop
398                 step_once ();
399
400                 // Step into ss1
401                 e = step_once ();
402                 assert_location (e, "ss1");
403
404                 // Skip }
405                 e = step_once ();
406
407                 // Step out of ss1
408                 e = step_once ();
409                 assert_location (e, "single_stepping");
410
411                 // Step over ss2
412                 e = step_over ();
413                 assert_location (e, "single_stepping");
414
415                 // Step into ss3
416                 e = step_into ();
417                 assert_location (e, "ss3");
418
419                 // Step back into single_stepping
420                 e = step_out ();
421                 assert_location (e, "single_stepping");
422
423                 // Step into ss3_2 ()
424                 e = step_into ();
425                 assert_location (e, "ss3_2");
426
427                 // Step over ss3_2_2 ()
428                 e = step_over ();
429                 assert_location (e, "ss3_2");
430
431                 // Recreate the request
432                 req.Disable ();
433                 req.Enable ();
434
435                 // Skip }
436                 e = step_once ();
437
438                 // Step back into single_stepping () with the new request
439                 e = step_once ();
440                 assert_location (e, "single_stepping");
441
442                 // Step into ss4 ()
443                 e = step_into ();
444                 assert_location (e, "ss4");
445
446                 // Skip nop
447                 e = step_once ();
448
449                 // Change to StepSize.Line
450                 req.Disable ();
451                 req.Depth = StepDepth.Over;
452                 req.Size = StepSize.Line;
453                 req.Enable ();
454
455                 // Step over ss1 (); ss1 ();
456                 e = step_once ();
457
458                 // Step into ss2 ()
459                 req.Disable ();
460                 req.Depth = StepDepth.Into;
461                 req.Enable ();
462
463                 e = step_once ();
464                 assert_location (e, "ss2");
465
466                 req.Disable ();
467
468                 // Run until ss5
469                 e = run_until ("ss5");
470
471                 // Add an assembly filter
472                 req.AssemblyFilter = new AssemblyMirror [] { (e as BreakpointEvent).Method.DeclaringType.Assembly };
473                 req.Enable ();
474
475                 // Skip nop
476                 e = step_once ();
477
478                 // Step into is_even, skipping the linq stuff
479                 e = step_once ();
480                 assert_location (e, "is_even");
481
482                 // FIXME: Check that single stepping works with lock (obj)
483                 req.Disable ();
484
485                 // Run until ss6
486                 e = run_until ("ss6");
487
488                 req = create_step (e);
489                 req.Depth = StepDepth.Over;
490                 req.Enable ();
491
492                 // Check that single stepping works in out-of-line bblocks
493                 e = step_once ();
494                 e = step_once ();
495                 assert_location (e, "ss6");
496                 req.Disable ();
497
498                 // Check that a step over stops at an EH clause
499                 e = run_until ("ss7_2");
500                 req = create_step (e);
501                 req.Depth = StepDepth.Out;
502                 req.Enable ();
503                 e = step_once ();
504                 assert_location (e, "ss7");
505                 req.Disable ();
506                 req = create_step (e);
507                 req.Depth = StepDepth.Over;
508                 req.Enable ();
509                 e = step_once ();
510                 assert_location (e, "ss7");
511                 req.Disable ();
512
513                 // Check that stepping stops between nested calls
514                 e = run_until ("ss_nested_2");
515                 e = step_out ();
516                 assert_location (e, "ss_nested");
517                 e = step_into ();
518                 assert_location (e, "ss_nested_1");
519                 e = step_out ();
520                 Console.WriteLine ("A: " + e.Thread.GetFrames ()[0].Location);
521                 assert_location (e, "ss_nested");
522                 // Check that step over steps over nested calls
523                 e = step_over ();
524                 assert_location (e, "ss_nested");
525                 e = step_into ();
526                 assert_location (e, "ss_nested_3");
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                 // Check decoding of nested structs (#14942)
1329                 obj = o.GetValue (o.Type.GetField ("nested_struct"));
1330                 o.SetValue (o.Type.GetField ("nested_struct"), obj);
1331
1332                 // Check round tripping of boxed struct fields (#12354)
1333                 obj = o.GetValue (o.Type.GetField ("boxed_struct_field"));
1334                 o.SetValue (o.Type.GetField ("boxed_struct_field"), obj);
1335                 obj = o.GetValue (o.Type.GetField ("boxed_struct_field"));
1336                 s = obj as StructMirror;
1337                 AssertValue (1, s ["key"]);
1338                 obj = s ["value"];
1339                 Assert.IsTrue (obj is StructMirror);
1340                 s = obj as StructMirror;
1341                 AssertValue (42, s ["m_value"]);
1342
1343                 // vtypes as arguments
1344                 s = frame.GetArgument (0) as StructMirror;
1345                 AssertValue (44, s ["i"]);
1346                 obj = s ["s"];
1347                 AssertValue ("T", obj);
1348                 AssertValue (45, s ["k"]);
1349
1350                 // vtypes as array entries
1351                 var arr = frame.GetArgument (1) as ArrayMirror;
1352                 obj = arr [0];
1353                 Assert.IsTrue (obj is StructMirror);
1354                 s = obj as StructMirror;
1355                 AssertValue (1, s ["i"]);
1356                 AssertValue ("S1", s ["s"]);
1357                 obj = arr [1];
1358                 Assert.IsTrue (obj is StructMirror);
1359                 s = obj as StructMirror;
1360                 AssertValue (2, s ["i"]);
1361                 AssertValue ("S2", s ["s"]);
1362
1363                 // Argument checking
1364                 s = frame.GetArgument (0) as StructMirror;
1365                 AssertThrows<ArgumentException> (delegate () {
1366                                 obj = s ["FOO"];
1367                         });
1368
1369                 // generic vtype instances
1370                 o = frame.GetThis () as ObjectMirror;
1371                 obj = o.GetValue (o.Type.GetField ("generic_field_struct"));
1372                 Assert.IsTrue (obj is StructMirror);
1373                 s = obj as StructMirror;
1374                 Assert.AreEqual ("GStruct`1", s.Type.Name);
1375                 AssertValue (42, s ["i"]);
1376
1377                 // this on vtype methods
1378                 e = run_until ("vtypes2");
1379                 e = step_until (e.Thread, "foo");
1380
1381                 frame = e.Thread.GetFrames () [0];
1382
1383                 Assert.AreEqual ("foo", (e as StepEvent).Method.Name);
1384                 obj = frame.GetThis ();
1385
1386                 Assert.IsTrue (obj is StructMirror);
1387                 s = obj as StructMirror;
1388                 AssertValue (44, s ["i"]);
1389                 AssertValue ("T", s ["s"]);
1390                 AssertValue (45, s ["k"]);
1391
1392                 // this on static vtype methods
1393                 e = run_until ("vtypes3");
1394                 e = step_until (e.Thread, "static_foo");
1395
1396                 frame = e.Thread.GetFrames () [0];
1397
1398                 Assert.AreEqual ("static_foo", (e as StepEvent).Method.Name);
1399                 obj = frame.GetThis ();
1400                 AssertValue (null, obj);
1401         }
1402
1403         [Test]
1404         public void AssemblyInfo () {
1405                 Event e = run_until ("single_stepping");
1406
1407                 StackFrame frame = e.Thread.GetFrames () [0];
1408
1409                 var aname = frame.Method.DeclaringType.Assembly.GetName ();
1410                 Assert.AreEqual ("dtest-app, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", aname.ToString ());
1411
1412                 ModuleMirror m = frame.Method.DeclaringType.Module;
1413
1414                 Assert.AreEqual ("dtest-app.exe", m.Name);
1415                 Assert.AreEqual ("dtest-app.exe", m.ScopeName);
1416                 Assert.IsTrue (m.FullyQualifiedName.IndexOf ("dtest-app.exe") != -1);
1417                 Guid guid = m.ModuleVersionId;
1418                 Assert.AreEqual (frame.Method.DeclaringType.Assembly, m.Assembly);
1419                 Assert.AreEqual (frame.Method.DeclaringType.Assembly.ManifestModule, m);
1420
1421                 // This is no longer true on 4.0
1422                 //Assert.AreEqual ("Assembly", frame.Method.DeclaringType.Assembly.GetAssemblyObject ().Type.Name);
1423
1424                 TypeMirror t = vm.RootDomain.Corlib.GetType ("System.Diagnostics.DebuggerDisplayAttribute");
1425                 Assert.AreEqual ("DebuggerDisplayAttribute", t.Name);
1426         }
1427
1428         [Test]
1429         public void LocalsInfo () {
1430                 Event e = run_until ("locals2");
1431
1432                 StackFrame frame = e.Thread.GetFrames () [0];
1433
1434                 var locals = frame.Method.GetLocals ();
1435                 Assert.AreEqual (7, locals.Length);
1436                 for (int i = 0; i < 7; ++i) {
1437                         if (locals [i].Name == "args") {
1438                                 Assert.IsTrue (locals [i].IsArg);
1439                                 Assert.AreEqual ("String[]", locals [i].Type.Name);
1440                         } else if (locals [i].Name == "arg") {
1441                                 Assert.IsTrue (locals [i].IsArg);
1442                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1443                         } else if (locals [i].Name == "i") {
1444                                 Assert.IsFalse (locals [i].IsArg);
1445                                 Assert.AreEqual ("Int64", locals [i].Type.Name);
1446                         } else if (locals [i].Name == "j") {
1447                                 Assert.IsFalse (locals [i].IsArg);
1448                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1449                         } else if (locals [i].Name == "s") {
1450                                 Assert.IsFalse (locals [i].IsArg);
1451                                 Assert.AreEqual ("String", locals [i].Type.Name);
1452                         } else if (locals [i].Name == "t") {
1453                                 // gshared
1454                                 Assert.IsTrue (locals [i].IsArg);
1455                                 Assert.AreEqual ("String", locals [i].Type.Name);
1456                         } else if (locals [i].Name == "rs") {
1457                                 Assert.IsTrue (locals [i].IsArg);
1458                                 Assert.AreEqual ("String", locals [i].Type.Name);
1459                         } else {
1460                                 Assert.Fail ();
1461                         }
1462                 }
1463         }
1464
1465         Event step_once () {
1466                 vm.Resume ();
1467                 var e = GetNextEvent ();
1468                 Assert.IsTrue (e is StepEvent);
1469                 return e;
1470         }
1471
1472         Event step_into () {
1473                 step_req.Disable ();
1474                 step_req.Depth = StepDepth.Into;
1475                 step_req.Enable ();
1476                 return step_once ();
1477         }
1478
1479         Event step_over () {
1480                 step_req.Disable ();
1481                 step_req.Depth = StepDepth.Over;
1482                 step_req.Enable ();
1483                 return step_once ();
1484         }
1485
1486         Event step_out () {
1487                 step_req.Disable ();
1488                 step_req.Depth = StepDepth.Out;
1489                 step_req.Enable ();
1490                 return step_once ();
1491         }
1492
1493         [Test]
1494         public void Locals () {
1495                 var be = run_until ("locals1");
1496
1497                 StackFrame frame = be.Thread.GetFrames () [0];
1498                 MethodMirror m1 = frame.Method;
1499
1500                 // Compiler generated byref local
1501                 foreach (var l in m1.GetLocals ()) {
1502                         // The byval flag is hidden from the type
1503                         if (l.Name != "ri" && l.Type.Name == "Double")
1504                                 AssertValue (null, frame.GetValue (l));
1505                 }
1506
1507                 be = run_until ("locals2");
1508
1509                 frame = be.Thread.GetFrames () [0];
1510
1511                 object val = frame.GetValue (frame.Method.GetLocal ("i"));
1512                 AssertValue (0, val);
1513
1514                 var req = create_step (be);
1515                 req.Enable ();
1516
1517                 // Skip nop
1518                 step_once ();
1519
1520                 // Execute i = 42
1521                 var e = step_once ();
1522                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1523
1524                 // Execute s = "AB";
1525                 e = step_once ();
1526                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1527
1528                 frame = e.Thread.GetFrames () [0];
1529
1530                 val = frame.GetValue (frame.Method.GetLocal ("i"));
1531                 AssertValue (42, val);
1532
1533                 LocalVariable[] locals = frame.Method.GetLocals ();
1534                 var vals = frame.GetValues (locals);
1535                 Assert.AreEqual (locals.Length, vals.Length);
1536                 for (int i = 0; i < locals.Length; ++i) {
1537                         if (locals [i].Name == "i")
1538                                 AssertValue (42, vals [i]);
1539                         if (locals [i].Name == "s")
1540                                 AssertValue ("AB", vals [i]);
1541                         if (locals [i].Name == "t")
1542                                 AssertValue ("ABC", vals [i]);
1543                 }
1544
1545                 // Argument checking
1546
1547                 // GetValue () null
1548                 AssertThrows<ArgumentNullException> (delegate () {
1549                                 frame.GetValue ((LocalVariable)null);
1550                         });
1551                 // GetValue () local from another method
1552                 AssertThrows<ArgumentException> (delegate () {
1553                                 frame.GetValue (m1.GetLocal ("foo"));
1554                         });
1555
1556                 // GetValue () null
1557                 AssertThrows<ArgumentNullException> (delegate () {
1558                                 frame.GetValue ((ParameterInfoMirror)null);
1559                         });
1560                 // GetValue () local from another method
1561                 AssertThrows<ArgumentException> (delegate () {
1562                                 frame.GetValue (m1.GetParameters ()[0]);
1563                         });
1564
1565                 // GetValues () null
1566                 AssertThrows<ArgumentNullException> (delegate () {
1567                                 frame.GetValues (null);
1568                         });
1569                 // GetValues () embedded null
1570                 AssertThrows<ArgumentNullException> (delegate () {
1571                                 frame.GetValues (new LocalVariable [] { null });
1572                         });
1573                 // GetValues () local from another method
1574                 AssertThrows<ArgumentException> (delegate () {
1575                                 frame.GetValues (new LocalVariable [] { m1.GetLocal ("foo") });
1576                         });
1577                 // return value
1578                 AssertThrows<ArgumentException> (delegate () {
1579                                 val = frame.GetValue (frame.Method.ReturnParameter);
1580                         });
1581
1582                 // invalid stack frames
1583                 vm.Resume ();
1584                 e = GetNextEvent ();
1585                 Assert.IsTrue (e is StepEvent);
1586                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1587
1588                 AssertThrows<InvalidStackFrameException> (delegate () {
1589                                 frame.GetValue (frame.Method.GetLocal ("i"));
1590                         });
1591
1592                 req.Disable ();
1593
1594                 // gsharedvt
1595                 be = run_until ("locals7");
1596
1597                 req = create_step (be);
1598                 req.Enable ();
1599
1600                 // Skip nop
1601                 e = step_once ();
1602
1603                 // Test that locals are initialized
1604                 frame = e.Thread.GetFrames () [0];
1605                 val = frame.GetValue (frame.Method.GetLocal ("t"));
1606                 AssertValue (0, val);
1607
1608                 // Execute t = arg
1609                 e = step_once ();
1610                 Assert.AreEqual ("locals7", (e as StepEvent).Method.Name);
1611
1612                 // Execute t2 = t
1613                 e = step_once ();
1614                 Assert.AreEqual ("locals7", (e as StepEvent).Method.Name);
1615
1616                 frame = e.Thread.GetFrames () [0];
1617                 val = frame.GetValue (frame.Method.GetParameters ()[0]);
1618                 AssertValue (22, val);
1619                 val = frame.GetValue (frame.Method.GetLocal ("t"));
1620                 AssertValue (22, val);
1621                 val = frame.GetValue (frame.Method.GetLocal ("t2"));
1622                 AssertValue (22, val);
1623         }
1624
1625         [Test]
1626         public void GetVisibleVariables () {
1627                 Event e = run_until ("locals4");
1628
1629                 // First scope
1630                 var locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1631                 Assert.AreEqual (2, locals.Count);
1632                 var loc = locals.First (l => l.Name == "i");
1633                 Assert.AreEqual ("Int64", loc.Type.Name);
1634                 loc = locals.First (l => l.Name == "s");
1635                 Assert.AreEqual ("String", loc.Type.Name);
1636
1637                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1638                 Assert.AreEqual ("i", loc.Name);
1639                 Assert.AreEqual ("Int64", loc.Type.Name);
1640
1641                 e = run_until ("locals5");
1642
1643                 // Second scope
1644                 locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1645                 Assert.AreEqual (2, locals.Count);
1646                 loc = locals.First (l => l.Name == "i");
1647                 Assert.AreEqual ("String", loc.Type.Name);
1648                 loc = locals.First (l => l.Name == "s");
1649                 Assert.AreEqual ("String", loc.Type.Name);
1650
1651                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1652                 Assert.AreEqual ("i", loc.Name);
1653                 Assert.AreEqual ("String", loc.Type.Name);
1654
1655                 // Variable in another scope
1656                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("j");
1657                 Assert.IsNull (loc);
1658         }
1659
1660         [Test]
1661         public void Exit () {
1662                 run_until ("Main");
1663
1664                 vm.Exit (5);
1665
1666                 var e = GetNextEvent ();
1667                 Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
1668
1669                 var p = vm.Process;
1670                 /* Could be a remote vm with no process */
1671                 if (p != null) {
1672                         p.WaitForExit ();
1673                         Assert.AreEqual (5, p.ExitCode);
1674
1675                         // error handling
1676                         AssertThrows<VMDisconnectedException> (delegate () {
1677                                         vm.Resume ();
1678                                 });
1679                 }
1680
1681                 vm = null;
1682         }
1683
1684         [Test]
1685         public void Dispose () {
1686                 run_until ("Main");
1687
1688                 vm.Detach ();
1689
1690                 var e = GetNextEvent ();
1691                 Assert.IsInstanceOfType (typeof (VMDisconnectEvent), e);
1692
1693                 var p = vm.Process;
1694                 /* Could be a remote vm with no process */
1695                 if (p != null) {
1696                         p.WaitForExit ();
1697                         Assert.AreEqual (3, p.ExitCode);
1698
1699                         // error handling
1700                         AssertThrows<VMDisconnectedException> (delegate () {
1701                                         vm.Resume ();
1702                                 });
1703                 }
1704
1705                 vm = null;
1706         }
1707
1708         [Test]
1709         public void ColumnNumbers () {
1710                 Event e = run_until ("line_numbers");
1711
1712                 // FIXME: Merge this with LineNumbers () when its fixed
1713
1714                 step_req = create_step (e);
1715                 step_req.Depth = StepDepth.Into;
1716                 step_req.Enable ();
1717
1718                 Location l;
1719                 
1720                 while (true) {
1721                         vm.Resume ();
1722
1723                         e = GetNextEvent ();
1724                         Assert.IsTrue (e is StepEvent);
1725                         if (e.Thread.GetFrames ()[0].Method.Name == "ln1")
1726                                 break;
1727                 }
1728
1729                 // Do an additional step over so we are not on the beginning line of the method
1730                 step_req.Disable ();
1731                 step_req.Depth = StepDepth.Over;
1732                 step_req.Enable ();
1733                 vm.Resume ();
1734                 e = GetNextEvent ();
1735                 Assert.IsTrue (e is StepEvent);         
1736
1737                 l = e.Thread.GetFrames ()[0].Location;
1738
1739                 Assert.AreEqual (3, l.ColumnNumber);
1740
1741                 step_req.Disable ();
1742         }
1743
1744         [Test]
1745         // Broken by mcs+runtime changes (#5438)
1746         [Category("NotWorking")]
1747         public void LineNumbers () {
1748                 Event e = run_until ("line_numbers");
1749
1750                 step_req = create_step (e);
1751                 step_req.Depth = StepDepth.Into;
1752                 step_req.Enable ();
1753
1754                 Location l;
1755                 
1756                 vm.Resume ();
1757
1758                 e = GetNextEvent ();
1759                 Assert.IsTrue (e is StepEvent);
1760
1761                 l = e.Thread.GetFrames ()[0].Location;
1762
1763                 Assert.IsTrue (l.SourceFile.IndexOf ("dtest-app.cs") != -1);
1764                 Assert.AreEqual ("ln1", l.Method.Name);
1765
1766                 // Check hash
1767                 using (FileStream fs = new FileStream (l.SourceFile, FileMode.Open, FileAccess.Read)) {
1768                         MD5 md5 = MD5.Create ();
1769                         var hash = md5.ComputeHash (fs);
1770
1771                         for (int i = 0; i < 16; ++i)
1772                                 Assert.AreEqual (hash [i], l.SourceFileHash [i]);
1773                 }
1774                 
1775                 int line_base = l.LineNumber;
1776
1777                 vm.Resume ();
1778                 e = GetNextEvent ();
1779                 Assert.IsTrue (e is StepEvent);
1780                 l = e.Thread.GetFrames ()[0].Location;
1781                 Assert.AreEqual ("ln2", l.Method.Name);
1782                 Assert.AreEqual (line_base + 6, l.LineNumber);
1783
1784                 vm.Resume ();
1785                 e = GetNextEvent ();
1786                 Assert.IsTrue (e is StepEvent);
1787                 l = e.Thread.GetFrames ()[0].Location;
1788                 Assert.AreEqual ("ln1", l.Method.Name);
1789                 Assert.AreEqual (line_base + 1, l.LineNumber);
1790
1791                 vm.Resume ();
1792                 e = GetNextEvent ();
1793                 Assert.IsTrue (e is StepEvent);
1794                 l = e.Thread.GetFrames ()[0].Location;
1795                 Assert.AreEqual ("ln3", l.Method.Name);
1796                 Assert.AreEqual (line_base + 11, l.LineNumber);
1797
1798                 vm.Resume ();
1799                 e = GetNextEvent ();
1800                 Assert.IsTrue (e is StepEvent);
1801                 l = e.Thread.GetFrames ()[0].Location;
1802                 Assert.AreEqual ("ln3", l.Method.Name);
1803                 Assert.IsTrue (l.SourceFile.EndsWith ("FOO"));
1804                 Assert.AreEqual (55, l.LineNumber);
1805
1806                 vm.Resume ();
1807                 e = GetNextEvent ();
1808                 Assert.IsTrue (e is StepEvent);
1809                 l = e.Thread.GetFrames ()[0].Location;
1810                 Assert.AreEqual ("ln1", l.Method.Name);
1811                 Assert.AreEqual (line_base + 2, l.LineNumber);
1812
1813                 // GetSourceFiles ()
1814                 string[] sources = l.Method.DeclaringType.GetSourceFiles ();
1815                 Assert.AreEqual (2, sources.Length);
1816                 Assert.AreEqual ("dtest-app.cs", sources [0]);
1817                 Assert.AreEqual ("FOO", sources [1]);
1818
1819                 sources = l.Method.DeclaringType.GetSourceFiles (true);
1820                 Assert.AreEqual (2, sources.Length);
1821                 Assert.IsTrue (sources [0].EndsWith ("dtest-app.cs"));
1822                 Assert.IsTrue (sources [1].EndsWith ("FOO"));
1823         }
1824
1825         [Test]
1826         public void Suspend () {
1827                 vm.Detach ();
1828
1829                 Start (new string [] { "dtest-app.exe", "suspend-test" });
1830
1831                 Event e = run_until ("suspend");
1832
1833                 ThreadMirror main = e.Thread;
1834
1835                 vm.Resume ();
1836
1837                 Thread.Sleep (100);
1838
1839                 vm.Suspend ();
1840
1841                 // The debuggee should be suspended while it is running the infinite loop
1842                 // in suspend ()
1843                 StackFrame frame = main.GetFrames ()[0];
1844                 Assert.AreEqual ("suspend", frame.Method.Name);
1845
1846                 vm.Resume ();
1847
1848                 // resuming when not suspended
1849                 AssertThrows<InvalidOperationException> (delegate () {
1850                                 vm.Resume ();
1851                         });
1852
1853                 vm.Exit (0);
1854
1855                 vm = null;
1856         }
1857
1858         [Test]
1859         public void AssemblyLoad () {
1860                 Event e = run_until ("assembly_load");
1861
1862                 var load_req = vm.CreateAssemblyLoadRequest ();
1863                 load_req.Enable ();
1864
1865                 vm.Resume ();
1866
1867                 e = GetNextEvent ();
1868                 Assert.IsInstanceOfType (typeof (AssemblyLoadEvent), e);
1869                 Assert.IsTrue ((e as AssemblyLoadEvent).Assembly.Location.EndsWith ("System.dll"));
1870
1871                 var frames = e.Thread.GetFrames ();
1872                 Assert.IsTrue (frames.Length > 0);
1873                 Assert.AreEqual ("assembly_load", frames [0].Method.Name);
1874         }
1875
1876         [Test]
1877         public void CreateValue () {
1878                 PrimitiveValue v;
1879
1880                 v = vm.CreateValue (1);
1881                 Assert.AreEqual (vm, v.VirtualMachine);
1882                 Assert.AreEqual (1, v.Value);
1883
1884                 v = vm.CreateValue (null);
1885                 Assert.AreEqual (vm, v.VirtualMachine);
1886                 Assert.AreEqual (null, v.Value);
1887
1888                 // Argument checking
1889                 AssertThrows <ArgumentException> (delegate () {
1890                                 v = vm.CreateValue ("FOO");
1891                         });
1892         }
1893
1894         [Test]
1895         public void CreateString () {
1896                 StringMirror s = vm.RootDomain.CreateString ("ABC");
1897
1898                 Assert.AreEqual (vm, s.VirtualMachine);
1899                 Assert.AreEqual ("ABC", s.Value);
1900                 Assert.AreEqual (vm.RootDomain, s.Domain);
1901
1902                 // Long strings
1903                 StringBuilder sb = new StringBuilder ();
1904                 for (int i = 0; i < 1024; ++i)
1905                         sb.Append ('A');
1906                 s = vm.RootDomain.CreateString (sb.ToString ());
1907
1908                 // Argument checking
1909                 AssertThrows <ArgumentNullException> (delegate () {
1910                                 s = vm.RootDomain.CreateString (null);
1911                         });
1912         }
1913
1914         [Test]
1915         public void CreateBoxedValue () {
1916                 ObjectMirror o = vm.RootDomain.CreateBoxedValue (new PrimitiveValue (vm, 42));
1917
1918                 Assert.AreEqual ("Int32", o.Type.Name);
1919                 //AssertValue (42, m.GetValue (o.Type.GetField ("m_value")));
1920
1921                 // Argument checking
1922                 AssertThrows <ArgumentNullException> (delegate () {
1923                                 vm.RootDomain.CreateBoxedValue (null);
1924                         });
1925
1926                 AssertThrows <ArgumentException> (delegate () {
1927                                 vm.RootDomain.CreateBoxedValue (o);
1928                         });
1929         }
1930
1931         [Test]
1932         public void Invoke () {
1933                 Event e = run_until ("invoke1");
1934
1935                 StackFrame frame = e.Thread.GetFrames () [0];
1936
1937                 TypeMirror t = frame.Method.DeclaringType;
1938                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
1939
1940                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
1941
1942                 MethodMirror m;
1943                 Value v;
1944
1945                 // return void
1946                 m = t.GetMethod ("invoke_return_void");
1947                 v = this_obj.InvokeMethod (e.Thread, m, null);
1948                 Assert.IsNull (v);
1949
1950                 // return ref
1951                 m = t.GetMethod ("invoke_return_ref");
1952                 v = this_obj.InvokeMethod (e.Thread, m, null);
1953                 AssertValue ("ABC", v);
1954
1955                 // return null
1956                 m = t.GetMethod ("invoke_return_null");
1957                 v = this_obj.InvokeMethod (e.Thread, m, null);
1958                 AssertValue (null, v);
1959
1960                 // return primitive
1961                 m = t.GetMethod ("invoke_return_primitive");
1962                 v = this_obj.InvokeMethod (e.Thread, m, null);
1963                 AssertValue (42, v);
1964
1965                 // return nullable
1966                 m = t.GetMethod ("invoke_return_nullable");
1967                 v = this_obj.InvokeMethod (e.Thread, m, null);
1968                 Assert.IsInstanceOfType (typeof (StructMirror), v);
1969                 var s = v as StructMirror;
1970                 AssertValue (42, s.Fields [0]);
1971                 AssertValue (true, s.Fields [1]);
1972
1973                 // pass nullable as this
1974                 //m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
1975                 m = s.Type.GetMethod ("ToString");
1976                 v = s.InvokeMethod (e.Thread, m, null);
1977
1978                 // return nullable null
1979                 m = t.GetMethod ("invoke_return_nullable_null");
1980                 v = this_obj.InvokeMethod (e.Thread, m, null);
1981                 Assert.IsInstanceOfType (typeof (StructMirror), v);
1982                 s = v as StructMirror;
1983                 AssertValue (0, s.Fields [0]);
1984                 AssertValue (false, s.Fields [1]);
1985
1986                 // pass nullable as this
1987                 //m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
1988                 m = s.Type.GetMethod ("ToString");
1989                 v = s.InvokeMethod (e.Thread, m, null);
1990
1991                 // pass primitive
1992                 m = t.GetMethod ("invoke_pass_primitive");
1993                 Value[] args = new Value [] {
1994                         vm.CreateValue ((byte)Byte.MaxValue),
1995                         vm.CreateValue ((sbyte)SByte.MaxValue),
1996                         vm.CreateValue ((short)1),
1997                         vm.CreateValue ((ushort)1),
1998                         vm.CreateValue ((int)1),
1999                         vm.CreateValue ((uint)1),
2000                         vm.CreateValue ((long)1),
2001                         vm.CreateValue ((ulong)1),
2002                         vm.CreateValue ('A'),
2003                         vm.CreateValue (true),
2004                         vm.CreateValue (3.14f),
2005                         vm.CreateValue (3.14) };
2006
2007                 v = this_obj.InvokeMethod (e.Thread, m, args);
2008                 AssertValue ((int)Byte.MaxValue + (int)SByte.MaxValue + 1 + 1 + 1 + 1 + 1 + 1 + 'A' + 1 + 3 + 3, v);
2009
2010                 // pass ref
2011                 m = t.GetMethod ("invoke_pass_ref");
2012                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2013                 AssertValue ("ABC", v);
2014
2015                 // pass null
2016                 m = t.GetMethod ("invoke_pass_ref");
2017                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (null) });
2018                 AssertValue (null, v);
2019
2020                 // static
2021                 m = t.GetMethod ("invoke_static_pass_ref");
2022                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2023                 AssertValue ("ABC", v);
2024
2025                 // static invoked using ObjectMirror.InvokeMethod
2026                 m = t.GetMethod ("invoke_static_pass_ref");
2027                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2028                 AssertValue ("ABC", v);
2029
2030                 // method which throws an exception
2031                 try {
2032                         m = t.GetMethod ("invoke_throws");
2033                         v = this_obj.InvokeMethod (e.Thread, m, null);
2034                         Assert.Fail ();
2035                 } catch (InvocationException ex) {
2036                         Assert.AreEqual ("Exception", ex.Exception.Type.Name);
2037                 }
2038
2039                 // newobj
2040                 m = t.GetMethod (".ctor");
2041                 v = t.InvokeMethod (e.Thread, m, null);
2042                 Assert.IsInstanceOfType (typeof (ObjectMirror), v);
2043                 Assert.AreEqual ("Tests", (v as ObjectMirror).Type.Name);
2044
2045                 // interface method
2046                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("ITest2");
2047                 m = cl1.GetMethod ("invoke_iface");
2048                 v = this_obj.InvokeMethod (e.Thread, m, null);
2049                 AssertValue (42, v);
2050
2051                 // Argument checking
2052                 
2053                 // null thread
2054                 AssertThrows<ArgumentNullException> (delegate {
2055                                 m = t.GetMethod ("invoke_pass_ref");
2056                                 v = this_obj.InvokeMethod (null, m, new Value [] { vm.CreateValue (null) });                            
2057                         });
2058
2059                 // null method
2060                 AssertThrows<ArgumentNullException> (delegate {
2061                                 v = this_obj.InvokeMethod (e.Thread, null, new Value [] { vm.CreateValue (null) });                             
2062                         });
2063
2064                 // invalid number of arguments
2065                 m = t.GetMethod ("invoke_pass_ref");
2066                 AssertThrows<ArgumentException> (delegate {
2067                                 v = this_obj.InvokeMethod (e.Thread, m, null);
2068                         });
2069
2070                 // invalid type of argument (ref != primitive)
2071                 m = t.GetMethod ("invoke_pass_ref");
2072                 AssertThrows<ArgumentException> (delegate {
2073                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2074                         });
2075
2076                 // invalid type of argument (primitive != primitive)
2077                 m = t.GetMethod ("invoke_pass_primitive_2");
2078                 AssertThrows<ArgumentException> (delegate {
2079                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2080                         });
2081
2082                 // invoking a non-static method as static
2083                 m = t.GetMethod ("invoke_pass_ref");
2084                 AssertThrows<ArgumentException> (delegate {
2085                                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2086                         });
2087
2088                 // invoking a method defined in another class
2089                 m = t2.GetMethod ("invoke");
2090                 AssertThrows<ArgumentException> (delegate {
2091                                 v = this_obj.InvokeMethod (e.Thread, m, null);
2092                         });
2093         }
2094
2095         [Test]
2096         public void InvokeVType () {
2097                 Event e = run_until ("invoke1");
2098
2099                 StackFrame frame = e.Thread.GetFrames () [0];
2100
2101                 var s = frame.GetArgument (1) as StructMirror;
2102
2103                 TypeMirror t = s.Type;
2104
2105                 MethodMirror m;
2106                 Value v;
2107
2108                 // Pass struct as this, receive int
2109                 m = t.GetMethod ("invoke_return_int");
2110                 v = s.InvokeMethod (e.Thread, m, null);
2111                 AssertValue (42, v);
2112
2113                 // Pass struct as this, receive intptr
2114                 m = t.GetMethod ("invoke_return_intptr");
2115                 v = s.InvokeMethod (e.Thread, m, null);
2116                 AssertValue (43, v);
2117
2118                 // Static method
2119                 m = t.GetMethod ("invoke_static");
2120                 v = t.InvokeMethod (e.Thread, m, null);
2121                 AssertValue (5, v);
2122
2123                 // Pass generic struct as this
2124                 s = frame.GetArgument (2) as StructMirror;
2125                 t = s.Type;
2126                 m = t.GetMethod ("invoke_return_int");
2127                 v = s.InvokeMethod (e.Thread, m, null);
2128                 AssertValue (42, v);
2129         }
2130
2131         [Test]
2132         public void BreakpointDuringInvoke () {
2133                 Event e = run_until ("invoke1");
2134
2135                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
2136                 Assert.IsNotNull (m);
2137                 vm.SetBreakpoint (m, 0);
2138
2139                 StackFrame frame = e.Thread.GetFrames () [0];
2140                 var o = frame.GetThis () as ObjectMirror;
2141
2142                 bool failed = false;
2143
2144                 bool finished = false;
2145                 object wait = new object ();
2146
2147                 // Have to invoke in a separate thread as the invoke is suspended until we
2148                 // resume after the breakpoint
2149                 Thread t = new Thread (delegate () {
2150                                 try {
2151                                         o.InvokeMethod (e.Thread, m, null);
2152                                 } catch {
2153                                         failed = true;
2154                                 }
2155                                 lock (wait) {
2156                                         finished = true;
2157                                         Monitor.Pulse (wait);
2158                                 }
2159                         });
2160
2161                 t.Start ();
2162
2163                 StackFrame invoke_frame = null;
2164
2165                 try {
2166                         e = GetNextEvent ();
2167                         Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
2168                         // Check stack trace support and invokes
2169                         var frames = e.Thread.GetFrames ();
2170                         invoke_frame = frames [0];
2171                         Assert.AreEqual ("invoke2", frames [0].Method.Name);
2172                         Assert.IsTrue (frames [0].IsDebuggerInvoke);
2173                         Assert.AreEqual ("invoke1", frames [1].Method.Name);
2174                 } finally {
2175                         vm.Resume ();
2176                 }
2177
2178                 lock (wait) {
2179                         if (!finished)
2180                                 Monitor.Wait (wait);
2181                 }
2182
2183                 // Check that the invoke frames are no longer valid
2184                 AssertThrows<InvalidStackFrameException> (delegate {
2185                                 invoke_frame.GetThis ();
2186                         });
2187
2188                 // Check InvokeOptions.DisableBreakpoints flag
2189                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2190         }
2191
2192         [Test]
2193         public void DisabledExceptionDuringInvoke () {
2194                 Event e = run_until ("invoke_ex");
2195
2196                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_ex_inner");
2197
2198                 StackFrame frame = e.Thread.GetFrames () [0];
2199                 var o = frame.GetThis () as ObjectMirror;
2200
2201                 var req = vm.CreateExceptionRequest (null);
2202                 req.Enable ();
2203
2204                 // Check InvokeOptions.DisableBreakpoints flag
2205                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2206
2207                 req.Disable ();
2208         }
2209
2210         [Test]
2211         public void InvokeSingleThreaded () {
2212                 vm.Detach ();
2213
2214                 Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
2215
2216                 Event e = run_until ("invoke_single_threaded_2");
2217
2218                 StackFrame f = e.Thread.GetFrames ()[0];
2219
2220                 var obj = f.GetThis () as ObjectMirror;
2221
2222                 // Check that the counter value incremented by the other thread does not increase
2223                 // during the invoke.
2224                 object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2225
2226                 var m = obj.Type.GetMethod ("invoke_return_void");
2227                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2228
2229             object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2230
2231                 Assert.AreEqual ((int)counter1, (int)counter2);
2232
2233                 // Test multiple invokes done in succession
2234                 m = obj.Type.GetMethod ("invoke_return_void");
2235                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2236
2237                 // Test events during single-threaded invokes
2238                 vm.EnableEvents (EventType.TypeLoad);
2239                 m = obj.Type.GetMethod ("invoke_type_load");
2240                 obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
2241                                 vm.Resume ();
2242                         }, null);
2243
2244                 e = GetNextEvent ();
2245                 Assert.AreEqual (EventType.TypeLoad, e.EventType);
2246         }
2247
2248         List<Value> invoke_results;
2249
2250         [Test]
2251         public void InvokeMultiple () {
2252                 Event e = run_until ("invoke1");
2253
2254                 StackFrame frame = e.Thread.GetFrames () [0];
2255
2256                 TypeMirror t = frame.Method.DeclaringType;
2257                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2258
2259                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2260
2261                 var methods = new MethodMirror [2];
2262                 methods [0] = t.GetMethod ("invoke_return_ref");
2263                 methods [1] = t.GetMethod ("invoke_return_primitive");
2264
2265                 invoke_results = new List<Value> ();
2266
2267                 var r = this_obj.BeginInvokeMultiple (e.Thread, methods, null, InvokeOptions.SingleThreaded, invoke_multiple_cb, this_obj);
2268                 WaitHandle.WaitAll (new WaitHandle[] { r.AsyncWaitHandle });
2269                 this_obj.EndInvokeMultiple (r);
2270                 // The callback might still be running
2271                 while (invoke_results.Count < 2) {
2272                         Thread.Sleep (100);
2273                 }
2274                 if (invoke_results [0] is PrimitiveValue) {
2275                         AssertValue ("ABC", invoke_results [1]);
2276                         AssertValue (42, invoke_results [0]);
2277                 } else {
2278                         AssertValue ("ABC", invoke_results [0]);
2279                         AssertValue (42, invoke_results [1]);
2280                 }
2281         }
2282
2283         void invoke_multiple_cb (IAsyncResult ar) {
2284                 ObjectMirror this_obj = (ObjectMirror)ar.AsyncState;
2285
2286                 var res = this_obj.EndInvokeMethod (ar);
2287                 lock (invoke_results)
2288                         invoke_results.Add (res);
2289         }
2290
2291         [Test]
2292         public void GetThreads () {
2293                 vm.GetThreads ();
2294         }
2295
2296         [Test]
2297         public void Threads () {
2298                 Event e = run_until ("threads");
2299
2300                 Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
2301
2302                 Assert.IsTrue (e.Thread.ThreadId > 0);
2303
2304                 Assert.AreEqual (e.Thread.TID, e.Thread.TID);
2305
2306                 vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
2307
2308                 vm.Resume ();
2309
2310                 e = GetNextEvent ();
2311                 Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
2312                 var state = e.Thread.ThreadState;
2313                 Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
2314
2315                 vm.Resume ();
2316
2317                 e = GetNextEvent ();
2318                 Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
2319                 Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
2320         }
2321
2322         [Test]
2323         public void Frame_SetValue () {
2324                 Event e = run_until ("locals2");
2325
2326                 StackFrame frame = e.Thread.GetFrames () [0];
2327
2328                 // primitive
2329                 var l = frame.Method.GetLocal ("i");
2330                 frame.SetValue (l, vm.CreateValue ((long)55));
2331                 AssertValue (55, frame.GetValue (l));
2332
2333                 // reference
2334                 l = frame.Method.GetLocal ("s");
2335                 frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
2336                 AssertValue ("DEF", frame.GetValue (l));
2337
2338                 // argument as local
2339                 l = frame.Method.GetLocal ("arg");
2340                 frame.SetValue (l, vm.CreateValue (6));
2341                 AssertValue (6, frame.GetValue (l));
2342
2343                 // argument
2344                 var p = frame.Method.GetParameters ()[1];
2345                 frame.SetValue (p, vm.CreateValue (7));
2346                 AssertValue (7, frame.GetValue (p));
2347
2348                 // gshared
2349                 p = frame.Method.GetParameters ()[2];
2350                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF"));
2351                 AssertValue ("DEF", frame.GetValue (p));
2352
2353                 // byref
2354                 p = frame.Method.GetParameters ()[3];
2355                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF2"));
2356                 AssertValue ("DEF2", frame.GetValue (p));
2357
2358                 // argument checking
2359
2360                 // variable null
2361                 AssertThrows<ArgumentNullException> (delegate () {
2362                                 frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
2363                         });
2364
2365                 // value null
2366                 AssertThrows<ArgumentNullException> (delegate () {
2367                                 l = frame.Method.GetLocal ("i");
2368                                 frame.SetValue (l, null);
2369                         });
2370
2371                 // value of invalid type
2372                 AssertThrows<ArgumentException> (delegate () {
2373                                 l = frame.Method.GetLocal ("i");
2374                                 frame.SetValue (l, vm.CreateValue (55));
2375                         });
2376         }
2377
2378         [Test]
2379         [Category ("only")]
2380         public void Frame_SetValue_Registers () {
2381                 Event e = run_until ("locals6_1");
2382
2383                 StackFrame frame = e.Thread.GetFrames () [1];
2384
2385                 // Set 'j' to 99
2386                 var l = frame.Method.GetLocal ("j");
2387                 frame.SetValue (l, vm.CreateValue (99));
2388                 AssertValue (99, frame.GetValue (l));
2389
2390                 // Check it during execution
2391                 e = run_until ("locals6_2");
2392                 frame = e.Thread.GetFrames () [0];
2393                 AssertValue (99, frame.GetValue (frame.Method.GetParameters ()[0]));
2394
2395                 // Set it while in a frame which clobbers its register
2396                 e = run_until ("locals6_3");
2397                 frame = e.Thread.GetFrames () [1];
2398                 frame.SetValue (l, vm.CreateValue (100));
2399                 AssertValue (100, frame.GetValue (l));
2400
2401                 // Check it during execution
2402                 e = run_until ("locals6_4");
2403                 frame = e.Thread.GetFrames () [0];
2404                 AssertValue (100, frame.GetValue (frame.Method.GetParameters ()[0]));
2405
2406                 // Signed byte value
2407                 e = run_until ("locals6_5");
2408                 frame = e.Thread.GetFrames () [1];
2409                 var l2 = frame.Method.GetLocal ("sb");
2410                 frame.SetValue (l2, vm.CreateValue ((sbyte)-99));
2411                 AssertValue (-99, frame.GetValue (l2));
2412
2413                 // Check it during execution
2414                 e = run_until ("locals6_6");
2415                 frame = e.Thread.GetFrames () [0];
2416                 AssertValue (-99, frame.GetValue (frame.Method.GetParameters ()[0]));
2417         }
2418
2419         [Test]
2420         public void InvokeRegress () {
2421                 Event e = run_until ("invoke1");
2422
2423                 StackFrame frame = e.Thread.GetFrames () [0];
2424
2425                 TypeMirror t = frame.Method.DeclaringType;
2426                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2427
2428                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2429
2430                 MethodMirror m;
2431                 Value v;
2432
2433                 // do an invoke
2434                 m = t.GetMethod ("invoke_return_void");
2435                 v = this_obj.InvokeMethod (e.Thread, m, null);
2436                 Assert.IsNull (v);
2437
2438                 // Check that the stack frames remain valid during the invoke
2439                 Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
2440
2441                 // do another invoke
2442                 m = t.GetMethod ("invoke_return_void");
2443                 v = this_obj.InvokeMethod (e.Thread, m, null);
2444                 Assert.IsNull (v);
2445
2446                 // Try a single step after the invoke
2447                 var req = create_step (e);
2448                 req.Depth = StepDepth.Into;
2449                 req.Size = StepSize.Line;
2450                 req.Enable ();
2451
2452                 // Skip nop
2453                 step_once ();
2454
2455                 // Step into invoke2
2456                 vm.Resume ();
2457                 e = GetNextEvent ();
2458                 Assert.IsTrue (e is StepEvent);
2459                 Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
2460
2461                 req.Disable ();
2462
2463                 frame = e.Thread.GetFrames () [0];
2464         }
2465
2466         [Test]
2467         public void Exceptions () {
2468                 Event e = run_until ("exceptions");
2469                 var req = vm.CreateExceptionRequest (null);
2470                 req.Enable ();
2471
2472                 vm.Resume ();
2473
2474                 e = GetNextEvent ();
2475                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2476                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2477
2478                 var frames = e.Thread.GetFrames ();
2479                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2480                 req.Disable ();
2481
2482                 // exception type filter
2483
2484                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
2485                 req.Enable ();
2486
2487                 // Skip the throwing of the second OverflowException       
2488                 vm.Resume ();
2489
2490                 e = GetNextEvent ();
2491                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2492                 Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
2493                 req.Disable ();
2494
2495                 // exception type filter for subclasses
2496                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
2497                 req.Enable ();
2498
2499                 vm.Resume ();
2500
2501                 e = GetNextEvent ();
2502                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2503                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2504                 req.Disable ();
2505
2506                 // Implicit exceptions
2507                 req = vm.CreateExceptionRequest (null);
2508                 req.Enable ();
2509
2510                 vm.Resume ();
2511
2512                 e = GetNextEvent ();
2513                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2514                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2515                 req.Disable ();
2516
2517                 // Single stepping after an exception
2518                 req = vm.CreateExceptionRequest (null);
2519                 req.Enable ();
2520
2521                 vm.Resume ();
2522
2523                 e = GetNextEvent ();
2524                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2525                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
2526                 frames = e.Thread.GetFrames ();
2527                 Assert.AreEqual ("exceptions2", frames [0].Method.Name);
2528                 req.Disable ();
2529
2530                 var sreq = create_step (e);
2531                 sreq.Depth = StepDepth.Over;
2532                 sreq.Size = StepSize.Line;
2533                 sreq.Enable ();
2534
2535                 vm.Resume ();
2536                 e = GetNextEvent ();
2537                 Assert.IsInstanceOfType (typeof (StepEvent), e);
2538                 frames = e.Thread.GetFrames ();
2539                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2540                 sreq.Disable ();
2541
2542                 // Argument checking
2543                 AssertThrows<ArgumentException> (delegate {
2544                                 vm.CreateExceptionRequest (e.Thread.Type);
2545                         });
2546         }
2547
2548         [Test]
2549         public void ExceptionFilter () {
2550                 Event e = run_until ("exception_filter");
2551
2552                 MethodMirror m = entry_point.DeclaringType.GetMethod ("exception_filter_filter");
2553                 Assert.IsNotNull (m);
2554
2555                 vm.SetBreakpoint (m, 0);
2556
2557                 vm.Resume ();
2558
2559                 e = GetNextEvent ();
2560                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
2561                 Assert.IsTrue (e is BreakpointEvent);
2562                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
2563
2564                 var frames = e.Thread.GetFrames ();
2565
2566                 Assert.IsTrue (frames [0].Location.SourceFile.IndexOf ("dtest-app.cs") != -1);
2567                 Assert.AreEqual ("exception_filter_filter", frames [0].Location.Method.Name);
2568
2569                 Assert.AreEqual (0, frames [1].Location.Method.MetadataToken);
2570                 Assert.AreEqual (0x0f, frames [1].Location.ILOffset);
2571
2572                 Assert.AreEqual ("exception_filter_method", frames [2].Location.Method.Name);
2573                 Assert.AreEqual (0x06, frames [2].Location.ILOffset);
2574
2575                 Assert.AreEqual (0, frames [3].Location.Method.MetadataToken, 0);
2576                 Assert.AreEqual (0, frames [3].Location.ILOffset);
2577
2578                 Assert.AreEqual ("exception_filter", frames [4].Location.Method.Name);
2579         }
2580
2581         [Test]
2582         public void ExceptionFilter2 () {
2583                 vm.Detach ();
2584
2585                 Start (new string [] { "dtest-excfilter.exe" });
2586
2587                 MethodMirror filter_method = entry_point.DeclaringType.GetMethod ("Filter");
2588                 Assert.IsNotNull (filter_method);
2589
2590                 MethodMirror test_method = entry_point.DeclaringType.GetMethod ("Test");
2591                 Assert.IsNotNull (test_method);
2592
2593                 vm.SetBreakpoint (filter_method, 0);
2594
2595                 vm.Resume ();
2596
2597                 var e = GetNextEvent ();
2598                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
2599                 Assert.IsTrue (e is BreakpointEvent);
2600                 Assert.AreEqual (filter_method.Name, (e as BreakpointEvent).Method.Name);
2601
2602                 var frames = e.Thread.GetFrames ();
2603
2604                 Assert.AreEqual (4, frames.Count ());
2605
2606                 Assert.AreEqual (filter_method.Name, frames [0].Location.Method.Name);
2607                 Assert.AreEqual (20, frames [0].Location.LineNumber);
2608                 Assert.AreEqual (0, frames [0].Location.ILOffset);
2609
2610                 Assert.AreEqual (test_method.Name, frames [1].Location.Method.Name);
2611                 Assert.AreEqual (37, frames [1].Location.LineNumber);
2612                 Assert.AreEqual (0x0b, frames [1].Location.ILOffset);
2613
2614                 Assert.AreEqual (test_method.Name, frames [2].Location.Method.Name);
2615                 Assert.AreEqual (33, frames [2].Location.LineNumber);
2616                 Assert.AreEqual (0x05, frames [2].Location.ILOffset);
2617
2618                 Assert.AreEqual (entry_point.Name, frames [3].Location.Method.Name);
2619                 Assert.AreEqual (14, frames [3].Location.LineNumber);
2620                 Assert.AreEqual (0x00, frames [3].Location.ILOffset);
2621
2622                 vm.Exit (0);
2623
2624                 vm = null;
2625         }
2626
2627         [Test]
2628         public void EventSets () {
2629                 //
2630                 // Create two filter which both match the same exception
2631                 //
2632                 Event e = run_until ("exceptions");
2633
2634                 var req = vm.CreateExceptionRequest (null);
2635                 req.Enable ();
2636
2637                 var req2 = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.OverflowException"));
2638                 req2.Enable ();
2639
2640                 vm.Resume ();
2641
2642                 var es = vm.GetNextEventSet ();
2643                 Assert.AreEqual (2, es.Events.Length);
2644
2645                 e = es [0];
2646                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2647                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2648
2649                 e = es [1];
2650                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2651                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2652
2653                 req.Disable ();
2654                 req2.Disable ();
2655         }
2656
2657         //
2658         // Test single threaded invokes during processing of nullref exceptions.
2659         // These won't work if the exception handling is done from the sigsegv signal
2660         // handler, since the sigsegv signal is disabled until control returns from the
2661         // signal handler.
2662         //
2663         [Test]
2664         [Category ("only3")]
2665         public void NullRefExceptionAndSingleThreadedInvoke () {
2666                 Event e = run_until ("exceptions");
2667                 var req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.NullReferenceException"));
2668                 req.Enable ();
2669
2670                 vm.Resume ();
2671
2672                 e = GetNextEvent ();
2673                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2674                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2675
2676                 var ex = (e as ExceptionEvent).Exception;
2677                 var tostring_method = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2678                 ex.InvokeMethod (e.Thread, tostring_method, null, InvokeOptions.SingleThreaded);
2679         }
2680
2681         [Test]
2682         public void Domains () {
2683                 vm.Detach ();
2684
2685                 Start (new string [] { "dtest-app.exe", "domain-test" });
2686
2687                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
2688
2689                 Event e = run_until ("domains");
2690
2691                 vm.Resume ();
2692                 
2693                 e = GetNextEvent ();
2694                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
2695
2696                 var domain = (e as AppDomainCreateEvent).Domain;
2697
2698                 // Check the object type
2699                 e = run_until ("domains_2");
2700                 var frame = e.Thread.GetFrames ()[0];
2701                 var o = frame.GetArgument (0) as ObjectMirror;
2702                 Assert.AreEqual ("CrossDomain", o.Type.Name);
2703
2704                 // Do a remoting invoke
2705                 var cross_domain_type = o.Type;
2706                 var v = o.InvokeMethod (e.Thread, cross_domain_type.GetMethod ("invoke_3"), null);
2707                 AssertValue (42, v);
2708
2709                 // Run until the callback in the domain
2710                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
2711                 Assert.IsNotNull (m);
2712                 vm.SetBreakpoint (m, 0);
2713
2714                 while (true) {
2715                         vm.Resume ();
2716                         e = GetNextEvent ();
2717                         if (e is BreakpointEvent)
2718                                 break;
2719                 }
2720
2721                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
2722
2723                 // d_method is from another domain
2724                 MethodMirror d_method = (e as BreakpointEvent).Method;
2725                 Assert.IsTrue (m != d_method);
2726
2727                 var frames = e.Thread.GetFrames ();
2728                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
2729                 Assert.AreEqual ("invoke", frames [1].Method.Name);
2730                 Assert.AreEqual ("domains", frames [2].Method.Name);
2731
2732                 // Test breakpoints on already JITted methods in other domains
2733                 m = entry_point.DeclaringType.GetMethod ("invoke_in_domain_2");
2734                 Assert.IsNotNull (m);
2735                 vm.SetBreakpoint (m, 0);
2736
2737                 while (true) {
2738                         vm.Resume ();
2739                         e = GetNextEvent ();
2740                         if (e is BreakpointEvent)
2741                                 break;
2742                 }
2743
2744                 Assert.AreEqual ("invoke_in_domain_2", (e as BreakpointEvent).Method.Name);
2745
2746                 // This is empty when receiving the AppDomainCreateEvent
2747                 Assert.AreEqual ("domain", domain.FriendlyName);
2748
2749                 // Run until the unload
2750                 while (true) {
2751                         vm.Resume ();
2752                         e = GetNextEvent ();
2753                         if (e is AssemblyUnloadEvent) {
2754                                 continue;
2755                         } else {
2756                                 break;
2757                         }
2758                 }
2759                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
2760                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
2761
2762                 // Run past the unload
2763                 e = run_until ("domains_3");
2764
2765                 // Test access to unloaded types
2766                 // FIXME: Add an exception type for this
2767                 AssertThrows<Exception> (delegate {
2768                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
2769                         });
2770         }
2771
2772         [Test]
2773         public void DynamicMethods () {
2774                 Event e = run_until ("dyn_call");
2775
2776                 var m = e.Thread.GetFrames ()[1].Method;
2777                 Assert.AreEqual ("dyn_method", m.Name);
2778
2779                 // Test access to IL
2780                 var body = m.GetMethodBody ();
2781
2782                 ILInstruction ins = body.Instructions [0];
2783                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2784                 Assert.AreEqual ("FOO", ins.Operand);
2785         }
2786
2787         [Test]
2788         public void RefEmit () {
2789                 vm.Detach ();
2790
2791                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
2792
2793                 Event e = run_until ("ref_emit_call");
2794
2795                 var m = e.Thread.GetFrames ()[1].Method;
2796                 Assert.AreEqual ("ref_emit_method", m.Name);
2797
2798                 // Test access to IL
2799                 var body = m.GetMethodBody ();
2800
2801                 ILInstruction ins;
2802
2803                 ins = body.Instructions [0];
2804                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2805                 Assert.AreEqual ("FOO", ins.Operand);
2806
2807                 ins = body.Instructions [1];
2808                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
2809                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
2810                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
2811         }
2812
2813         [Test]
2814         public void IsAttached () {
2815                 var f = entry_point.DeclaringType.GetField ("is_attached");
2816
2817                 Event e = run_until ("Main");
2818
2819                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
2820         }
2821
2822         [Test]
2823         public void StackTraceInNative () {
2824                 // Check that stack traces can be produced for threads in native code
2825                 vm.Detach ();
2826
2827                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
2828
2829                 var e = run_until ("frames_in_native");
2830
2831                 // FIXME: This is racy
2832                 vm.Resume ();
2833
2834                 Thread.Sleep (100);
2835
2836                 vm.Suspend ();
2837
2838                 StackFrame[] frames = e.Thread.GetFrames ();
2839
2840                 int frame_index = -1;
2841                 for (int i = 0; i < frames.Length; ++i) {
2842                         if (frames [i].Method.Name == "Sleep") {
2843                                 frame_index = i;
2844                                 break;
2845                         }
2846                 }
2847
2848                 Assert.IsTrue (frame_index != -1);
2849                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
2850                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
2851                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
2852
2853                 // Check that invokes are disabled for such threads
2854                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
2855
2856                 var m = t.GetMethod ("invoke_static_return_void");
2857                 AssertThrows<InvalidOperationException> (delegate {
2858                                 t.InvokeMethod (e.Thread, m, null);
2859                         });
2860
2861                 // Check that the frame info is invalidated
2862                 run_until ("frames_in_native_2");
2863
2864                 AssertThrows<InvalidStackFrameException> (delegate {
2865                                 Console.WriteLine (frames [frame_index].GetThis ());
2866                         });
2867         }
2868
2869         [Test]
2870         public void VirtualMachine_CreateEnumMirror () {
2871                 var e = run_until ("o1");
2872                 var frame = e.Thread.GetFrames () [0];
2873
2874                 object val = frame.GetThis ();
2875                 Assert.IsTrue (val is ObjectMirror);
2876                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
2877                 ObjectMirror o = (val as ObjectMirror);
2878
2879                 FieldInfoMirror field = o.Type.GetField ("field_enum");
2880                 Value f = o.GetValue (field);
2881                 TypeMirror enumType = (f as EnumMirror).Type;
2882
2883                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
2884                 f = o.GetValue (field);
2885                 Assert.AreEqual (1, (f as EnumMirror).Value);
2886
2887                 // Argument checking
2888                 AssertThrows<ArgumentNullException> (delegate () {
2889                                 vm.CreateEnumMirror (enumType, null);
2890                         });
2891
2892                 AssertThrows<ArgumentNullException> (delegate () {
2893                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
2894                         });
2895
2896                 // null value
2897                 AssertThrows<ArgumentException> (delegate () {
2898                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
2899                         });
2900
2901                 // value of a wrong type
2902                 AssertThrows<ArgumentException> (delegate () {
2903                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
2904                         });
2905         }
2906
2907         [Test]
2908         public void VirtualMachine_EnableEvents_Breakpoint () {
2909                 AssertThrows<ArgumentException> (delegate () {
2910                                 vm.EnableEvents (EventType.Breakpoint);
2911                         });
2912         }
2913
2914         [Test]
2915         public void SingleStepRegress654694 () {
2916                 int il_offset = -1;
2917
2918                 MethodMirror m = entry_point.DeclaringType.GetMethod ("ss_regress_654694");
2919                 foreach (Location l in m.Locations) {
2920                         if (l.ILOffset > 0 && il_offset == -1)
2921                                 il_offset = l.ILOffset;
2922                 }
2923
2924                 Event e = run_until ("ss_regress_654694");
2925
2926                 Assert.IsNotNull (m);
2927                 vm.SetBreakpoint (m, il_offset);
2928
2929                 vm.Resume ();
2930
2931                 e = GetNextEvent ();
2932                 Assert.IsTrue (e is BreakpointEvent);
2933
2934                 var req = create_step (e);
2935                 req.Depth = StepDepth.Over;
2936                 req.Size = StepSize.Line;
2937                 req.Enable ();
2938
2939                 vm.Resume ();
2940
2941                 e = GetNextEvent ();
2942                 Assert.IsTrue (e is StepEvent);
2943
2944                 req.Disable ();
2945         }
2946
2947         [Test]
2948         public void DebugBreak () {
2949                 vm.EnableEvents (EventType.UserBreak);
2950
2951                 run_until ("user");
2952
2953                 vm.Resume ();
2954                 var e = GetNextEvent ();
2955                 Assert.IsTrue (e is UserBreakEvent);
2956         }
2957
2958         [Test]
2959         public void DebugLog () {
2960                 vm.EnableEvents (EventType.UserLog);
2961
2962                 run_until ("user");
2963
2964                 vm.Resume ();
2965                 var e = GetNextEvent ();
2966                 Assert.IsTrue (e is UserLogEvent);
2967                 var le = e as UserLogEvent;
2968
2969                 Assert.AreEqual (5, le.Level);
2970                 Assert.AreEqual ("A", le.Category);
2971                 Assert.AreEqual ("B", le.Message);
2972         }
2973
2974         [Test]
2975         public void TypeGetMethodsByNameFlags () {
2976                 MethodMirror[] mm;
2977                 var assembly = entry_point.DeclaringType.Assembly;
2978                 var type = assembly.GetType ("Tests3");
2979
2980                 Assert.IsNotNull (type);
2981
2982                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Public, false);
2983                 Assert.AreEqual (1, mm.Length, "#1");
2984                 Assert.AreEqual ("M1", mm[0].Name, "#2");
2985
2986                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.NonPublic, false);
2987                 Assert.AreEqual (1, mm.Length, "#3");
2988                 Assert.AreEqual ("M2", mm[0].Name, "#4");
2989
2990                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public, false);
2991                 Assert.AreEqual (7, mm.Length, "#5"); //M3 plus Equals, GetHashCode, GetType, ToString, .ctor
2992
2993                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, false);
2994                 Assert.AreEqual (2, mm.Length, "#7");
2995
2996                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
2997                 Assert.AreEqual (1, mm.Length, "#9");
2998
2999                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
3000                 Assert.AreEqual (5, mm.Length, "#11");
3001
3002                 //Now with name
3003                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static | BindingFlags.Public, false);
3004                 Assert.AreEqual (1, mm.Length, "#12");
3005                 Assert.AreEqual ("M1", mm[0].Name, "#13");
3006
3007                 mm = type.GetMethodsByNameFlags ("m1", BindingFlags.Static | BindingFlags.Public, true);
3008                 Assert.AreEqual (1, mm.Length, "#14");
3009                 Assert.AreEqual ("M1", mm[0].Name, "#15");
3010
3011                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static  | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, false);
3012                 Assert.AreEqual (1, mm.Length, "#16");
3013                 Assert.AreEqual ("M1", mm[0].Name, "#17");
3014         }
3015
3016         [Test]
3017         [Category ("only88")]
3018         public void TypeLoadSourceFileFilter () {
3019                 Event e = run_until ("type_load");
3020
3021                 if (!vm.Version.AtLeast (2, 7))
3022                         return;
3023
3024                 string srcfile = (e as BreakpointEvent).Method.DeclaringType.GetSourceFiles (true)[0];
3025
3026                 var req = vm.CreateTypeLoadRequest ();
3027                 req.SourceFileFilter = new string [] { srcfile.ToUpper () };
3028                 req.Enable ();
3029
3030                 vm.Resume ();
3031                 e = GetNextEvent ();
3032                 Assert.IsTrue (e is TypeLoadEvent);
3033                 Assert.AreEqual ("TypeLoadClass", (e as TypeLoadEvent).Type.FullName);
3034         }
3035
3036         [Test]
3037         public void TypeLoadTypeNameFilter () {
3038                 Event e = run_until ("type_load");
3039
3040                 var req = vm.CreateTypeLoadRequest ();
3041                 req.TypeNameFilter = new string [] { "TypeLoadClass2" };
3042                 req.Enable ();
3043
3044                 vm.Resume ();
3045                 e = GetNextEvent ();
3046                 Assert.IsTrue (e is TypeLoadEvent);
3047                 Assert.AreEqual ("TypeLoadClass2", (e as TypeLoadEvent).Type.FullName);
3048         }
3049
3050         [Test]
3051         public void GetTypesForSourceFile () {
3052                 run_until ("user");
3053
3054                 var types = vm.GetTypesForSourceFile ("dtest-app.cs", false);
3055                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3056                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3057
3058                 types = vm.GetTypesForSourceFile ("DTEST-app.cs", true);
3059                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3060                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3061         }
3062
3063         [Test]
3064         public void GetTypesNamed () {
3065                 run_until ("user");
3066
3067                 var types = vm.GetTypes ("Tests", false);
3068                 Assert.AreEqual (1, types.Count);
3069                 Assert.AreEqual ("Tests", types [0].FullName);
3070
3071                 types = vm.GetTypes ("System.Exception", false);
3072                 Assert.AreEqual (1, types.Count);
3073                 Assert.AreEqual ("System.Exception", types [0].FullName);
3074         }
3075
3076         [Test]
3077         public void String_GetChars () {
3078                 object val;
3079
3080                 // Reuse this test
3081                 var e = run_until ("arg2");
3082
3083                 var frame = e.Thread.GetFrames () [0];
3084
3085                 val = frame.GetArgument (0);
3086                 Assert.IsTrue (val is StringMirror);
3087                 AssertValue ("FOO", val);
3088                 var s = (val as StringMirror);
3089                 Assert.AreEqual (3, s.Length);
3090
3091                 var c = s.GetChars (0, 2);
3092                 Assert.AreEqual (2, c.Length);
3093                 Assert.AreEqual ('F', c [0]);
3094                 Assert.AreEqual ('O', c [1]);
3095
3096                 AssertThrows<ArgumentException> (delegate () {          
3097                                 s.GetChars (2, 2);
3098                         });
3099         }
3100
3101         [Test]
3102         public void GetInterfaces () {
3103                 var e = run_until ("arg2");
3104
3105                 var frame = e.Thread.GetFrames () [0];
3106
3107                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3108                 var ifaces = cl1.GetInterfaces ();
3109                 Assert.AreEqual (1, ifaces.Length);
3110                 Assert.AreEqual ("ITest", ifaces [0].Name);
3111
3112                 var cl2 = cl1.GetMethod ("Baz").ReturnType;
3113                 var ifaces2 = cl2.GetInterfaces ();
3114                 Assert.AreEqual (1, ifaces2.Length);
3115                 Assert.AreEqual ("ITest`1", ifaces2 [0].Name);
3116         }
3117
3118         [Test]
3119         public void GetInterfaceMap () {
3120                 var e = run_until ("arg2");
3121
3122                 var frame = e.Thread.GetFrames () [0];
3123
3124                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3125                 var iface = cl1.Assembly.GetType ("ITest");
3126                 var map = cl1.GetInterfaceMap (iface);
3127                 Assert.AreEqual (cl1, map.TargetType);
3128                 Assert.AreEqual (iface, map.InterfaceType);
3129                 Assert.AreEqual (2, map.InterfaceMethods.Length);
3130                 Assert.AreEqual (2, map.TargetMethods.Length);
3131         }
3132
3133         [Test]
3134         public void StackAlloc_Breakpoints_Regress2775 () {
3135                 // Check that breakpoints on arm don't overwrite stackalloc-ed memory
3136                 var e = run_until ("regress_2755");
3137
3138                 var frame = e.Thread.GetFrames () [0];
3139                 var m = e.Method;
3140                 // This breaks at the call site
3141                 vm.SetBreakpoint (m, m.Locations [2].ILOffset);
3142
3143                 vm.Resume ();
3144                 var e2 = GetNextEvent ();
3145                 Assert.IsTrue (e2 is BreakpointEvent);
3146
3147                 e = run_until ("regress_2755_3");
3148                 frame = e.Thread.GetFrames () [1];
3149                 var res = frame.GetValue (m.GetLocal ("sum"));
3150                 AssertValue (0, res);
3151         }
3152
3153         [Test]
3154         public void MethodInfo () {
3155                 Event e = run_until ("locals2");
3156
3157                 StackFrame frame = e.Thread.GetFrames () [0];
3158                 var m = frame.Method;
3159
3160                 Assert.IsTrue (m.IsGenericMethod);
3161                 Assert.IsFalse (m.IsGenericMethodDefinition);
3162
3163                 var args = m.GetGenericArguments ();
3164                 Assert.AreEqual (1, args.Length);
3165                 Assert.AreEqual ("String", args [0].Name);
3166
3167                 var gmd = m.GetGenericMethodDefinition ();
3168                 Assert.IsTrue (gmd.IsGenericMethod);
3169                 Assert.IsTrue (gmd.IsGenericMethodDefinition);
3170                 Assert.AreEqual (gmd, gmd.GetGenericMethodDefinition ());
3171
3172                 args = gmd.GetGenericArguments ();
3173                 Assert.AreEqual (1, args.Length);
3174                 Assert.AreEqual ("T", args [0].Name);
3175
3176                 var attrs = m.GetCustomAttributes (true);
3177                 Assert.AreEqual (1, attrs.Length);
3178                 Assert.AreEqual ("StateMachineAttribute", attrs [0].Constructor.DeclaringType.Name);
3179         }
3180
3181         [Test]
3182         public void UnhandledException () {
3183                 vm.Exit (0);
3184
3185                 Start (new string [] { "dtest-app.exe", "unhandled-exception" });
3186
3187                 var req = vm.CreateExceptionRequest (null, false, true);
3188                 req.Enable ();
3189
3190                 var e = run_until ("unhandled_exception");
3191                 vm.Resume ();
3192
3193                 var e2 = GetNextEvent ();
3194                 Assert.IsTrue (e2 is ExceptionEvent);
3195
3196                 vm.Exit (0);
3197                 vm = null;
3198         }
3199
3200         [Test]
3201         public void UnhandledException_2 () {
3202                 vm.Exit (0);
3203
3204                 Start (new string [] { "dtest-app.exe", "unhandled-exception-endinvoke" });
3205
3206                 var req = vm.CreateExceptionRequest (null, false, true);
3207                 req.Enable ();
3208
3209                 MethodMirror m = entry_point.DeclaringType.GetMethod ("unhandled_exception_endinvoke_2");
3210                 Assert.IsNotNull (m);
3211                 vm.SetBreakpoint (m, m.ILOffsets [0]);
3212
3213                 var e = run_until ("unhandled_exception_endinvoke");
3214                 vm.Resume ();
3215
3216                 var e2 = GetNextEvent ();
3217                 Assert.IsFalse (e2 is ExceptionEvent);
3218
3219                 vm.Exit (0);
3220                 vm = null;
3221         }
3222
3223 #if NET_4_5
3224         [Test]
3225         public void UnhandledExceptionUserCode () {
3226                 vm.Detach ();
3227
3228                 // Exceptions caught in non-user code are treated as unhandled
3229                 Start (new string [] { "dtest-app.exe", "unhandled-exception-user" });
3230
3231                 var req = vm.CreateExceptionRequest (null, false, true);
3232                 req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
3233                 req.Enable ();
3234
3235                 var e = run_until ("unhandled_exception_user");
3236                 vm.Resume ();
3237
3238                 var e2 = GetNextEvent ();
3239                 Assert.IsTrue (e2 is ExceptionEvent);
3240
3241                 vm.Exit (0);
3242                 vm = null;
3243         }
3244 #endif
3245
3246         [Test]
3247         public void GCWhileSuspended () {
3248                 // Check that objects are kept alive during suspensions
3249                 Event e = run_until ("gc_suspend_1");
3250
3251                 MethodMirror m = entry_point.DeclaringType.GetMethod ("gc_suspend_invoke");
3252
3253                 var o = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3254                 //Console.WriteLine (o);
3255
3256                 StackFrame frame = e.Thread.GetFrames () [0];
3257                 TypeMirror t = frame.Method.DeclaringType;
3258                 for (int i = 0; i < 10; ++i)
3259                         t.InvokeMethod (e.Thread, m, new Value [] { });
3260
3261                 // This throws an exception if the object is collected
3262                 long addr = o.Address;
3263
3264                 var o2 = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3265                 Assert.IsNull (o2);
3266         }
3267
3268         [Test]
3269         public void MakeGenericMethod () {
3270                 Event e = run_until ("bp1");
3271
3272                 var intm = vm.RootDomain.GetCorrespondingType (typeof (int));
3273                 var stringm = vm.RootDomain.GetCorrespondingType (typeof (string));
3274                 var gm = entry_point.DeclaringType.GetMethod ("generic_method");
3275                 var res = gm.MakeGenericMethod (new TypeMirror [] { stringm });
3276                 var args = res.GetGenericArguments ();
3277                 Assert.AreEqual (1, args.Length);
3278                 Assert.AreEqual (stringm, args [0]);
3279
3280                 // Error checking
3281                 AssertThrows<ArgumentNullException> (delegate {
3282                                 gm.MakeGenericMethod (null);
3283                         });
3284                 AssertThrows<ArgumentNullException> (delegate {
3285                                 gm.MakeGenericMethod (new TypeMirror [] { null });
3286                         });
3287                 AssertThrows<ArgumentException> (delegate {
3288                                 gm.MakeGenericMethod (new TypeMirror [] { stringm, stringm });
3289                         });
3290                 AssertThrows<InvalidOperationException> (delegate {
3291                                 gm.MakeGenericMethod (new TypeMirror [] { intm });
3292                         });
3293                 AssertThrows<InvalidOperationException> (delegate {
3294                                 entry_point.DeclaringType.GetMethod ("Main").MakeGenericMethod (new TypeMirror [] { intm });
3295                         });
3296         }
3297
3298         [Test]
3299         public void InspectThreadSuspenedOnWaitOne () {
3300                 TearDown ();
3301                 Start (true, "dtest-app.exe", "wait-one" );
3302
3303                 ThreadMirror.NativeTransitions = true;
3304
3305                 var evt = run_until ("wait_one");
3306                 Assert.IsNotNull (evt, "#1");
3307
3308                 var thread = evt.Thread;
3309                 Assert.AreEqual (ThreadState.Running, thread.ThreadState, "#1.1");
3310
3311                 var frames = thread.GetFrames ();
3312                 Assert.IsNotNull (frames, "#2");
3313                 Assert.AreEqual (2, frames.Length, "#3");
3314                 Assert.AreEqual ("wait_one", frames [0].Method.Name, "#4");
3315                 Assert.AreEqual ("Main", frames [1].Method.Name, "#5");
3316
3317                 vm.Resume ();
3318
3319                 Thread.Sleep (500); //FIXME this is racy, maybe single step? or something?
3320
3321                 vm.Suspend ();
3322                 Assert.AreEqual (ThreadState.WaitSleepJoin, thread.ThreadState, "#6");
3323
3324                 frames = thread.GetFrames ();
3325                 Assert.AreEqual (4, frames.Length, "#7");
3326                 Assert.AreEqual ("WaitOne_internal", frames [0].Method.Name, "#8");
3327                 Assert.AreEqual ("WaitOne", frames [1].Method.Name, "#8.1");
3328                 Assert.AreEqual ("wait_one", frames [2].Method.Name, "#9");
3329                 Assert.AreEqual ("Main", frames [3].Method.Name, "#10");
3330
3331
3332                 var frame = frames [0];
3333                 Assert.IsTrue (frame.IsNativeTransition, "#11.1");
3334                 try {
3335                         frame.GetThis ();
3336                         Assert.Fail ("Known limitation - can't get info from m2n frames");
3337                 } catch (AbsentInformationException) {}
3338
3339                 frame = frames [1];
3340                 Assert.IsFalse (frame.IsNativeTransition, "#12.1");
3341                 var wait_one_this = frame.GetThis ();
3342                 Assert.IsNotNull (wait_one_this, "#12.2");
3343
3344                 frame = frames [2];
3345                 var locals = frame.GetVisibleVariables ();
3346                 Assert.AreEqual (1, locals.Count, "#13.1");
3347
3348                 var local_0 = frame.GetValue (locals [0]);
3349                 Assert.IsNotNull (local_0, "#13.2");
3350
3351                 Assert.AreEqual (wait_one_this, local_0, "#14.2");
3352         }
3353 }
3354
3355 }