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