f04385add38397d31187e0d89de4eb395eed31b3
[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                 // no subclasses
2507                 req.IncludeSubclasses = false;
2508                 req.Enable ();
2509
2510                 vm.Resume ();
2511
2512                 e = GetNextEvent ();
2513                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2514                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
2515                 req.Disable ();
2516
2517                 // Implicit exceptions
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 ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2526                 req.Disable ();
2527
2528                 // Single stepping after an exception
2529                 req = vm.CreateExceptionRequest (null);
2530                 req.Enable ();
2531
2532                 vm.Resume ();
2533
2534                 e = GetNextEvent ();
2535                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2536                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
2537                 frames = e.Thread.GetFrames ();
2538                 Assert.AreEqual ("exceptions2", frames [0].Method.Name);
2539                 req.Disable ();
2540
2541                 var sreq = create_step (e);
2542                 sreq.Depth = StepDepth.Over;
2543                 sreq.Size = StepSize.Line;
2544                 sreq.Enable ();
2545
2546                 vm.Resume ();
2547                 e = GetNextEvent ();
2548                 Assert.IsInstanceOfType (typeof (StepEvent), e);
2549                 frames = e.Thread.GetFrames ();
2550                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2551                 sreq.Disable ();
2552
2553                 // Argument checking
2554                 AssertThrows<ArgumentException> (delegate {
2555                                 vm.CreateExceptionRequest (e.Thread.Type);
2556                         });
2557         }
2558
2559         [Test]
2560         public void ExceptionFilter () {
2561                 Event e = run_until ("exception_filter");
2562
2563                 MethodMirror m = entry_point.DeclaringType.GetMethod ("exception_filter_filter");
2564                 Assert.IsNotNull (m);
2565
2566                 vm.SetBreakpoint (m, 0);
2567
2568                 vm.Resume ();
2569
2570                 e = GetNextEvent ();
2571                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
2572                 Assert.IsTrue (e is BreakpointEvent);
2573                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
2574
2575                 var frames = e.Thread.GetFrames ();
2576
2577                 Assert.IsTrue (frames [0].Location.SourceFile.IndexOf ("dtest-app.cs") != -1);
2578                 Assert.AreEqual ("exception_filter_filter", frames [0].Location.Method.Name);
2579
2580                 Assert.AreEqual (0, frames [1].Location.Method.MetadataToken);
2581                 Assert.AreEqual (0x0f, frames [1].Location.ILOffset);
2582
2583                 Assert.AreEqual ("exception_filter_method", frames [2].Location.Method.Name);
2584                 Assert.AreEqual (0x06, frames [2].Location.ILOffset);
2585
2586                 Assert.AreEqual (0, frames [3].Location.Method.MetadataToken, 0);
2587                 Assert.AreEqual (0, frames [3].Location.ILOffset);
2588
2589                 Assert.AreEqual ("exception_filter", frames [4].Location.Method.Name);
2590         }
2591
2592         [Test]
2593         public void ExceptionFilter2 () {
2594                 vm.Detach ();
2595
2596                 Start (new string [] { "dtest-excfilter.exe" });
2597
2598                 MethodMirror filter_method = entry_point.DeclaringType.GetMethod ("Filter");
2599                 Assert.IsNotNull (filter_method);
2600
2601                 MethodMirror test_method = entry_point.DeclaringType.GetMethod ("Test");
2602                 Assert.IsNotNull (test_method);
2603
2604                 vm.SetBreakpoint (filter_method, 0);
2605
2606                 vm.Resume ();
2607
2608                 var e = GetNextEvent ();
2609                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
2610                 Assert.IsTrue (e is BreakpointEvent);
2611                 Assert.AreEqual (filter_method.Name, (e as BreakpointEvent).Method.Name);
2612
2613                 var frames = e.Thread.GetFrames ();
2614
2615                 Assert.AreEqual (4, frames.Count ());
2616
2617                 Assert.AreEqual (filter_method.Name, frames [0].Location.Method.Name);
2618                 Assert.AreEqual (20, frames [0].Location.LineNumber);
2619                 Assert.AreEqual (0, frames [0].Location.ILOffset);
2620
2621                 Assert.AreEqual (test_method.Name, frames [1].Location.Method.Name);
2622                 Assert.AreEqual (37, frames [1].Location.LineNumber);
2623                 Assert.AreEqual (0x0b, frames [1].Location.ILOffset);
2624
2625                 Assert.AreEqual (test_method.Name, frames [2].Location.Method.Name);
2626                 Assert.AreEqual (33, frames [2].Location.LineNumber);
2627                 Assert.AreEqual (0x05, frames [2].Location.ILOffset);
2628
2629                 Assert.AreEqual (entry_point.Name, frames [3].Location.Method.Name);
2630                 Assert.AreEqual (14, frames [3].Location.LineNumber);
2631                 Assert.AreEqual (0x00, frames [3].Location.ILOffset);
2632
2633                 vm.Exit (0);
2634
2635                 vm = null;
2636         }
2637
2638         [Test]
2639         public void EventSets () {
2640                 //
2641                 // Create two filter which both match the same exception
2642                 //
2643                 Event e = run_until ("exceptions");
2644
2645                 var req = vm.CreateExceptionRequest (null);
2646                 req.Enable ();
2647
2648                 var req2 = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.OverflowException"));
2649                 req2.Enable ();
2650
2651                 vm.Resume ();
2652
2653                 var es = vm.GetNextEventSet ();
2654                 Assert.AreEqual (2, es.Events.Length);
2655
2656                 e = es [0];
2657                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2658                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2659
2660                 e = es [1];
2661                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2662                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2663
2664                 req.Disable ();
2665                 req2.Disable ();
2666         }
2667
2668         //
2669         // Test single threaded invokes during processing of nullref exceptions.
2670         // These won't work if the exception handling is done from the sigsegv signal
2671         // handler, since the sigsegv signal is disabled until control returns from the
2672         // signal handler.
2673         //
2674         [Test]
2675         [Category ("only3")]
2676         public void NullRefExceptionAndSingleThreadedInvoke () {
2677                 Event e = run_until ("exceptions");
2678                 var req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.NullReferenceException"));
2679                 req.Enable ();
2680
2681                 vm.Resume ();
2682
2683                 e = GetNextEvent ();
2684                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2685                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2686
2687                 var ex = (e as ExceptionEvent).Exception;
2688                 var tostring_method = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2689                 ex.InvokeMethod (e.Thread, tostring_method, null, InvokeOptions.SingleThreaded);
2690         }
2691
2692         [Test]
2693         public void Domains () {
2694                 vm.Detach ();
2695
2696                 Start (new string [] { "dtest-app.exe", "domain-test" });
2697
2698                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
2699
2700                 Event e = run_until ("domains");
2701
2702                 vm.Resume ();
2703                 
2704                 e = GetNextEvent ();
2705                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
2706
2707                 var domain = (e as AppDomainCreateEvent).Domain;
2708
2709                 // Check the object type
2710                 e = run_until ("domains_2");
2711                 var frame = e.Thread.GetFrames ()[0];
2712                 var o = frame.GetArgument (0) as ObjectMirror;
2713                 Assert.AreEqual ("CrossDomain", o.Type.Name);
2714
2715                 // Do a remoting invoke
2716                 var cross_domain_type = o.Type;
2717                 var v = o.InvokeMethod (e.Thread, cross_domain_type.GetMethod ("invoke_3"), null);
2718                 AssertValue (42, v);
2719
2720                 // Run until the callback in the domain
2721                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
2722                 Assert.IsNotNull (m);
2723                 vm.SetBreakpoint (m, 0);
2724
2725                 while (true) {
2726                         vm.Resume ();
2727                         e = GetNextEvent ();
2728                         if (e is BreakpointEvent)
2729                                 break;
2730                 }
2731
2732                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
2733
2734                 // d_method is from another domain
2735                 MethodMirror d_method = (e as BreakpointEvent).Method;
2736                 Assert.IsTrue (m != d_method);
2737
2738                 var frames = e.Thread.GetFrames ();
2739                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
2740                 Assert.AreEqual ("invoke", frames [1].Method.Name);
2741                 Assert.AreEqual ("domains", frames [2].Method.Name);
2742
2743                 // Test breakpoints on already JITted methods in other domains
2744                 m = entry_point.DeclaringType.GetMethod ("invoke_in_domain_2");
2745                 Assert.IsNotNull (m);
2746                 vm.SetBreakpoint (m, 0);
2747
2748                 while (true) {
2749                         vm.Resume ();
2750                         e = GetNextEvent ();
2751                         if (e is BreakpointEvent)
2752                                 break;
2753                 }
2754
2755                 Assert.AreEqual ("invoke_in_domain_2", (e as BreakpointEvent).Method.Name);
2756
2757                 // This is empty when receiving the AppDomainCreateEvent
2758                 Assert.AreEqual ("domain", domain.FriendlyName);
2759
2760                 // Run until the unload
2761                 while (true) {
2762                         vm.Resume ();
2763                         e = GetNextEvent ();
2764                         if (e is AssemblyUnloadEvent) {
2765                                 continue;
2766                         } else {
2767                                 break;
2768                         }
2769                 }
2770                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
2771                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
2772
2773                 // Run past the unload
2774                 e = run_until ("domains_3");
2775
2776                 // Test access to unloaded types
2777                 // FIXME: Add an exception type for this
2778                 AssertThrows<Exception> (delegate {
2779                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
2780                         });
2781         }
2782
2783         [Test]
2784         public void DynamicMethods () {
2785                 Event e = run_until ("dyn_call");
2786
2787                 var m = e.Thread.GetFrames ()[1].Method;
2788                 Assert.AreEqual ("dyn_method", m.Name);
2789
2790                 // Test access to IL
2791                 var body = m.GetMethodBody ();
2792
2793                 ILInstruction ins = body.Instructions [0];
2794                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2795                 Assert.AreEqual ("FOO", ins.Operand);
2796         }
2797
2798         [Test]
2799         public void RefEmit () {
2800                 vm.Detach ();
2801
2802                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
2803
2804                 Event e = run_until ("ref_emit_call");
2805
2806                 var m = e.Thread.GetFrames ()[1].Method;
2807                 Assert.AreEqual ("ref_emit_method", m.Name);
2808
2809                 // Test access to IL
2810                 var body = m.GetMethodBody ();
2811
2812                 ILInstruction ins;
2813
2814                 ins = body.Instructions [0];
2815                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2816                 Assert.AreEqual ("FOO", ins.Operand);
2817
2818                 ins = body.Instructions [1];
2819                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
2820                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
2821                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
2822         }
2823
2824         [Test]
2825         public void IsAttached () {
2826                 var f = entry_point.DeclaringType.GetField ("is_attached");
2827
2828                 Event e = run_until ("Main");
2829
2830                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
2831         }
2832
2833         [Test]
2834         public void StackTraceInNative () {
2835                 // Check that stack traces can be produced for threads in native code
2836                 vm.Detach ();
2837
2838                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
2839
2840                 var e = run_until ("frames_in_native");
2841
2842                 // FIXME: This is racy
2843                 vm.Resume ();
2844
2845                 Thread.Sleep (100);
2846
2847                 vm.Suspend ();
2848
2849                 StackFrame[] frames = e.Thread.GetFrames ();
2850
2851                 int frame_index = -1;
2852                 for (int i = 0; i < frames.Length; ++i) {
2853                         if (frames [i].Method.Name == "Sleep") {
2854                                 frame_index = i;
2855                                 break;
2856                         }
2857                 }
2858
2859                 Assert.IsTrue (frame_index != -1);
2860                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
2861                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
2862                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
2863
2864                 // Check that invokes are disabled for such threads
2865                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
2866
2867                 var m = t.GetMethod ("invoke_static_return_void");
2868                 AssertThrows<InvalidOperationException> (delegate {
2869                                 t.InvokeMethod (e.Thread, m, null);
2870                         });
2871
2872                 // Check that the frame info is invalidated
2873                 run_until ("frames_in_native_2");
2874
2875                 AssertThrows<InvalidStackFrameException> (delegate {
2876                                 Console.WriteLine (frames [frame_index].GetThis ());
2877                         });
2878         }
2879
2880         [Test]
2881         public void VirtualMachine_CreateEnumMirror () {
2882                 var e = run_until ("o1");
2883                 var frame = e.Thread.GetFrames () [0];
2884
2885                 object val = frame.GetThis ();
2886                 Assert.IsTrue (val is ObjectMirror);
2887                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
2888                 ObjectMirror o = (val as ObjectMirror);
2889
2890                 FieldInfoMirror field = o.Type.GetField ("field_enum");
2891                 Value f = o.GetValue (field);
2892                 TypeMirror enumType = (f as EnumMirror).Type;
2893
2894                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
2895                 f = o.GetValue (field);
2896                 Assert.AreEqual (1, (f as EnumMirror).Value);
2897
2898                 // Argument checking
2899                 AssertThrows<ArgumentNullException> (delegate () {
2900                                 vm.CreateEnumMirror (enumType, null);
2901                         });
2902
2903                 AssertThrows<ArgumentNullException> (delegate () {
2904                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
2905                         });
2906
2907                 // null value
2908                 AssertThrows<ArgumentException> (delegate () {
2909                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
2910                         });
2911
2912                 // value of a wrong type
2913                 AssertThrows<ArgumentException> (delegate () {
2914                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
2915                         });
2916         }
2917
2918         [Test]
2919         public void VirtualMachine_EnableEvents_Breakpoint () {
2920                 AssertThrows<ArgumentException> (delegate () {
2921                                 vm.EnableEvents (EventType.Breakpoint);
2922                         });
2923         }
2924
2925         [Test]
2926         public void SingleStepRegress654694 () {
2927                 int il_offset = -1;
2928
2929                 MethodMirror m = entry_point.DeclaringType.GetMethod ("ss_regress_654694");
2930                 foreach (Location l in m.Locations) {
2931                         if (l.ILOffset > 0 && il_offset == -1)
2932                                 il_offset = l.ILOffset;
2933                 }
2934
2935                 Event e = run_until ("ss_regress_654694");
2936
2937                 Assert.IsNotNull (m);
2938                 vm.SetBreakpoint (m, il_offset);
2939
2940                 vm.Resume ();
2941
2942                 e = GetNextEvent ();
2943                 Assert.IsTrue (e is BreakpointEvent);
2944
2945                 var req = create_step (e);
2946                 req.Depth = StepDepth.Over;
2947                 req.Size = StepSize.Line;
2948                 req.Enable ();
2949
2950                 vm.Resume ();
2951
2952                 e = GetNextEvent ();
2953                 Assert.IsTrue (e is StepEvent);
2954
2955                 req.Disable ();
2956         }
2957
2958         [Test]
2959         public void DebugBreak () {
2960                 vm.EnableEvents (EventType.UserBreak);
2961
2962                 run_until ("user");
2963
2964                 vm.Resume ();
2965                 var e = GetNextEvent ();
2966                 Assert.IsTrue (e is UserBreakEvent);
2967         }
2968
2969         [Test]
2970         public void DebugLog () {
2971                 vm.EnableEvents (EventType.UserLog);
2972
2973                 run_until ("user");
2974
2975                 vm.Resume ();
2976                 var e = GetNextEvent ();
2977                 Assert.IsTrue (e is UserLogEvent);
2978                 var le = e as UserLogEvent;
2979
2980                 Assert.AreEqual (5, le.Level);
2981                 Assert.AreEqual ("A", le.Category);
2982                 Assert.AreEqual ("B", le.Message);
2983         }
2984
2985         [Test]
2986         public void TypeGetMethodsByNameFlags () {
2987                 MethodMirror[] mm;
2988                 var assembly = entry_point.DeclaringType.Assembly;
2989                 var type = assembly.GetType ("Tests3");
2990
2991                 Assert.IsNotNull (type);
2992
2993                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Public, false);
2994                 Assert.AreEqual (1, mm.Length, "#1");
2995                 Assert.AreEqual ("M1", mm[0].Name, "#2");
2996
2997                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.NonPublic, false);
2998                 Assert.AreEqual (1, mm.Length, "#3");
2999                 Assert.AreEqual ("M2", mm[0].Name, "#4");
3000
3001                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public, false);
3002                 Assert.AreEqual (7, mm.Length, "#5"); //M3 plus Equals, GetHashCode, GetType, ToString, .ctor
3003
3004                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, false);
3005                 Assert.AreEqual (2, mm.Length, "#7");
3006
3007                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
3008                 Assert.AreEqual (1, mm.Length, "#9");
3009
3010                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
3011                 Assert.AreEqual (5, mm.Length, "#11");
3012
3013                 //Now with name
3014                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static | BindingFlags.Public, false);
3015                 Assert.AreEqual (1, mm.Length, "#12");
3016                 Assert.AreEqual ("M1", mm[0].Name, "#13");
3017
3018                 mm = type.GetMethodsByNameFlags ("m1", BindingFlags.Static | BindingFlags.Public, true);
3019                 Assert.AreEqual (1, mm.Length, "#14");
3020                 Assert.AreEqual ("M1", mm[0].Name, "#15");
3021
3022                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static  | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, false);
3023                 Assert.AreEqual (1, mm.Length, "#16");
3024                 Assert.AreEqual ("M1", mm[0].Name, "#17");
3025         }
3026
3027         [Test]
3028         [Category ("only88")]
3029         public void TypeLoadSourceFileFilter () {
3030                 Event e = run_until ("type_load");
3031
3032                 if (!vm.Version.AtLeast (2, 7))
3033                         return;
3034
3035                 string srcfile = (e as BreakpointEvent).Method.DeclaringType.GetSourceFiles (true)[0];
3036
3037                 var req = vm.CreateTypeLoadRequest ();
3038                 req.SourceFileFilter = new string [] { srcfile.ToUpper () };
3039                 req.Enable ();
3040
3041                 vm.Resume ();
3042                 e = GetNextEvent ();
3043                 Assert.IsTrue (e is TypeLoadEvent);
3044                 Assert.AreEqual ("TypeLoadClass", (e as TypeLoadEvent).Type.FullName);
3045         }
3046
3047         [Test]
3048         public void TypeLoadTypeNameFilter () {
3049                 Event e = run_until ("type_load");
3050
3051                 var req = vm.CreateTypeLoadRequest ();
3052                 req.TypeNameFilter = new string [] { "TypeLoadClass2" };
3053                 req.Enable ();
3054
3055                 vm.Resume ();
3056                 e = GetNextEvent ();
3057                 Assert.IsTrue (e is TypeLoadEvent);
3058                 Assert.AreEqual ("TypeLoadClass2", (e as TypeLoadEvent).Type.FullName);
3059         }
3060
3061         [Test]
3062         public void GetTypesForSourceFile () {
3063                 run_until ("user");
3064
3065                 var types = vm.GetTypesForSourceFile ("dtest-app.cs", false);
3066                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3067                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3068
3069                 types = vm.GetTypesForSourceFile ("DTEST-app.cs", true);
3070                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3071                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3072         }
3073
3074         [Test]
3075         public void GetTypesNamed () {
3076                 run_until ("user");
3077
3078                 var types = vm.GetTypes ("Tests", false);
3079                 Assert.AreEqual (1, types.Count);
3080                 Assert.AreEqual ("Tests", types [0].FullName);
3081
3082                 types = vm.GetTypes ("System.Exception", false);
3083                 Assert.AreEqual (1, types.Count);
3084                 Assert.AreEqual ("System.Exception", types [0].FullName);
3085         }
3086
3087         [Test]
3088         public void String_GetChars () {
3089                 object val;
3090
3091                 // Reuse this test
3092                 var e = run_until ("arg2");
3093
3094                 var frame = e.Thread.GetFrames () [0];
3095
3096                 val = frame.GetArgument (0);
3097                 Assert.IsTrue (val is StringMirror);
3098                 AssertValue ("FOO", val);
3099                 var s = (val as StringMirror);
3100                 Assert.AreEqual (3, s.Length);
3101
3102                 var c = s.GetChars (0, 2);
3103                 Assert.AreEqual (2, c.Length);
3104                 Assert.AreEqual ('F', c [0]);
3105                 Assert.AreEqual ('O', c [1]);
3106
3107                 AssertThrows<ArgumentException> (delegate () {          
3108                                 s.GetChars (2, 2);
3109                         });
3110         }
3111
3112         [Test]
3113         public void GetInterfaces () {
3114                 var e = run_until ("arg2");
3115
3116                 var frame = e.Thread.GetFrames () [0];
3117
3118                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3119                 var ifaces = cl1.GetInterfaces ();
3120                 Assert.AreEqual (1, ifaces.Length);
3121                 Assert.AreEqual ("ITest", ifaces [0].Name);
3122
3123                 var cl2 = cl1.GetMethod ("Baz").ReturnType;
3124                 var ifaces2 = cl2.GetInterfaces ();
3125                 Assert.AreEqual (1, ifaces2.Length);
3126                 Assert.AreEqual ("ITest`1", ifaces2 [0].Name);
3127         }
3128
3129         [Test]
3130         public void GetInterfaceMap () {
3131                 var e = run_until ("arg2");
3132
3133                 var frame = e.Thread.GetFrames () [0];
3134
3135                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3136                 var iface = cl1.Assembly.GetType ("ITest");
3137                 var map = cl1.GetInterfaceMap (iface);
3138                 Assert.AreEqual (cl1, map.TargetType);
3139                 Assert.AreEqual (iface, map.InterfaceType);
3140                 Assert.AreEqual (2, map.InterfaceMethods.Length);
3141                 Assert.AreEqual (2, map.TargetMethods.Length);
3142         }
3143
3144         [Test]
3145         public void StackAlloc_Breakpoints_Regress2775 () {
3146                 // Check that breakpoints on arm don't overwrite stackalloc-ed memory
3147                 var e = run_until ("regress_2755");
3148
3149                 var frame = e.Thread.GetFrames () [0];
3150                 var m = e.Method;
3151                 // This breaks at the call site
3152                 vm.SetBreakpoint (m, m.Locations [2].ILOffset);
3153
3154                 vm.Resume ();
3155                 var e2 = GetNextEvent ();
3156                 Assert.IsTrue (e2 is BreakpointEvent);
3157
3158                 e = run_until ("regress_2755_3");
3159                 frame = e.Thread.GetFrames () [1];
3160                 var res = frame.GetValue (m.GetLocal ("sum"));
3161                 AssertValue (0, res);
3162         }
3163
3164         [Test]
3165         public void MethodInfo () {
3166                 Event e = run_until ("locals2");
3167
3168                 StackFrame frame = e.Thread.GetFrames () [0];
3169                 var m = frame.Method;
3170
3171                 Assert.IsTrue (m.IsGenericMethod);
3172                 Assert.IsFalse (m.IsGenericMethodDefinition);
3173
3174                 var args = m.GetGenericArguments ();
3175                 Assert.AreEqual (1, args.Length);
3176                 Assert.AreEqual ("String", args [0].Name);
3177
3178                 var gmd = m.GetGenericMethodDefinition ();
3179                 Assert.IsTrue (gmd.IsGenericMethod);
3180                 Assert.IsTrue (gmd.IsGenericMethodDefinition);
3181                 Assert.AreEqual (gmd, gmd.GetGenericMethodDefinition ());
3182
3183                 args = gmd.GetGenericArguments ();
3184                 Assert.AreEqual (1, args.Length);
3185                 Assert.AreEqual ("T", args [0].Name);
3186
3187                 var attrs = m.GetCustomAttributes (true);
3188                 Assert.AreEqual (1, attrs.Length);
3189                 Assert.AreEqual ("StateMachineAttribute", attrs [0].Constructor.DeclaringType.Name);
3190         }
3191
3192         [Test]
3193         public void UnhandledException () {
3194                 vm.Exit (0);
3195
3196                 Start (new string [] { "dtest-app.exe", "unhandled-exception" });
3197
3198                 var req = vm.CreateExceptionRequest (null, false, true);
3199                 req.Enable ();
3200
3201                 var e = run_until ("unhandled_exception");
3202                 vm.Resume ();
3203
3204                 var e2 = GetNextEvent ();
3205                 Assert.IsTrue (e2 is ExceptionEvent);
3206
3207                 vm.Exit (0);
3208                 vm = null;
3209         }
3210
3211         [Test]
3212         public void UnhandledException_2 () {
3213                 vm.Exit (0);
3214
3215                 Start (new string [] { "dtest-app.exe", "unhandled-exception-endinvoke" });
3216
3217                 var req = vm.CreateExceptionRequest (null, false, true);
3218                 req.Enable ();
3219
3220                 MethodMirror m = entry_point.DeclaringType.GetMethod ("unhandled_exception_endinvoke_2");
3221                 Assert.IsNotNull (m);
3222                 vm.SetBreakpoint (m, m.ILOffsets [0]);
3223
3224                 var e = run_until ("unhandled_exception_endinvoke");
3225                 vm.Resume ();
3226
3227                 var e2 = GetNextEvent ();
3228                 Assert.IsFalse (e2 is ExceptionEvent);
3229
3230                 vm.Exit (0);
3231                 vm = null;
3232         }
3233
3234 #if NET_4_5
3235         [Test]
3236         public void UnhandledExceptionUserCode () {
3237                 vm.Detach ();
3238
3239                 // Exceptions caught in non-user code are treated as unhandled
3240                 Start (new string [] { "dtest-app.exe", "unhandled-exception-user" });
3241
3242                 var req = vm.CreateExceptionRequest (null, false, true);
3243                 req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
3244                 req.Enable ();
3245
3246                 var e = run_until ("unhandled_exception_user");
3247                 vm.Resume ();
3248
3249                 var e2 = GetNextEvent ();
3250                 Assert.IsTrue (e2 is ExceptionEvent);
3251
3252                 vm.Exit (0);
3253                 vm = null;
3254         }
3255 #endif
3256
3257         [Test]
3258         public void GCWhileSuspended () {
3259                 // Check that objects are kept alive during suspensions
3260                 Event e = run_until ("gc_suspend_1");
3261
3262                 MethodMirror m = entry_point.DeclaringType.GetMethod ("gc_suspend_invoke");
3263
3264                 var o = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3265                 //Console.WriteLine (o);
3266
3267                 StackFrame frame = e.Thread.GetFrames () [0];
3268                 TypeMirror t = frame.Method.DeclaringType;
3269                 for (int i = 0; i < 10; ++i)
3270                         t.InvokeMethod (e.Thread, m, new Value [] { });
3271
3272                 // This throws an exception if the object is collected
3273                 long addr = o.Address;
3274
3275                 var o2 = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3276                 Assert.IsNull (o2);
3277         }
3278
3279         [Test]
3280         public void MakeGenericMethod () {
3281                 Event e = run_until ("bp1");
3282
3283                 var intm = vm.RootDomain.GetCorrespondingType (typeof (int));
3284                 var stringm = vm.RootDomain.GetCorrespondingType (typeof (string));
3285                 var gm = entry_point.DeclaringType.GetMethod ("generic_method");
3286                 var res = gm.MakeGenericMethod (new TypeMirror [] { stringm });
3287                 var args = res.GetGenericArguments ();
3288                 Assert.AreEqual (1, args.Length);
3289                 Assert.AreEqual (stringm, args [0]);
3290
3291                 // Error checking
3292                 AssertThrows<ArgumentNullException> (delegate {
3293                                 gm.MakeGenericMethod (null);
3294                         });
3295                 AssertThrows<ArgumentNullException> (delegate {
3296                                 gm.MakeGenericMethod (new TypeMirror [] { null });
3297                         });
3298                 AssertThrows<ArgumentException> (delegate {
3299                                 gm.MakeGenericMethod (new TypeMirror [] { stringm, stringm });
3300                         });
3301                 AssertThrows<InvalidOperationException> (delegate {
3302                                 gm.MakeGenericMethod (new TypeMirror [] { intm });
3303                         });
3304                 AssertThrows<InvalidOperationException> (delegate {
3305                                 entry_point.DeclaringType.GetMethod ("Main").MakeGenericMethod (new TypeMirror [] { intm });
3306                         });
3307         }
3308
3309         [Test]
3310         public void InspectThreadSuspenedOnWaitOne () {
3311                 TearDown ();
3312                 Start (true, "dtest-app.exe", "wait-one" );
3313
3314                 ThreadMirror.NativeTransitions = true;
3315
3316                 var evt = run_until ("wait_one");
3317                 Assert.IsNotNull (evt, "#1");
3318
3319                 var thread = evt.Thread;
3320                 Assert.AreEqual (ThreadState.Running, thread.ThreadState, "#1.1");
3321
3322                 var frames = thread.GetFrames ();
3323                 Assert.IsNotNull (frames, "#2");
3324                 Assert.AreEqual (2, frames.Length, "#3");
3325                 Assert.AreEqual ("wait_one", frames [0].Method.Name, "#4");
3326                 Assert.AreEqual ("Main", frames [1].Method.Name, "#5");
3327
3328                 vm.Resume ();
3329
3330                 Thread.Sleep (500); //FIXME this is racy, maybe single step? or something?
3331
3332                 vm.Suspend ();
3333                 Assert.AreEqual (ThreadState.WaitSleepJoin, thread.ThreadState, "#6");
3334
3335                 frames = thread.GetFrames ();
3336                 Assert.AreEqual (4, frames.Length, "#7");
3337                 Assert.AreEqual ("WaitOne_internal", frames [0].Method.Name, "#8");
3338                 Assert.AreEqual ("WaitOne", frames [1].Method.Name, "#8.1");
3339                 Assert.AreEqual ("wait_one", frames [2].Method.Name, "#9");
3340                 Assert.AreEqual ("Main", frames [3].Method.Name, "#10");
3341
3342
3343                 var frame = frames [0];
3344                 Assert.IsTrue (frame.IsNativeTransition, "#11.1");
3345                 try {
3346                         frame.GetThis ();
3347                         Assert.Fail ("Known limitation - can't get info from m2n frames");
3348                 } catch (AbsentInformationException) {}
3349
3350                 frame = frames [1];
3351                 Assert.IsFalse (frame.IsNativeTransition, "#12.1");
3352                 var wait_one_this = frame.GetThis ();
3353                 Assert.IsNotNull (wait_one_this, "#12.2");
3354
3355                 frame = frames [2];
3356                 var locals = frame.GetVisibleVariables ();
3357                 Assert.AreEqual (1, locals.Count, "#13.1");
3358
3359                 var local_0 = frame.GetValue (locals [0]);
3360                 Assert.IsNotNull (local_0, "#13.2");
3361
3362                 Assert.AreEqual (wait_one_this, local_0, "#14.2");
3363         }
3364 }
3365
3366 }