Handle ENETDOWN error if defined.
[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
1556         [Test]
1557         public void GetVisibleVariables () {
1558                 Event e = run_until ("locals4");
1559
1560                 // First scope
1561                 var locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1562                 Assert.AreEqual (2, locals.Count);
1563                 var loc = locals.First (l => l.Name == "i");
1564                 Assert.AreEqual ("Int64", loc.Type.Name);
1565                 loc = locals.First (l => l.Name == "s");
1566                 Assert.AreEqual ("String", loc.Type.Name);
1567
1568                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1569                 Assert.AreEqual ("i", loc.Name);
1570                 Assert.AreEqual ("Int64", loc.Type.Name);
1571
1572                 e = run_until ("locals5");
1573
1574                 // Second scope
1575                 locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1576                 Assert.AreEqual (2, locals.Count);
1577                 loc = locals.First (l => l.Name == "i");
1578                 Assert.AreEqual ("String", loc.Type.Name);
1579                 loc = locals.First (l => l.Name == "s");
1580                 Assert.AreEqual ("String", loc.Type.Name);
1581
1582                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1583                 Assert.AreEqual ("i", loc.Name);
1584                 Assert.AreEqual ("String", loc.Type.Name);
1585
1586                 // Variable in another scope
1587                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("j");
1588                 Assert.IsNull (loc);
1589         }
1590
1591         [Test]
1592         public void Exit () {
1593                 run_until ("Main");
1594
1595                 vm.Exit (5);
1596
1597                 var e = GetNextEvent ();
1598                 Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
1599
1600                 var p = vm.Process;
1601                 /* Could be a remote vm with no process */
1602                 if (p != null) {
1603                         p.WaitForExit ();
1604                         Assert.AreEqual (5, p.ExitCode);
1605
1606                         // error handling
1607                         AssertThrows<VMDisconnectedException> (delegate () {
1608                                         vm.Resume ();
1609                                 });
1610                 }
1611
1612                 vm = null;
1613         }
1614
1615         [Test]
1616         public void Dispose () {
1617                 run_until ("Main");
1618
1619                 vm.Detach ();
1620
1621                 var e = GetNextEvent ();
1622                 Assert.IsInstanceOfType (typeof (VMDisconnectEvent), e);
1623
1624                 var p = vm.Process;
1625                 /* Could be a remote vm with no process */
1626                 if (p != null) {
1627                         p.WaitForExit ();
1628                         Assert.AreEqual (3, p.ExitCode);
1629
1630                         // error handling
1631                         AssertThrows<VMDisconnectedException> (delegate () {
1632                                         vm.Resume ();
1633                                 });
1634                 }
1635
1636                 vm = null;
1637         }
1638
1639         [Test]
1640         public void ColumnNumbers () {
1641                 Event e = run_until ("line_numbers");
1642
1643                 // FIXME: Merge this with LineNumbers () when its fixed
1644
1645                 step_req = vm.CreateStepRequest (e.Thread);
1646                 step_req.Depth = StepDepth.Into;
1647                 step_req.Enable ();
1648
1649                 Location l;
1650                 
1651                 vm.Resume ();
1652
1653                 e = GetNextEvent ();
1654                 Assert.IsTrue (e is StepEvent);
1655
1656                 l = e.Thread.GetFrames ()[0].Location;
1657
1658                 Assert.AreEqual (3, l.ColumnNumber);
1659
1660                 step_req.Disable ();
1661         }
1662
1663         [Test]
1664         // Broken by mcs+runtime changes (#5438)
1665         [Category("NotWorking")]
1666         public void LineNumbers () {
1667                 Event e = run_until ("line_numbers");
1668
1669                 step_req = vm.CreateStepRequest (e.Thread);
1670                 step_req.Depth = StepDepth.Into;
1671                 step_req.Enable ();
1672
1673                 Location l;
1674                 
1675                 vm.Resume ();
1676
1677                 e = GetNextEvent ();
1678                 Assert.IsTrue (e is StepEvent);
1679
1680                 l = e.Thread.GetFrames ()[0].Location;
1681
1682                 Assert.IsTrue (l.SourceFile.IndexOf ("dtest-app.cs") != -1);
1683                 Assert.AreEqual ("ln1", l.Method.Name);
1684
1685                 // Check hash
1686                 using (FileStream fs = new FileStream (l.SourceFile, FileMode.Open, FileAccess.Read)) {
1687                         MD5 md5 = MD5.Create ();
1688                         var hash = md5.ComputeHash (fs);
1689
1690                         for (int i = 0; i < 16; ++i)
1691                                 Assert.AreEqual (hash [i], l.SourceFileHash [i]);
1692                 }
1693                 
1694                 int line_base = l.LineNumber;
1695
1696                 vm.Resume ();
1697                 e = GetNextEvent ();
1698                 Assert.IsTrue (e is StepEvent);
1699                 l = e.Thread.GetFrames ()[0].Location;
1700                 Assert.AreEqual ("ln2", l.Method.Name);
1701                 Assert.AreEqual (line_base + 6, l.LineNumber);
1702
1703                 vm.Resume ();
1704                 e = GetNextEvent ();
1705                 Assert.IsTrue (e is StepEvent);
1706                 l = e.Thread.GetFrames ()[0].Location;
1707                 Assert.AreEqual ("ln1", l.Method.Name);
1708                 Assert.AreEqual (line_base + 1, l.LineNumber);
1709
1710                 vm.Resume ();
1711                 e = GetNextEvent ();
1712                 Assert.IsTrue (e is StepEvent);
1713                 l = e.Thread.GetFrames ()[0].Location;
1714                 Assert.AreEqual ("ln3", l.Method.Name);
1715                 Assert.AreEqual (line_base + 11, l.LineNumber);
1716
1717                 vm.Resume ();
1718                 e = GetNextEvent ();
1719                 Assert.IsTrue (e is StepEvent);
1720                 l = e.Thread.GetFrames ()[0].Location;
1721                 Assert.AreEqual ("ln3", l.Method.Name);
1722                 Assert.IsTrue (l.SourceFile.EndsWith ("FOO"));
1723                 Assert.AreEqual (55, l.LineNumber);
1724
1725                 vm.Resume ();
1726                 e = GetNextEvent ();
1727                 Assert.IsTrue (e is StepEvent);
1728                 l = e.Thread.GetFrames ()[0].Location;
1729                 Assert.AreEqual ("ln1", l.Method.Name);
1730                 Assert.AreEqual (line_base + 2, l.LineNumber);
1731
1732                 // GetSourceFiles ()
1733                 string[] sources = l.Method.DeclaringType.GetSourceFiles ();
1734                 Assert.AreEqual (2, sources.Length);
1735                 Assert.AreEqual ("dtest-app.cs", sources [0]);
1736                 Assert.AreEqual ("FOO", sources [1]);
1737
1738                 sources = l.Method.DeclaringType.GetSourceFiles (true);
1739                 Assert.AreEqual (2, sources.Length);
1740                 Assert.IsTrue (sources [0].EndsWith ("dtest-app.cs"));
1741                 Assert.IsTrue (sources [1].EndsWith ("FOO"));
1742         }
1743
1744         [Test]
1745         public void Suspend () {
1746                 vm.Detach ();
1747
1748                 Start (new string [] { "dtest-app.exe", "suspend-test" });
1749
1750                 Event e = run_until ("suspend");
1751
1752                 ThreadMirror main = e.Thread;
1753
1754                 vm.Resume ();
1755
1756                 Thread.Sleep (100);
1757
1758                 vm.Suspend ();
1759
1760                 // The debuggee should be suspended while it is running the infinite loop
1761                 // in suspend ()
1762                 StackFrame frame = main.GetFrames ()[0];
1763                 Assert.AreEqual ("suspend", frame.Method.Name);
1764
1765                 vm.Resume ();
1766
1767                 // resuming when not suspended
1768                 AssertThrows<InvalidOperationException> (delegate () {
1769                                 vm.Resume ();
1770                         });
1771
1772                 vm.Exit (0);
1773
1774                 vm = null;
1775         }
1776
1777         [Test]
1778         public void AssemblyLoad () {
1779                 Event e = run_until ("assembly_load");
1780
1781                 var load_req = vm.CreateAssemblyLoadRequest ();
1782                 load_req.Enable ();
1783
1784                 vm.Resume ();
1785
1786                 e = GetNextEvent ();
1787                 Assert.IsInstanceOfType (typeof (AssemblyLoadEvent), e);
1788                 Assert.IsTrue ((e as AssemblyLoadEvent).Assembly.Location.EndsWith ("System.dll"));
1789
1790                 var frames = e.Thread.GetFrames ();
1791                 Assert.IsTrue (frames.Length > 0);
1792                 Assert.AreEqual ("assembly_load", frames [0].Method.Name);
1793         }
1794
1795         [Test]
1796         public void CreateValue () {
1797                 PrimitiveValue v;
1798
1799                 v = vm.CreateValue (1);
1800                 Assert.AreEqual (vm, v.VirtualMachine);
1801                 Assert.AreEqual (1, v.Value);
1802
1803                 v = vm.CreateValue (null);
1804                 Assert.AreEqual (vm, v.VirtualMachine);
1805                 Assert.AreEqual (null, v.Value);
1806
1807                 // Argument checking
1808                 AssertThrows <ArgumentException> (delegate () {
1809                                 v = vm.CreateValue ("FOO");
1810                         });
1811         }
1812
1813         [Test]
1814         public void CreateString () {
1815                 StringMirror s = vm.RootDomain.CreateString ("ABC");
1816
1817                 Assert.AreEqual (vm, s.VirtualMachine);
1818                 Assert.AreEqual ("ABC", s.Value);
1819                 Assert.AreEqual (vm.RootDomain, s.Domain);
1820
1821                 // Long strings
1822                 StringBuilder sb = new StringBuilder ();
1823                 for (int i = 0; i < 1024; ++i)
1824                         sb.Append ('A');
1825                 s = vm.RootDomain.CreateString (sb.ToString ());
1826
1827                 // Argument checking
1828                 AssertThrows <ArgumentNullException> (delegate () {
1829                                 s = vm.RootDomain.CreateString (null);
1830                         });
1831         }
1832
1833         [Test]
1834         public void CreateBoxedValue () {
1835                 ObjectMirror o = vm.RootDomain.CreateBoxedValue (new PrimitiveValue (vm, 42));
1836
1837                 Assert.AreEqual ("Int32", o.Type.Name);
1838                 //AssertValue (42, m.GetValue (o.Type.GetField ("m_value")));
1839
1840                 // Argument checking
1841                 AssertThrows <ArgumentNullException> (delegate () {
1842                                 vm.RootDomain.CreateBoxedValue (null);
1843                         });
1844
1845                 AssertThrows <ArgumentException> (delegate () {
1846                                 vm.RootDomain.CreateBoxedValue (o);
1847                         });
1848         }
1849
1850         [Test]
1851         public void Invoke () {
1852                 Event e = run_until ("invoke1");
1853
1854                 StackFrame frame = e.Thread.GetFrames () [0];
1855
1856                 TypeMirror t = frame.Method.DeclaringType;
1857                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
1858
1859                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
1860
1861                 MethodMirror m;
1862                 Value v;
1863
1864                 // return void
1865                 m = t.GetMethod ("invoke_return_void");
1866                 v = this_obj.InvokeMethod (e.Thread, m, null);
1867                 Assert.IsNull (v);
1868
1869                 // return ref
1870                 m = t.GetMethod ("invoke_return_ref");
1871                 v = this_obj.InvokeMethod (e.Thread, m, null);
1872                 AssertValue ("ABC", v);
1873
1874                 // return null
1875                 m = t.GetMethod ("invoke_return_null");
1876                 v = this_obj.InvokeMethod (e.Thread, m, null);
1877                 AssertValue (null, v);
1878
1879                 // return primitive
1880                 m = t.GetMethod ("invoke_return_primitive");
1881                 v = this_obj.InvokeMethod (e.Thread, m, null);
1882                 AssertValue (42, v);
1883
1884                 // return nullable
1885                 m = t.GetMethod ("invoke_return_nullable");
1886                 v = this_obj.InvokeMethod (e.Thread, m, null);
1887                 Assert.IsInstanceOfType (typeof (StructMirror), v);
1888                 var s = v as StructMirror;
1889                 AssertValue (42, s.Fields [0]);
1890                 AssertValue (true, s.Fields [1]);
1891
1892                 // pass nullable as this
1893                 //m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
1894                 m = s.Type.GetMethod ("ToString");
1895                 v = s.InvokeMethod (e.Thread, m, null);
1896
1897                 // return nullable null
1898                 m = t.GetMethod ("invoke_return_nullable_null");
1899                 v = this_obj.InvokeMethod (e.Thread, m, null);
1900                 Assert.IsInstanceOfType (typeof (StructMirror), v);
1901                 s = v as StructMirror;
1902                 AssertValue (0, s.Fields [0]);
1903                 AssertValue (false, s.Fields [1]);
1904
1905                 // pass nullable as this
1906                 //m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
1907                 m = s.Type.GetMethod ("ToString");
1908                 v = s.InvokeMethod (e.Thread, m, null);
1909
1910                 // pass primitive
1911                 m = t.GetMethod ("invoke_pass_primitive");
1912                 Value[] args = new Value [] {
1913                         vm.CreateValue ((byte)Byte.MaxValue),
1914                         vm.CreateValue ((sbyte)SByte.MaxValue),
1915                         vm.CreateValue ((short)1),
1916                         vm.CreateValue ((ushort)1),
1917                         vm.CreateValue ((int)1),
1918                         vm.CreateValue ((uint)1),
1919                         vm.CreateValue ((long)1),
1920                         vm.CreateValue ((ulong)1),
1921                         vm.CreateValue ('A'),
1922                         vm.CreateValue (true),
1923                         vm.CreateValue (3.14f),
1924                         vm.CreateValue (3.14) };
1925
1926                 v = this_obj.InvokeMethod (e.Thread, m, args);
1927                 AssertValue ((int)Byte.MaxValue + (int)SByte.MaxValue + 1 + 1 + 1 + 1 + 1 + 1 + 'A' + 1 + 3 + 3, v);
1928
1929                 // pass ref
1930                 m = t.GetMethod ("invoke_pass_ref");
1931                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1932                 AssertValue ("ABC", v);
1933
1934                 // pass null
1935                 m = t.GetMethod ("invoke_pass_ref");
1936                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (null) });
1937                 AssertValue (null, v);
1938
1939                 // static
1940                 m = t.GetMethod ("invoke_static_pass_ref");
1941                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1942                 AssertValue ("ABC", v);
1943
1944                 // static invoked using ObjectMirror.InvokeMethod
1945                 m = t.GetMethod ("invoke_static_pass_ref");
1946                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1947                 AssertValue ("ABC", v);
1948
1949                 // method which throws an exception
1950                 try {
1951                         m = t.GetMethod ("invoke_throws");
1952                         v = this_obj.InvokeMethod (e.Thread, m, null);
1953                         Assert.Fail ();
1954                 } catch (InvocationException ex) {
1955                         Assert.AreEqual ("Exception", ex.Exception.Type.Name);
1956                 }
1957
1958                 // newobj
1959                 m = t.GetMethod (".ctor");
1960                 v = t.InvokeMethod (e.Thread, m, null);
1961                 Assert.IsInstanceOfType (typeof (ObjectMirror), v);
1962                 Assert.AreEqual ("Tests", (v as ObjectMirror).Type.Name);
1963
1964                 // Argument checking
1965                 
1966                 // null thread
1967                 AssertThrows<ArgumentNullException> (delegate {
1968                                 m = t.GetMethod ("invoke_pass_ref");
1969                                 v = this_obj.InvokeMethod (null, m, new Value [] { vm.CreateValue (null) });                            
1970                         });
1971
1972                 // null method
1973                 AssertThrows<ArgumentNullException> (delegate {
1974                                 v = this_obj.InvokeMethod (e.Thread, null, new Value [] { vm.CreateValue (null) });                             
1975                         });
1976
1977                 // invalid number of arguments
1978                 m = t.GetMethod ("invoke_pass_ref");
1979                 AssertThrows<ArgumentException> (delegate {
1980                                 v = this_obj.InvokeMethod (e.Thread, m, null);
1981                         });
1982
1983                 // invalid type of argument (ref != primitive)
1984                 m = t.GetMethod ("invoke_pass_ref");
1985                 AssertThrows<ArgumentException> (delegate {
1986                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
1987                         });
1988
1989                 // invalid type of argument (primitive != primitive)
1990                 m = t.GetMethod ("invoke_pass_primitive_2");
1991                 AssertThrows<ArgumentException> (delegate {
1992                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
1993                         });
1994
1995                 // invoking a non-static method as static
1996                 m = t.GetMethod ("invoke_pass_ref");
1997                 AssertThrows<ArgumentException> (delegate {
1998                                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1999                         });
2000
2001                 // invoking a method defined in another class
2002                 m = t2.GetMethod ("invoke");
2003                 AssertThrows<ArgumentException> (delegate {
2004                                 v = this_obj.InvokeMethod (e.Thread, m, null);
2005                         });
2006         }
2007
2008         [Test]
2009         public void InvokeVType () {
2010                 Event e = run_until ("invoke1");
2011
2012                 StackFrame frame = e.Thread.GetFrames () [0];
2013
2014                 var s = frame.GetArgument (1) as StructMirror;
2015
2016                 TypeMirror t = s.Type;
2017
2018                 MethodMirror m;
2019                 Value v;
2020
2021                 // Pass struct as this, receive int
2022                 m = t.GetMethod ("invoke_return_int");
2023                 v = s.InvokeMethod (e.Thread, m, null);
2024                 AssertValue (42, v);
2025
2026                 // Pass struct as this, receive intptr
2027                 m = t.GetMethod ("invoke_return_intptr");
2028                 v = s.InvokeMethod (e.Thread, m, null);
2029                 AssertValue (43, v);
2030
2031                 // Static method
2032                 m = t.GetMethod ("invoke_static");
2033                 v = t.InvokeMethod (e.Thread, m, null);
2034                 AssertValue (5, v);
2035
2036                 // Pass generic struct as this
2037                 s = frame.GetArgument (2) as StructMirror;
2038                 t = s.Type;
2039                 m = t.GetMethod ("invoke_return_int");
2040                 v = s.InvokeMethod (e.Thread, m, null);
2041                 AssertValue (42, v);
2042         }
2043
2044         [Test]
2045         public void BreakpointDuringInvoke () {
2046                 Event e = run_until ("invoke1");
2047
2048                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
2049                 Assert.IsNotNull (m);
2050                 vm.SetBreakpoint (m, 0);
2051
2052                 StackFrame frame = e.Thread.GetFrames () [0];
2053                 var o = frame.GetThis () as ObjectMirror;
2054
2055                 bool failed = false;
2056
2057                 bool finished = false;
2058                 object wait = new object ();
2059
2060                 // Have to invoke in a separate thread as the invoke is suspended until we
2061                 // resume after the breakpoint
2062                 Thread t = new Thread (delegate () {
2063                                 try {
2064                                         o.InvokeMethod (e.Thread, m, null);
2065                                 } catch {
2066                                         failed = true;
2067                                 }
2068                                 lock (wait) {
2069                                         finished = true;
2070                                         Monitor.Pulse (wait);
2071                                 }
2072                         });
2073
2074                 t.Start ();
2075
2076                 StackFrame invoke_frame = null;
2077
2078                 try {
2079                         e = GetNextEvent ();
2080                         Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
2081                         // Check stack trace support and invokes
2082                         var frames = e.Thread.GetFrames ();
2083                         invoke_frame = frames [0];
2084                         Assert.AreEqual ("invoke2", frames [0].Method.Name);
2085                         Assert.IsTrue (frames [0].IsDebuggerInvoke);
2086                         Assert.AreEqual ("invoke1", frames [1].Method.Name);
2087                 } finally {
2088                         vm.Resume ();
2089                 }
2090
2091                 lock (wait) {
2092                         if (!finished)
2093                                 Monitor.Wait (wait);
2094                 }
2095
2096                 // Check that the invoke frames are no longer valid
2097                 AssertThrows<InvalidStackFrameException> (delegate {
2098                                 invoke_frame.GetThis ();
2099                         });
2100
2101                 // Check InvokeOptions.DisableBreakpoints flag
2102                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2103         }
2104
2105         [Test]
2106         public void DisabledExceptionDuringInvoke () {
2107                 Event e = run_until ("invoke_ex");
2108
2109                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_ex_inner");
2110
2111                 StackFrame frame = e.Thread.GetFrames () [0];
2112                 var o = frame.GetThis () as ObjectMirror;
2113
2114                 var req = vm.CreateExceptionRequest (null);
2115                 req.Enable ();
2116
2117                 // Check InvokeOptions.DisableBreakpoints flag
2118                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2119
2120                 req.Disable ();
2121         }
2122
2123         [Test]
2124         public void InvokeSingleThreaded () {
2125                 vm.Detach ();
2126
2127                 Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
2128
2129                 Event e = run_until ("invoke_single_threaded_2");
2130
2131                 StackFrame f = e.Thread.GetFrames ()[0];
2132
2133                 var obj = f.GetThis () as ObjectMirror;
2134
2135                 // Check that the counter value incremented by the other thread does not increase
2136                 // during the invoke.
2137                 object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2138
2139                 var m = obj.Type.GetMethod ("invoke_return_void");
2140                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2141
2142             object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2143
2144                 Assert.AreEqual ((int)counter1, (int)counter2);
2145
2146                 // Test multiple invokes done in succession
2147                 m = obj.Type.GetMethod ("invoke_return_void");
2148                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2149
2150                 // Test events during single-threaded invokes
2151                 vm.EnableEvents (EventType.TypeLoad);
2152                 m = obj.Type.GetMethod ("invoke_type_load");
2153                 obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
2154                                 vm.Resume ();
2155                         }, null);
2156
2157                 e = GetNextEvent ();
2158                 Assert.AreEqual (EventType.TypeLoad, e.EventType);
2159         }
2160
2161         List<Value> invoke_results;
2162
2163         [Test]
2164         public void InvokeMultiple () {
2165                 Event e = run_until ("invoke1");
2166
2167                 StackFrame frame = e.Thread.GetFrames () [0];
2168
2169                 TypeMirror t = frame.Method.DeclaringType;
2170                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2171
2172                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2173
2174                 var methods = new MethodMirror [2];
2175                 methods [0] = t.GetMethod ("invoke_return_ref");
2176                 methods [1] = t.GetMethod ("invoke_return_primitive");
2177
2178                 invoke_results = new List<Value> ();
2179
2180                 var r = this_obj.BeginInvokeMultiple (e.Thread, methods, null, InvokeOptions.SingleThreaded, invoke_multiple_cb, this_obj);
2181                 WaitHandle.WaitAll (new WaitHandle[] { r.AsyncWaitHandle });
2182                 this_obj.EndInvokeMultiple (r);
2183                 // The callback might still be running
2184                 while (invoke_results.Count < 2) {
2185                         Thread.Sleep (100);
2186                 }
2187                 AssertValue ("ABC", invoke_results [0]);
2188                 AssertValue (42, invoke_results [1]);
2189         }
2190
2191         void invoke_multiple_cb (IAsyncResult ar) {
2192                 ObjectMirror this_obj = (ObjectMirror)ar.AsyncState;
2193
2194                 var res = this_obj.EndInvokeMethod (ar);
2195                 lock (invoke_results)
2196                         invoke_results.Add (res);
2197         }
2198
2199         [Test]
2200         public void GetThreads () {
2201                 vm.GetThreads ();
2202         }
2203
2204         [Test]
2205         public void Threads () {
2206                 Event e = run_until ("threads");
2207
2208                 Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
2209
2210                 Assert.IsTrue (e.Thread.ThreadId > 0);
2211
2212                 Assert.AreEqual (e.Thread.TID, e.Thread.TID);
2213
2214                 vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
2215
2216                 vm.Resume ();
2217
2218                 e = GetNextEvent ();
2219                 Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
2220                 var state = e.Thread.ThreadState;
2221                 Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
2222
2223                 vm.Resume ();
2224
2225                 e = GetNextEvent ();
2226                 Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
2227                 Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
2228         }
2229
2230         [Test]
2231         public void Frame_SetValue () {
2232                 Event e = run_until ("locals2");
2233
2234                 StackFrame frame = e.Thread.GetFrames () [0];
2235
2236                 // primitive
2237                 var l = frame.Method.GetLocal ("i");
2238                 frame.SetValue (l, vm.CreateValue ((long)55));
2239                 AssertValue (55, frame.GetValue (l));
2240
2241                 // reference
2242                 l = frame.Method.GetLocal ("s");
2243                 frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
2244                 AssertValue ("DEF", frame.GetValue (l));
2245
2246                 // argument as local
2247                 l = frame.Method.GetLocal ("arg");
2248                 frame.SetValue (l, vm.CreateValue (6));
2249                 AssertValue (6, frame.GetValue (l));
2250
2251                 // argument
2252                 var p = frame.Method.GetParameters ()[1];
2253                 frame.SetValue (p, vm.CreateValue (7));
2254                 AssertValue (7, frame.GetValue (p));
2255
2256                 // gshared
2257                 p = frame.Method.GetParameters ()[2];
2258                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF"));
2259                 AssertValue ("DEF", frame.GetValue (p));
2260
2261                 // byref
2262                 p = frame.Method.GetParameters ()[3];
2263                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF2"));
2264                 AssertValue ("DEF2", frame.GetValue (p));
2265
2266                 // argument checking
2267
2268                 // variable null
2269                 AssertThrows<ArgumentNullException> (delegate () {
2270                                 frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
2271                         });
2272
2273                 // value null
2274                 AssertThrows<ArgumentNullException> (delegate () {
2275                                 l = frame.Method.GetLocal ("i");
2276                                 frame.SetValue (l, null);
2277                         });
2278
2279                 // value of invalid type
2280                 AssertThrows<ArgumentException> (delegate () {
2281                                 l = frame.Method.GetLocal ("i");
2282                                 frame.SetValue (l, vm.CreateValue (55));
2283                         });
2284         }
2285
2286         [Test]
2287         [Category ("only")]
2288         public void Frame_SetValue_Registers () {
2289                 Event e = run_until ("locals6_1");
2290
2291                 StackFrame frame = e.Thread.GetFrames () [1];
2292
2293                 // Set 'j' to 99
2294                 var l = frame.Method.GetLocal ("j");
2295                 frame.SetValue (l, vm.CreateValue (99));
2296                 AssertValue (99, frame.GetValue (l));
2297
2298                 // Check it during execution
2299                 e = run_until ("locals6_2");
2300                 frame = e.Thread.GetFrames () [0];
2301                 AssertValue (99, frame.GetValue (frame.Method.GetParameters ()[0]));
2302
2303                 // Set it while in a frame which clobbers its register
2304                 e = run_until ("locals6_3");
2305                 frame = e.Thread.GetFrames () [1];
2306                 frame.SetValue (l, vm.CreateValue (100));
2307                 AssertValue (100, frame.GetValue (l));
2308
2309                 // Check it during execution
2310                 e = run_until ("locals6_4");
2311                 frame = e.Thread.GetFrames () [0];
2312                 AssertValue (100, frame.GetValue (frame.Method.GetParameters ()[0]));
2313
2314                 // Signed byte value
2315                 e = run_until ("locals6_5");
2316                 frame = e.Thread.GetFrames () [1];
2317                 var l2 = frame.Method.GetLocal ("sb");
2318                 frame.SetValue (l2, vm.CreateValue ((sbyte)-99));
2319                 AssertValue (-99, frame.GetValue (l2));
2320
2321                 // Check it during execution
2322                 e = run_until ("locals6_6");
2323                 frame = e.Thread.GetFrames () [0];
2324                 AssertValue (-99, frame.GetValue (frame.Method.GetParameters ()[0]));
2325         }
2326
2327         [Test]
2328         public void InvokeRegress () {
2329                 Event e = run_until ("invoke1");
2330
2331                 StackFrame frame = e.Thread.GetFrames () [0];
2332
2333                 TypeMirror t = frame.Method.DeclaringType;
2334                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2335
2336                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2337
2338                 MethodMirror m;
2339                 Value v;
2340
2341                 // do an invoke
2342                 m = t.GetMethod ("invoke_return_void");
2343                 v = this_obj.InvokeMethod (e.Thread, m, null);
2344                 Assert.IsNull (v);
2345
2346                 // Check that the stack frames remain valid during the invoke
2347                 Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
2348
2349                 // do another invoke
2350                 m = t.GetMethod ("invoke_return_void");
2351                 v = this_obj.InvokeMethod (e.Thread, m, null);
2352                 Assert.IsNull (v);
2353
2354                 // Try a single step after the invoke
2355                 var req = vm.CreateStepRequest (e.Thread);
2356                 req.Depth = StepDepth.Into;
2357                 req.Size = StepSize.Line;
2358                 req.Enable ();
2359
2360                 step_req = req;
2361
2362                 // Skip nop
2363                 step_once ();
2364
2365                 // Step into invoke2
2366                 vm.Resume ();
2367                 e = GetNextEvent ();
2368                 Assert.IsTrue (e is StepEvent);
2369                 Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
2370
2371                 req.Disable ();
2372
2373                 frame = e.Thread.GetFrames () [0];
2374         }
2375
2376         [Test]
2377         public void Exceptions () {
2378                 Event e = run_until ("exceptions");
2379                 var req = vm.CreateExceptionRequest (null);
2380                 req.Enable ();
2381
2382                 vm.Resume ();
2383
2384                 e = GetNextEvent ();
2385                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2386                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2387
2388                 var frames = e.Thread.GetFrames ();
2389                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2390                 req.Disable ();
2391
2392                 // exception type filter
2393
2394                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
2395                 req.Enable ();
2396
2397                 // Skip the throwing of the second OverflowException       
2398                 vm.Resume ();
2399
2400                 e = GetNextEvent ();
2401                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2402                 Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
2403                 req.Disable ();
2404
2405                 // exception type filter for subclasses
2406                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
2407                 req.Enable ();
2408
2409                 vm.Resume ();
2410
2411                 e = GetNextEvent ();
2412                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2413                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2414                 req.Disable ();
2415
2416                 // Implicit exceptions
2417                 req = vm.CreateExceptionRequest (null);
2418                 req.Enable ();
2419
2420                 vm.Resume ();
2421
2422                 e = GetNextEvent ();
2423                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2424                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2425                 req.Disable ();
2426
2427                 // Single stepping after an exception
2428                 req = vm.CreateExceptionRequest (null);
2429                 req.Enable ();
2430
2431                 vm.Resume ();
2432
2433                 e = GetNextEvent ();
2434                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2435                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
2436                 frames = e.Thread.GetFrames ();
2437                 Assert.AreEqual ("exceptions2", frames [0].Method.Name);
2438                 req.Disable ();
2439
2440                 var sreq = vm.CreateStepRequest (e.Thread);
2441                 sreq.Depth = StepDepth.Over;
2442                 sreq.Size = StepSize.Line;
2443                 sreq.Enable ();
2444
2445                 vm.Resume ();
2446                 e = GetNextEvent ();
2447                 Assert.IsInstanceOfType (typeof (StepEvent), e);
2448                 frames = e.Thread.GetFrames ();
2449                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2450                 sreq.Disable ();
2451
2452                 // Argument checking
2453                 AssertThrows<ArgumentException> (delegate {
2454                                 vm.CreateExceptionRequest (e.Thread.Type);
2455                         });
2456         }
2457
2458         [Test]
2459         public void ExceptionFilter () {
2460                 Event e = run_until ("exception_filter");
2461
2462                 MethodMirror m = entry_point.DeclaringType.GetMethod ("exception_filter_filter");
2463                 Assert.IsNotNull (m);
2464
2465                 vm.SetBreakpoint (m, 0);
2466
2467                 vm.Resume ();
2468
2469                 e = GetNextEvent ();
2470                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
2471                 Assert.IsTrue (e is BreakpointEvent);
2472                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
2473
2474                 var frames = e.Thread.GetFrames ();
2475
2476                 Assert.IsTrue (frames [0].Location.SourceFile.IndexOf ("dtest-app.cs") != -1);
2477                 Assert.AreEqual ("exception_filter_filter", frames [0].Location.Method.Name);
2478
2479                 Assert.AreEqual (0, frames [1].Location.Method.MetadataToken);
2480                 Assert.AreEqual (0x0f, frames [1].Location.ILOffset);
2481
2482                 Assert.AreEqual ("exception_filter_method", frames [2].Location.Method.Name);
2483                 Assert.AreEqual (0x06, frames [2].Location.ILOffset);
2484
2485                 Assert.AreEqual (0, frames [3].Location.Method.MetadataToken, 0);
2486                 Assert.AreEqual (0, frames [3].Location.ILOffset);
2487
2488                 Assert.AreEqual ("exception_filter", frames [4].Location.Method.Name);
2489         }
2490
2491         [Test]
2492         public void ExceptionFilter2 () {
2493                 vm.Detach ();
2494
2495                 Start (new string [] { "dtest-excfilter.exe" });
2496
2497                 MethodMirror filter_method = entry_point.DeclaringType.GetMethod ("Filter");
2498                 Assert.IsNotNull (filter_method);
2499
2500                 MethodMirror test_method = entry_point.DeclaringType.GetMethod ("Test");
2501                 Assert.IsNotNull (test_method);
2502
2503                 vm.SetBreakpoint (filter_method, 0);
2504
2505                 vm.Resume ();
2506
2507                 var e = GetNextEvent ();
2508                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
2509                 Assert.IsTrue (e is BreakpointEvent);
2510                 Assert.AreEqual (filter_method.Name, (e as BreakpointEvent).Method.Name);
2511
2512                 var frames = e.Thread.GetFrames ();
2513
2514                 Assert.AreEqual (4, frames.Count ());
2515
2516                 Assert.AreEqual (filter_method.Name, frames [0].Location.Method.Name);
2517                 Assert.AreEqual (20, frames [0].Location.LineNumber);
2518                 Assert.AreEqual (0, frames [0].Location.ILOffset);
2519
2520                 Assert.AreEqual (test_method.Name, frames [1].Location.Method.Name);
2521                 Assert.AreEqual (37, frames [1].Location.LineNumber);
2522                 Assert.AreEqual (0x0b, frames [1].Location.ILOffset);
2523
2524                 Assert.AreEqual (test_method.Name, frames [2].Location.Method.Name);
2525                 Assert.AreEqual (33, frames [2].Location.LineNumber);
2526                 Assert.AreEqual (0x05, frames [2].Location.ILOffset);
2527
2528                 Assert.AreEqual (entry_point.Name, frames [3].Location.Method.Name);
2529                 Assert.AreEqual (14, frames [3].Location.LineNumber);
2530                 Assert.AreEqual (0x00, frames [3].Location.ILOffset);
2531
2532                 vm.Exit (0);
2533
2534                 vm = null;
2535         }
2536
2537         [Test]
2538         public void EventSets () {
2539                 //
2540                 // Create two filter which both match the same exception
2541                 //
2542                 Event e = run_until ("exceptions");
2543
2544                 var req = vm.CreateExceptionRequest (null);
2545                 req.Enable ();
2546
2547                 var req2 = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.OverflowException"));
2548                 req2.Enable ();
2549
2550                 vm.Resume ();
2551
2552                 var es = vm.GetNextEventSet ();
2553                 Assert.AreEqual (2, es.Events.Length);
2554
2555                 e = es [0];
2556                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2557                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2558
2559                 e = es [1];
2560                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2561                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2562
2563                 req.Disable ();
2564                 req2.Disable ();
2565         }
2566
2567         //
2568         // Test single threaded invokes during processing of nullref exceptions.
2569         // These won't work if the exception handling is done from the sigsegv signal
2570         // handler, since the sigsegv signal is disabled until control returns from the
2571         // signal handler.
2572         //
2573         [Test]
2574         [Category ("only3")]
2575         public void NullRefExceptionAndSingleThreadedInvoke () {
2576                 Event e = run_until ("exceptions");
2577                 var req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.NullReferenceException"));
2578                 req.Enable ();
2579
2580                 vm.Resume ();
2581
2582                 e = GetNextEvent ();
2583                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2584                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2585
2586                 var ex = (e as ExceptionEvent).Exception;
2587                 var tostring_method = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2588                 ex.InvokeMethod (e.Thread, tostring_method, null, InvokeOptions.SingleThreaded);
2589         }
2590
2591         [Test]
2592         public void Domains () {
2593                 vm.Detach ();
2594
2595                 Start (new string [] { "dtest-app.exe", "domain-test" });
2596
2597                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
2598
2599                 Event e = run_until ("domains");
2600
2601                 vm.Resume ();
2602                 
2603                 e = GetNextEvent ();
2604                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
2605
2606                 var domain = (e as AppDomainCreateEvent).Domain;
2607
2608                 // Check the object type
2609                 e = run_until ("domains_2");
2610                 var frame = e.Thread.GetFrames ()[0];
2611                 var o = frame.GetArgument (0) as ObjectMirror;
2612                 Assert.AreEqual ("CrossDomain", o.Type.Name);
2613
2614                 // Do a remoting invoke
2615                 var cross_domain_type = o.Type;
2616                 var v = o.InvokeMethod (e.Thread, cross_domain_type.GetMethod ("invoke_3"), null);
2617                 AssertValue (42, v);
2618
2619                 // Run until the callback in the domain
2620                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
2621                 Assert.IsNotNull (m);
2622                 vm.SetBreakpoint (m, 0);
2623
2624                 while (true) {
2625                         vm.Resume ();
2626                         e = GetNextEvent ();
2627                         if (e is BreakpointEvent)
2628                                 break;
2629                 }
2630
2631                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
2632
2633                 // d_method is from another domain
2634                 MethodMirror d_method = (e as BreakpointEvent).Method;
2635                 Assert.IsTrue (m != d_method);
2636
2637                 var frames = e.Thread.GetFrames ();
2638                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
2639                 Assert.AreEqual ("invoke", frames [1].Method.Name);
2640                 Assert.AreEqual ("domains", frames [2].Method.Name);
2641
2642                 // Test breakpoints on already JITted methods in other domains
2643                 m = entry_point.DeclaringType.GetMethod ("invoke_in_domain_2");
2644                 Assert.IsNotNull (m);
2645                 vm.SetBreakpoint (m, 0);
2646
2647                 while (true) {
2648                         vm.Resume ();
2649                         e = GetNextEvent ();
2650                         if (e is BreakpointEvent)
2651                                 break;
2652                 }
2653
2654                 Assert.AreEqual ("invoke_in_domain_2", (e as BreakpointEvent).Method.Name);
2655
2656                 // This is empty when receiving the AppDomainCreateEvent
2657                 Assert.AreEqual ("domain", domain.FriendlyName);
2658
2659                 // Run until the unload
2660                 while (true) {
2661                         vm.Resume ();
2662                         e = GetNextEvent ();
2663                         if (e is AssemblyUnloadEvent) {
2664                                 continue;
2665                         } else {
2666                                 break;
2667                         }
2668                 }
2669                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
2670                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
2671
2672                 // Run past the unload
2673                 e = run_until ("domains_3");
2674
2675                 // Test access to unloaded types
2676                 // FIXME: Add an exception type for this
2677                 AssertThrows<Exception> (delegate {
2678                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
2679                         });
2680         }
2681
2682         [Test]
2683         public void DynamicMethods () {
2684                 Event e = run_until ("dyn_call");
2685
2686                 var m = e.Thread.GetFrames ()[1].Method;
2687                 Assert.AreEqual ("dyn_method", m.Name);
2688
2689                 // Test access to IL
2690                 var body = m.GetMethodBody ();
2691
2692                 ILInstruction ins = body.Instructions [0];
2693                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2694                 Assert.AreEqual ("FOO", ins.Operand);
2695         }
2696
2697         [Test]
2698         public void RefEmit () {
2699                 vm.Detach ();
2700
2701                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
2702
2703                 Event e = run_until ("ref_emit_call");
2704
2705                 var m = e.Thread.GetFrames ()[1].Method;
2706                 Assert.AreEqual ("ref_emit_method", m.Name);
2707
2708                 // Test access to IL
2709                 var body = m.GetMethodBody ();
2710
2711                 ILInstruction ins;
2712
2713                 ins = body.Instructions [0];
2714                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2715                 Assert.AreEqual ("FOO", ins.Operand);
2716
2717                 ins = body.Instructions [1];
2718                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
2719                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
2720                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
2721         }
2722
2723         [Test]
2724         public void IsAttached () {
2725                 var f = entry_point.DeclaringType.GetField ("is_attached");
2726
2727                 Event e = run_until ("Main");
2728
2729                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
2730         }
2731
2732         [Test]
2733         public void StackTraceInNative () {
2734                 // Check that stack traces can be produced for threads in native code
2735                 vm.Detach ();
2736
2737                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
2738
2739                 var e = run_until ("frames_in_native");
2740
2741                 // FIXME: This is racy
2742                 vm.Resume ();
2743
2744                 Thread.Sleep (100);
2745
2746                 vm.Suspend ();
2747
2748                 StackFrame[] frames = e.Thread.GetFrames ();
2749
2750                 int frame_index = -1;
2751                 for (int i = 0; i < frames.Length; ++i) {
2752                         if (frames [i].Method.Name == "Sleep") {
2753                                 frame_index = i;
2754                                 break;
2755                         }
2756                 }
2757
2758                 Assert.IsTrue (frame_index != -1);
2759                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
2760                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
2761                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
2762
2763                 // Check that invokes are disabled for such threads
2764                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
2765
2766                 var m = t.GetMethod ("invoke_static_return_void");
2767                 AssertThrows<InvalidOperationException> (delegate {
2768                                 t.InvokeMethod (e.Thread, m, null);
2769                         });
2770
2771                 // Check that the frame info is invalidated
2772                 run_until ("frames_in_native_2");
2773
2774                 AssertThrows<InvalidStackFrameException> (delegate {
2775                                 Console.WriteLine (frames [frame_index].GetThis ());
2776                         });
2777         }
2778
2779         [Test]
2780         public void VirtualMachine_CreateEnumMirror () {
2781                 var e = run_until ("o1");
2782                 var frame = e.Thread.GetFrames () [0];
2783
2784                 object val = frame.GetThis ();
2785                 Assert.IsTrue (val is ObjectMirror);
2786                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
2787                 ObjectMirror o = (val as ObjectMirror);
2788
2789                 FieldInfoMirror field = o.Type.GetField ("field_enum");
2790                 Value f = o.GetValue (field);
2791                 TypeMirror enumType = (f as EnumMirror).Type;
2792
2793                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
2794                 f = o.GetValue (field);
2795                 Assert.AreEqual (1, (f as EnumMirror).Value);
2796
2797                 // Argument checking
2798                 AssertThrows<ArgumentNullException> (delegate () {
2799                                 vm.CreateEnumMirror (enumType, null);
2800                         });
2801
2802                 AssertThrows<ArgumentNullException> (delegate () {
2803                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
2804                         });
2805
2806                 // null value
2807                 AssertThrows<ArgumentException> (delegate () {
2808                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
2809                         });
2810
2811                 // value of a wrong type
2812                 AssertThrows<ArgumentException> (delegate () {
2813                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
2814                         });
2815         }
2816
2817         [Test]
2818         public void VirtualMachine_EnableEvents_Breakpoint () {
2819                 AssertThrows<ArgumentException> (delegate () {
2820                                 vm.EnableEvents (EventType.Breakpoint);
2821                         });
2822         }
2823
2824         [Test]
2825         public void SingleStepRegress654694 () {
2826                 int il_offset = -1;
2827
2828                 MethodMirror m = entry_point.DeclaringType.GetMethod ("ss_regress_654694");
2829                 foreach (Location l in m.Locations) {
2830                         if (l.ILOffset > 0 && il_offset == -1)
2831                                 il_offset = l.ILOffset;
2832                 }
2833
2834                 Event e = run_until ("ss_regress_654694");
2835
2836                 Assert.IsNotNull (m);
2837                 vm.SetBreakpoint (m, il_offset);
2838
2839                 vm.Resume ();
2840
2841                 e = GetNextEvent ();
2842                 Assert.IsTrue (e is BreakpointEvent);
2843
2844                 var req = vm.CreateStepRequest (e.Thread);
2845                 req.Depth = StepDepth.Over;
2846                 req.Size = StepSize.Line;
2847                 req.Enable ();
2848
2849                 vm.Resume ();
2850
2851                 e = GetNextEvent ();
2852                 Assert.IsTrue (e is StepEvent);
2853
2854                 req.Disable ();
2855         }
2856
2857         [Test]
2858         public void DebugBreak () {
2859                 vm.EnableEvents (EventType.UserBreak);
2860
2861                 run_until ("user");
2862
2863                 vm.Resume ();
2864                 var e = GetNextEvent ();
2865                 Assert.IsTrue (e is UserBreakEvent);
2866         }
2867
2868         [Test]
2869         public void DebugLog () {
2870                 vm.EnableEvents (EventType.UserLog);
2871
2872                 run_until ("user");
2873
2874                 vm.Resume ();
2875                 var e = GetNextEvent ();
2876                 Assert.IsTrue (e is UserLogEvent);
2877                 var le = e as UserLogEvent;
2878
2879                 Assert.AreEqual (5, le.Level);
2880                 Assert.AreEqual ("A", le.Category);
2881                 Assert.AreEqual ("B", le.Message);
2882         }
2883
2884         [Test]
2885         public void TypeGetMethodsByNameFlags () {
2886                 MethodMirror[] mm;
2887                 var assembly = entry_point.DeclaringType.Assembly;
2888                 var type = assembly.GetType ("Tests3");
2889
2890                 Assert.IsNotNull (type);
2891
2892                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Public, false);
2893                 Assert.AreEqual (1, mm.Length, "#1");
2894                 Assert.AreEqual ("M1", mm[0].Name, "#2");
2895
2896                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.NonPublic, false);
2897                 Assert.AreEqual (1, mm.Length, "#3");
2898                 Assert.AreEqual ("M2", mm[0].Name, "#4");
2899
2900                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public, false);
2901                 Assert.AreEqual (7, mm.Length, "#5"); //M3 plus Equals, GetHashCode, GetType, ToString, .ctor
2902
2903                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, false);
2904                 Assert.AreEqual (2, mm.Length, "#7");
2905
2906                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
2907                 Assert.AreEqual (1, mm.Length, "#9");
2908
2909                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
2910                 Assert.AreEqual (5, mm.Length, "#11");
2911
2912                 //Now with name
2913                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static | BindingFlags.Public, false);
2914                 Assert.AreEqual (1, mm.Length, "#12");
2915                 Assert.AreEqual ("M1", mm[0].Name, "#13");
2916
2917                 mm = type.GetMethodsByNameFlags ("m1", BindingFlags.Static | BindingFlags.Public, true);
2918                 Assert.AreEqual (1, mm.Length, "#14");
2919                 Assert.AreEqual ("M1", mm[0].Name, "#15");
2920
2921                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static  | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, false);
2922                 Assert.AreEqual (1, mm.Length, "#16");
2923                 Assert.AreEqual ("M1", mm[0].Name, "#17");
2924         }
2925
2926         [Test]
2927         [Category ("only88")]
2928         public void TypeLoadSourceFileFilter () {
2929                 Event e = run_until ("type_load");
2930
2931                 if (!vm.Version.AtLeast (2, 7))
2932                         return;
2933
2934                 string srcfile = (e as BreakpointEvent).Method.DeclaringType.GetSourceFiles (true)[0];
2935
2936                 var req = vm.CreateTypeLoadRequest ();
2937                 req.SourceFileFilter = new string [] { srcfile.ToUpper () };
2938                 req.Enable ();
2939
2940                 vm.Resume ();
2941                 e = GetNextEvent ();
2942                 Assert.IsTrue (e is TypeLoadEvent);
2943                 Assert.AreEqual ("TypeLoadClass", (e as TypeLoadEvent).Type.FullName);
2944         }
2945
2946         [Test]
2947         public void TypeLoadTypeNameFilter () {
2948                 Event e = run_until ("type_load");
2949
2950                 var req = vm.CreateTypeLoadRequest ();
2951                 req.TypeNameFilter = new string [] { "TypeLoadClass2" };
2952                 req.Enable ();
2953
2954                 vm.Resume ();
2955                 e = GetNextEvent ();
2956                 Assert.IsTrue (e is TypeLoadEvent);
2957                 Assert.AreEqual ("TypeLoadClass2", (e as TypeLoadEvent).Type.FullName);
2958         }
2959
2960         [Test]
2961         public void GetTypesForSourceFile () {
2962                 run_until ("user");
2963
2964                 var types = vm.GetTypesForSourceFile ("dtest-app.cs", false);
2965                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
2966                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
2967
2968                 types = vm.GetTypesForSourceFile ("DTEST-app.cs", true);
2969                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
2970                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
2971         }
2972
2973         [Test]
2974         public void GetTypesNamed () {
2975                 run_until ("user");
2976
2977                 var types = vm.GetTypes ("Tests", false);
2978                 Assert.AreEqual (1, types.Count);
2979                 Assert.AreEqual ("Tests", types [0].FullName);
2980
2981                 types = vm.GetTypes ("System.Exception", false);
2982                 Assert.AreEqual (1, types.Count);
2983                 Assert.AreEqual ("System.Exception", types [0].FullName);
2984         }
2985
2986         [Test]
2987         public void String_GetChars () {
2988                 object val;
2989
2990                 // Reuse this test
2991                 var e = run_until ("arg2");
2992
2993                 var frame = e.Thread.GetFrames () [0];
2994
2995                 val = frame.GetArgument (0);
2996                 Assert.IsTrue (val is StringMirror);
2997                 AssertValue ("FOO", val);
2998                 var s = (val as StringMirror);
2999                 Assert.AreEqual (3, s.Length);
3000
3001                 var c = s.GetChars (0, 2);
3002                 Assert.AreEqual (2, c.Length);
3003                 Assert.AreEqual ('F', c [0]);
3004                 Assert.AreEqual ('O', c [1]);
3005
3006                 AssertThrows<ArgumentException> (delegate () {          
3007                                 s.GetChars (2, 2);
3008                         });
3009         }
3010
3011         [Test]
3012         public void GetInterfaces () {
3013                 var e = run_until ("arg2");
3014
3015                 var frame = e.Thread.GetFrames () [0];
3016
3017                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3018                 var ifaces = cl1.GetInterfaces ();
3019                 Assert.AreEqual (1, ifaces.Length);
3020                 Assert.AreEqual ("ITest", ifaces [0].Name);
3021
3022                 var cl2 = cl1.GetMethod ("Baz").ReturnType;
3023                 var ifaces2 = cl2.GetInterfaces ();
3024                 Assert.AreEqual (1, ifaces2.Length);
3025                 Assert.AreEqual ("ITest`1", ifaces2 [0].Name);
3026         }
3027
3028         [Test]
3029         public void GetInterfaceMap () {
3030                 var e = run_until ("arg2");
3031
3032                 var frame = e.Thread.GetFrames () [0];
3033
3034                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3035                 var iface = cl1.Assembly.GetType ("ITest");
3036                 var map = cl1.GetInterfaceMap (iface);
3037                 Assert.AreEqual (cl1, map.TargetType);
3038                 Assert.AreEqual (iface, map.InterfaceType);
3039                 Assert.AreEqual (2, map.InterfaceMethods.Length);
3040                 Assert.AreEqual (2, map.TargetMethods.Length);
3041         }
3042
3043         [Test]
3044         public void StackAlloc_Breakpoints_Regress2775 () {
3045                 // Check that breakpoints on arm don't overwrite stackalloc-ed memory
3046                 var e = run_until ("regress_2755");
3047
3048                 var frame = e.Thread.GetFrames () [0];
3049                 var m = e.Method;
3050                 // This breaks at the call site
3051                 vm.SetBreakpoint (m, m.Locations [2].ILOffset);
3052
3053                 vm.Resume ();
3054                 var e2 = GetNextEvent ();
3055                 Assert.IsTrue (e2 is BreakpointEvent);
3056
3057                 e = run_until ("regress_2755_3");
3058                 frame = e.Thread.GetFrames () [1];
3059                 var res = frame.GetValue (m.GetLocal ("sum"));
3060                 AssertValue (0, res);
3061         }
3062
3063         [Test]
3064         public void MethodInfo () {
3065                 Event e = run_until ("locals2");
3066
3067                 StackFrame frame = e.Thread.GetFrames () [0];
3068                 var m = frame.Method;
3069
3070                 Assert.IsTrue (m.IsGenericMethod);
3071                 Assert.IsFalse (m.IsGenericMethodDefinition);
3072
3073                 var args = m.GetGenericArguments ();
3074                 Assert.AreEqual (1, args.Length);
3075                 Assert.AreEqual ("String", args [0].Name);
3076
3077                 var gmd = m.GetGenericMethodDefinition ();
3078                 Assert.IsTrue (gmd.IsGenericMethod);
3079                 Assert.IsTrue (gmd.IsGenericMethodDefinition);
3080                 Assert.AreEqual (gmd, gmd.GetGenericMethodDefinition ());
3081
3082                 args = gmd.GetGenericArguments ();
3083                 Assert.AreEqual (1, args.Length);
3084                 Assert.AreEqual ("T", args [0].Name);
3085
3086                 var attrs = m.GetCustomAttributes (true);
3087                 Assert.AreEqual (1, attrs.Length);
3088                 Assert.AreEqual ("StateMachineAttribute", attrs [0].Constructor.DeclaringType.Name);
3089         }
3090
3091         [Test]
3092         public void UnhandledException () {
3093                 vm.Detach ();
3094
3095                 Start (new string [] { "dtest-app.exe", "unhandled-exception" });
3096
3097                 var req = vm.CreateExceptionRequest (null, false, true);
3098                 req.Enable ();
3099
3100                 var e = run_until ("unhandled_exception");
3101                 vm.Resume ();
3102
3103                 var e2 = GetNextEvent ();
3104                 Assert.IsTrue (e2 is ExceptionEvent);
3105
3106                 vm.Exit (0);
3107                 vm = null;
3108         }
3109
3110 #if NET_4_5
3111         [Test]
3112         public void UnhandledExceptionUserCode () {
3113                 vm.Detach ();
3114
3115                 // Exceptions caught in non-user code are treated as unhandled
3116                 Start (new string [] { "dtest-app.exe", "unhandled-exception-user" });
3117
3118                 var req = vm.CreateExceptionRequest (null, false, true);
3119                 req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
3120                 req.Enable ();
3121
3122                 var e = run_until ("unhandled_exception_user");
3123                 vm.Resume ();
3124
3125                 var e2 = GetNextEvent ();
3126                 Assert.IsTrue (e2 is ExceptionEvent);
3127
3128                 vm.Exit (0);
3129                 vm = null;
3130         }
3131 #endif
3132
3133         [Test]
3134         public void GCWhileSuspended () {
3135                 // Check that objects are kept alive during suspensions
3136                 Event e = run_until ("gc_suspend_1");
3137
3138                 MethodMirror m = entry_point.DeclaringType.GetMethod ("gc_suspend_invoke");
3139
3140                 var o = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3141                 //Console.WriteLine (o);
3142
3143                 StackFrame frame = e.Thread.GetFrames () [0];
3144                 TypeMirror t = frame.Method.DeclaringType;
3145                 for (int i = 0; i < 10; ++i)
3146                         t.InvokeMethod (e.Thread, m, new Value [] { });
3147
3148                 // This throws an exception if the object is collected
3149                 long addr = o.Address;
3150
3151                 var o2 = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3152                 Assert.IsNull (o2);
3153         }
3154 }
3155
3156 }