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