When single stepping from a exception throw site, single step to the catch site....
[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
12 using NUnit.Framework;
13
14 #pragma warning disable 0219
15
16 [TestFixture]
17 public class DebuggerTests
18 {
19         VirtualMachine vm;
20         MethodMirror entry_point;
21         StepEventRequest step_req;
22
23         void AssertThrows<ExType> (Action del) where ExType : Exception {
24                 bool thrown = false;
25
26                 try {
27                         del ();
28                 } catch (ExType) {
29                         thrown = true;
30                 }
31                 Assert.IsTrue (thrown);
32         }
33
34         // No other way to pass arguments to the tests ?
35         public static bool listening = Environment.GetEnvironmentVariable ("DBG_SUSPEND") != null;
36         public static string runtime = Environment.GetEnvironmentVariable ("DBG_RUNTIME");
37         public static string agent_args = Environment.GetEnvironmentVariable ("DBG_AGENT_ARGS");
38
39         void Start (string[] args) {
40                 if (!listening) {
41                         var pi = new Diag.ProcessStartInfo ();
42
43                         if (runtime != null)
44                                 pi.FileName = runtime;
45                         else
46                                 pi.FileName = "mono";
47                         pi.Arguments = String.Join (" ", args);
48                         vm = VirtualMachineManager.Launch (pi, new LaunchOptions { AgentArgs = agent_args });
49                 } else {
50                         Console.WriteLine ("Listening...");
51                         vm = VirtualMachineManager.Listen (new IPEndPoint (IPAddress.Any, 10000));
52                 }
53
54                 vm.EnableEvents (EventType.AssemblyLoad);
55
56                 Event vmstart = vm.GetNextEvent ();
57                 Assert.AreEqual (EventType.VMStart, vmstart.EventType);
58
59                 vm.Resume ();
60
61                 entry_point = null;
62                 step_req = null;
63
64                 Event e;
65
66                 /* Find out the entry point */
67                 while (true) {
68                         e = vm.GetNextEvent ();
69
70                         if (e is AssemblyLoadEvent) {
71                                 AssemblyLoadEvent ae = (AssemblyLoadEvent)e;
72                                 entry_point = ae.Assembly.EntryPoint;
73                                 if (entry_point != null)
74                                         break;
75                         }
76
77                         vm.Resume ();
78                 }
79         }
80
81         BreakpointEvent run_until (string name) {
82                 // String
83                 MethodMirror m = entry_point.DeclaringType.GetMethod (name);
84                 Assert.IsNotNull (m);
85                 vm.SetBreakpoint (m, 0);
86
87                 Event e = null;
88
89                 while (true) {
90                         vm.Resume ();
91                         e = vm.GetNextEvent ();
92                         if (e is BreakpointEvent)
93                                 break;
94                 }
95
96                 Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
97                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
98
99                 return (e as BreakpointEvent);
100         }
101
102         Event single_step (ThreadMirror t) {
103                 var req = vm.CreateStepRequest (t);
104                 req.Enable ();
105
106                 vm.Resume ();
107                 Event e = vm.GetNextEvent ();
108                 Assert.IsTrue (e is StepEvent);
109
110                 req.Disable ();
111
112                 return e;
113         }
114
115         void check_arg_val (StackFrame frame, int pos, Type type, object eval) {
116                 object val = frame.GetArgument (pos);
117                 Assert.IsTrue (val is PrimitiveValue);
118                 object v = (val as PrimitiveValue).Value;
119                 Assert.AreEqual (type, v.GetType ());
120                 if (eval is float)
121                         Assert.IsTrue (Math.Abs ((float)eval - (float)v) < 0.0001);
122                 else if (eval is double)
123                         Assert.IsTrue (Math.Abs ((double)eval - (double)v) < 0.0001);
124                 else
125                         Assert.AreEqual (eval, v);
126         }
127
128         void AssertValue (object expected, object val) {
129                 if (expected is string) {
130                         Assert.IsTrue (val is StringMirror);
131                         Assert.AreEqual (expected, (val as StringMirror).Value);
132                 } else if (val is StructMirror && (val as StructMirror).Type.Name == "IntPtr") {
133                         AssertValue (expected, (val as StructMirror).Fields [0]);
134                 } else {
135                         Assert.IsTrue (val is PrimitiveValue);
136                         Assert.AreEqual (expected, (val as PrimitiveValue).Value);
137                 }
138         }
139
140         [SetUp]
141         public void SetUp () {
142                 Start (new string [] { "dtest-app.exe" });
143         }
144
145         [TearDown]
146         public void TearDown () {
147                 if (vm == null)
148                         return;
149
150                 if (step_req != null)
151                         step_req.Disable ();
152
153                 vm.Resume ();
154                 while (true) {
155                         Event e = vm.GetNextEvent ();
156
157                         if (e is VMDeathEvent)
158                                 break;
159
160                         vm.Resume ();
161                 }
162         }
163
164         [Test]
165         public void SimpleBreakpoint () {
166                 Event e;
167
168                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp1");
169                 Assert.IsNotNull (m);
170
171                 vm.SetBreakpoint (m, 0);
172
173                 vm.Resume ();
174
175                 e = vm.GetNextEvent ();
176                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
177                 Assert.IsTrue (e is BreakpointEvent);
178                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
179
180                 // Argument checking
181                 AssertThrows<ArgumentException> (delegate {
182                                 // Invalid IL offset
183                                 vm.SetBreakpoint (m, 1);
184                         });
185         }
186
187         [Test]
188         public void BreakpointsSameLocation () {
189                 Event e;
190
191                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp2");
192                 Assert.IsNotNull (m);
193
194                 vm.SetBreakpoint (m, 0);
195                 vm.SetBreakpoint (m, 0);
196
197                 vm.Resume ();
198
199                 e = vm.GetNextEvent ();
200                 Assert.IsTrue (e is BreakpointEvent);
201                 Assert.AreEqual (m, (e as BreakpointEvent).Method);
202
203                 e = vm.GetNextEvent ();
204                 Assert.IsTrue (e is BreakpointEvent);
205                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
206         }
207
208         [Test]
209         public void BreakpointAlreadyJITted () {
210                 Event e = run_until ("bp1");
211
212                 /* Place a breakpoint on bp3 */
213                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp3");
214                 Assert.IsNotNull (m);
215                 vm.SetBreakpoint (m, 0);
216
217                 /* Same with generic instances */
218                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp7");
219                 Assert.IsNotNull (m2);
220                 vm.SetBreakpoint (m2, 0);
221
222                 vm.Resume ();
223
224                 e = vm.GetNextEvent ();
225                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
226                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
227
228                 vm.Resume ();
229
230                 /* Non-shared instance */
231                 e = vm.GetNextEvent ();
232                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
233                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
234
235                 vm.Resume ();
236
237                 /* Shared instance */
238                 e = vm.GetNextEvent ();
239                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
240                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
241         }
242
243         [Test]
244         public void ClearBreakpoint () {
245                 Event e;
246
247                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
248                 Assert.IsNotNull (m);
249                 EventRequest req1 = vm.SetBreakpoint (m, 0);
250                 EventRequest req2 = vm.SetBreakpoint (m, 0);
251
252                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
253                 Assert.IsNotNull (m2);
254                 vm.SetBreakpoint (m2, 0);
255
256                 /* Run until bp4 */
257                 vm.Resume ();
258
259                 e = vm.GetNextEvent ();
260                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
261                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
262                 e = vm.GetNextEvent ();
263                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
264                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
265
266                 /* Clear one of them */
267                 req1.Disable ();
268
269                 vm.Resume ();
270
271                 e = vm.GetNextEvent ();
272                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
273                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
274
275                 /* Clear the other */
276                 req2.Disable ();
277
278                 vm.Resume ();
279
280                 e = vm.GetNextEvent ();
281                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
282                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
283         }
284
285         [Test]
286         public void ClearAllBreakpoints () {
287                 Event e;
288
289                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
290                 Assert.IsNotNull (m);
291                 vm.SetBreakpoint (m, 0);
292
293                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
294                 Assert.IsNotNull (m2);
295                 vm.SetBreakpoint (m2, 0);
296
297                 vm.ClearAllBreakpoints ();
298
299                 vm.Resume ();
300
301                 e = vm.GetNextEvent ();
302                 Assert.IsTrue (!(e is BreakpointEvent));
303                 if (e is VMDeathEvent)
304                         vm = null;
305         }
306
307         [Test]
308         public void BreakpointOnGShared () {
309                 Event e;
310
311                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp6");
312                 Assert.IsNotNull (m);
313
314                 vm.SetBreakpoint (m, 0);
315
316                 vm.Resume ();
317
318                 e = vm.GetNextEvent ();
319                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
320                 Assert.IsTrue (e is BreakpointEvent);
321                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
322         }
323
324         [Test]
325         public void SingleStepping () {
326                 Event e = run_until ("single_stepping");
327
328                 var req = vm.CreateStepRequest (e.Thread);
329                 req.Enable ();
330
331                 step_req = req;
332
333                 // Step into ss1
334                 vm.Resume ();
335                 e = vm.GetNextEvent ();
336                 Assert.IsTrue (e is StepEvent);
337                 Assert.AreEqual ("ss1", (e as StepEvent).Method.Name);
338
339                 // Step out of ss1
340                 vm.Resume ();
341                 e = vm.GetNextEvent ();
342                 Assert.IsTrue (e is StepEvent);
343                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
344
345                 // Change to step over
346                 req.Disable ();
347                 req.Depth = StepDepth.Over;
348                 req.Enable ();
349
350                 // Step over ss2
351                 vm.Resume ();
352                 e = vm.GetNextEvent ();
353                 Assert.IsTrue (e is StepEvent);
354                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
355
356                 // Change to step into
357                 req.Disable ();
358                 req.Depth = StepDepth.Into;
359                 req.Enable ();
360
361                 // Step into ss3
362                 vm.Resume ();
363                 e = vm.GetNextEvent ();
364                 Assert.IsTrue (e is StepEvent);
365                 Assert.AreEqual ("ss3", (e as StepEvent).Method.Name);
366
367                 // Change to step out
368                 req.Disable ();
369                 req.Depth = StepDepth.Out;
370                 req.Enable ();
371
372                 // Step back into single_stepping
373                 vm.Resume ();
374                 e = vm.GetNextEvent ();
375                 Assert.IsTrue (e is StepEvent);
376                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
377
378                 // Change to step into
379                 req.Disable ();
380                 req.Depth = StepDepth.Into;
381                 req.Enable ();
382
383                 // Step into ss3_2 ()
384                 vm.Resume ();
385                 e = vm.GetNextEvent ();
386                 Assert.IsTrue (e is StepEvent);
387                 Assert.AreEqual ("ss3_2", (e as StepEvent).Method.Name);
388
389                 // Change to step over
390                 req.Disable ();
391                 req.Depth = StepDepth.Over;
392                 req.Enable ();
393
394                 // Step over ss3_2_2 ()
395                 vm.Resume ();
396                 e = vm.GetNextEvent ();
397                 Assert.IsTrue (e is StepEvent);
398                 Assert.AreEqual ("ss3_2", (e as StepEvent).Method.Name);
399
400                 // Recreate the request
401                 req.Disable ();
402                 req.Enable ();
403
404                 // Step back into single_stepping () with the new request
405                 vm.Resume ();
406                 e = vm.GetNextEvent ();
407                 Assert.IsTrue (e is StepEvent);
408                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
409
410                 // Change to step into
411                 req.Disable ();
412                 req.Depth = StepDepth.Into;
413                 req.Enable ();
414
415                 // Step into ss4 ()
416                 vm.Resume ();
417                 e = vm.GetNextEvent ();
418                 Assert.IsTrue (e is StepEvent);
419                 Assert.AreEqual ("ss4", (e as StepEvent).Method.Name);
420
421                 // Change to StepSize.Line
422                 req.Disable ();
423                 req.Depth = StepDepth.Over;
424                 req.Size = StepSize.Line;
425                 req.Enable ();
426
427                 // Step over ss1 (); ss1 ();
428                 vm.Resume ();
429                 e = vm.GetNextEvent ();
430                 Assert.IsTrue (e is StepEvent);
431
432                 // Step into ss2 ()
433                 req.Disable ();
434                 req.Depth = StepDepth.Into;
435                 req.Enable ();
436
437                 vm.Resume ();
438                 e = vm.GetNextEvent ();
439                 Assert.IsTrue (e is StepEvent);
440                 Assert.AreEqual ("ss2", (e as StepEvent).Method.Name);
441
442                 req.Disable ();
443
444                 // Run until ss5
445                 e = run_until ("ss5");
446
447                 // Add an assembly filter
448                 req.AssemblyFilter = new AssemblyMirror [] { (e as BreakpointEvent).Method.DeclaringType.Assembly };
449                 req.Enable ();
450
451                 // Step into is_even, skipping the linq stuff
452                 vm.Resume ();
453                 e = vm.GetNextEvent ();
454                 Assert.IsTrue (e is StepEvent);
455                 Assert.AreEqual ("is_even", (e as StepEvent).Method.Name);
456
457                 // FIXME: Check that single stepping works with lock (obj)
458                 
459                 req.Disable ();
460
461                 // Run until ss6
462                 e = run_until ("ss6");
463
464                 req = vm.CreateStepRequest (e.Thread);
465                 req.Depth = StepDepth.Over;
466                 req.Enable ();
467
468                 // Check that single stepping works in out-of-line bblocks
469                 vm.Resume ();
470                 e = vm.GetNextEvent ();
471                 Assert.IsTrue (e is StepEvent);
472                 vm.Resume ();
473                 e = vm.GetNextEvent ();
474                 Assert.IsTrue (e is StepEvent);
475                 Assert.AreEqual ("ss6", (e as StepEvent).Method.Name);
476
477                 req.Disable ();
478         }
479
480         [Test]
481         public void MethodEntryExit () {
482                 run_until ("single_stepping");
483
484                 var req1 = vm.CreateMethodEntryRequest ();
485                 var req2 = vm.CreateMethodExitRequest ();
486
487                 req1.Enable ();
488                 req2.Enable ();
489
490                 vm.Resume ();
491                 Event e = vm.GetNextEvent ();
492                 Assert.IsTrue (e is MethodEntryEvent);
493                 Assert.AreEqual ("ss1", (e as MethodEntryEvent).Method.Name);
494
495                 vm.Resume ();
496                 e = vm.GetNextEvent ();
497                 Assert.IsTrue (e is MethodExitEvent);
498                 Assert.AreEqual ("ss1", (e as MethodExitEvent).Method.Name);
499
500                 req1.Disable ();
501                 req2.Disable ();
502         }
503
504         [Test]
505         public void CountFilter () {
506                 run_until ("single_stepping");
507
508                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("ss3");
509                 Assert.IsNotNull (m2);
510                 vm.SetBreakpoint (m2, 0);
511
512                 var req1 = vm.CreateMethodEntryRequest ();
513                 req1.Count = 2;
514                 req1.Enable ();
515
516                 // Enter ss2, ss1 is skipped
517                 vm.Resume ();
518                 Event e = vm.GetNextEvent ();
519                 Assert.IsTrue (e is MethodEntryEvent);
520                 Assert.AreEqual ("ss2", (e as MethodEntryEvent).Method.Name);
521
522                 // Breakpoint on ss3, the entry event is no longer reported
523                 vm.Resume ();
524                 e = vm.GetNextEvent ();
525                 Assert.IsTrue (e is BreakpointEvent);
526
527                 req1.Disable ();
528         }
529
530         [Test]
531         public void Arguments () {
532                 object val;
533
534                 var e = run_until ("arg1");
535
536                 StackFrame frame = e.Thread.GetFrames () [0];
537
538                 check_arg_val (frame, 0, typeof (sbyte), SByte.MaxValue - 5);
539                 check_arg_val (frame, 1, typeof (byte), Byte.MaxValue - 5);
540                 check_arg_val (frame, 2, typeof (bool), true);
541                 check_arg_val (frame, 3, typeof (short), Int16.MaxValue - 5);
542                 check_arg_val (frame, 4, typeof (ushort), UInt16.MaxValue - 5);
543                 check_arg_val (frame, 5, typeof (char), 'F');
544                 check_arg_val (frame, 6, typeof (int), Int32.MaxValue - 5);
545                 check_arg_val (frame, 7, typeof (uint), UInt32.MaxValue - 5);
546                 check_arg_val (frame, 8, typeof (long), Int64.MaxValue - 5);
547                 check_arg_val (frame, 9, typeof (ulong), UInt64.MaxValue - 5);
548                 check_arg_val (frame, 10, typeof (float), 1.2345f);
549                 check_arg_val (frame, 11, typeof (double), 6.78910);
550
551                 e = run_until ("arg2");
552
553                 frame = e.Thread.GetFrames () [0];
554
555                 // String
556                 val = frame.GetArgument (0);
557                 AssertValue ("FOO", val);
558                 Assert.AreEqual ("String", (val as ObjectMirror).Type.Name);
559
560                 // null
561                 val = frame.GetArgument (1);
562                 AssertValue (null, val);
563
564                 // object
565                 val = frame.GetArgument (2);
566                 AssertValue ("BLA", val);
567
568                 // byref
569                 val = frame.GetArgument (3);
570                 AssertValue (42, val);
571
572                 // generic instance
573                 val = frame.GetArgument (4);
574                 Assert.IsTrue (val is ObjectMirror);
575                 Assert.AreEqual ("GClass`1", (val as ObjectMirror).Type.Name);
576
577                 // System.Object
578                 val = frame.GetArgument (5);
579                 Assert.IsTrue (val is ObjectMirror);
580                 Assert.AreEqual ("Object", (val as ObjectMirror).Type.Name);
581
582                 // this on static methods
583                 val = frame.GetThis ();
584                 AssertValue (null, val);
585
586                 e = run_until ("arg3");
587
588                 frame = e.Thread.GetFrames () [0];
589
590                 // this
591                 val = frame.GetThis ();
592                 Assert.IsTrue (val is ObjectMirror);
593                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
594
595                 // objref in register
596                 val = frame.GetArgument (0);
597                 AssertValue ("BLA", val);
598         }
599
600         [Test]
601         public void Arrays () {
602                 object val;
603
604                 var e = run_until ("o2");
605
606                 StackFrame frame = e.Thread.GetFrames () [0];
607
608                 // String[]
609                 val = frame.GetArgument (0);
610                 Assert.IsTrue (val is ArrayMirror);
611                 ArrayMirror arr = val as ArrayMirror;
612                 Assert.AreEqual (2, arr.Length);
613                 AssertValue ("BAR", arr [0]);
614                 AssertValue ("BAZ", arr [1]);
615
616                 var vals = arr.GetValues (0, 2);
617                 Assert.AreEqual (2, vals.Count);
618                 AssertValue ("BAR", vals [0]);
619                 AssertValue ("BAZ", vals [1]);
620
621                 arr [0] = vm.RootDomain.CreateString ("ABC");
622                 AssertValue ("ABC", arr [0]);
623
624                 arr [0] = vm.CreateValue (null);
625                 AssertValue (null, arr [0]);
626
627                 arr.SetValues (0, new Value [] { vm.RootDomain.CreateString ("D1"), vm.RootDomain.CreateString ("D2") });
628                 AssertValue ("D1", arr [0]);
629                 AssertValue ("D2", arr [1]);
630
631                 // int
632                 val = frame.GetArgument (1);
633                 Assert.IsTrue (val is ArrayMirror);
634                 arr = val as ArrayMirror;
635                 Assert.AreEqual (2, arr.Length);
636                 AssertValue (42, arr [0]);
637                 AssertValue (43, arr [1]);
638
639                 // Argument checking
640                 AssertThrows<IndexOutOfRangeException> (delegate () {
641                                 val = arr [2];
642                         });
643
644                 AssertThrows<IndexOutOfRangeException> (delegate () {
645                                 val = arr [Int32.MinValue];
646                         });
647
648                 AssertThrows<IndexOutOfRangeException> (delegate () {
649                                 vals = arr.GetValues (0, 3);
650                         });
651
652                 AssertThrows<IndexOutOfRangeException> (delegate () {
653                                 arr [2] = vm.CreateValue (null);
654                         });
655
656                 AssertThrows<IndexOutOfRangeException> (delegate () {
657                                 arr [Int32.MinValue] = vm.CreateValue (null);
658                         });
659
660                 AssertThrows<IndexOutOfRangeException> (delegate () {
661                                 arr.SetValues (0, new Value [] { null, null, null });
662                         });
663
664                 // Multidim arrays
665                 val = frame.GetArgument (2);
666                 Assert.IsTrue (val is ArrayMirror);
667                 arr = val as ArrayMirror;
668                 Assert.AreEqual (2, arr.Rank);
669                 Assert.AreEqual (4, arr.Length);
670                 Assert.AreEqual (2, arr.GetLength (0));
671                 Assert.AreEqual (2, arr.GetLength (1));
672                 Assert.AreEqual (0, arr.GetLowerBound (0));
673                 Assert.AreEqual (0, arr.GetLowerBound (1));
674                 vals = arr.GetValues (0, 4);
675                 AssertValue (1, vals [0]);
676                 AssertValue (2, vals [1]);
677                 AssertValue (3, vals [2]);
678                 AssertValue (4, vals [3]);
679
680                 val = frame.GetArgument (3);
681                 Assert.IsTrue (val is ArrayMirror);
682                 arr = val as ArrayMirror;
683                 Assert.AreEqual (2, arr.Rank);
684                 Assert.AreEqual (4, arr.Length);
685                 Assert.AreEqual (2, arr.GetLength (0));
686                 Assert.AreEqual (2, arr.GetLength (1));
687                 Assert.AreEqual (1, arr.GetLowerBound (0));
688                 Assert.AreEqual (3, arr.GetLowerBound (1));
689
690                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
691                                 arr.GetLength (-1);
692                         });
693                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
694                                 arr.GetLength (2);
695                         });
696
697                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
698                                 arr.GetLowerBound (-1);
699                         });
700                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
701                                 arr.GetLowerBound (2);
702                         });
703
704                 // arrays treated as generic collections
705                 val = frame.GetArgument (4);
706                 Assert.IsTrue (val is ArrayMirror);
707                 arr = val as ArrayMirror;
708         }
709
710         [Test]
711         public void Object_GetValue () {
712                 var e = run_until ("o1");
713                 var frame = e.Thread.GetFrames () [0];
714
715                 object val = frame.GetThis ();
716                 Assert.IsTrue (val is ObjectMirror);
717                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
718                 ObjectMirror o = (val as ObjectMirror);
719
720                 TypeMirror t = o.Type;
721
722                 // object fields
723                 object f = o.GetValue (t.GetField ("field_i"));
724                 AssertValue (42, f);
725                 f = o.GetValue (t.GetField ("field_s"));
726                 AssertValue ("S", f);
727                 f = o.GetValue (t.GetField ("field_enum"));
728                 Assert.IsTrue (f is EnumMirror);
729                 Assert.AreEqual (1, (f as EnumMirror).Value);
730                 Assert.AreEqual ("B", (f as EnumMirror).StringValue);
731
732                 // Inherited object fields
733                 TypeMirror parent = t.BaseType;
734                 f = o.GetValue (parent.GetField ("base_field_i"));
735                 AssertValue (43, f);
736                 f = o.GetValue (parent.GetField ("base_field_s"));
737                 AssertValue ("T", f);
738
739                 // Static fields
740                 f = o.GetValue (o.Type.GetField ("static_i"));
741                 AssertValue (55, f);
742
743                 // generic instances
744                 ObjectMirror o2 = frame.GetValue (frame.Method.GetParameters ()[1]) as ObjectMirror;
745                 Assert.AreEqual ("GClass`1", o2.Type.Name);
746                 TypeMirror t2 = o2.Type;
747                 f = o2.GetValue (t2.GetField ("field"));
748                 AssertValue (42, f);
749
750                 ObjectMirror o3 = frame.GetValue (frame.Method.GetParameters ()[2]) as ObjectMirror;
751                 Assert.AreEqual ("GClass`1", o3.Type.Name);
752                 TypeMirror t3 = o3.Type;
753                 f = o3.GetValue (t3.GetField ("field"));
754                 AssertValue ("FOO", f);
755
756                 // Argument checking
757                 AssertThrows<ArgumentNullException> (delegate () {
758                         o.GetValue (null);
759                         });
760         }
761
762         [Test]
763         public void Object_GetValues () {
764                 var e = run_until ("o1");
765                 var frame = e.Thread.GetFrames () [0];
766
767                 object val = frame.GetThis ();
768                 Assert.IsTrue (val is ObjectMirror);
769                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
770                 ObjectMirror o = (val as ObjectMirror);
771
772                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
773
774                 TypeMirror t = o.Type;
775
776                 object[] vals = o.GetValues (new FieldInfoMirror [] { t.GetField ("field_i"), t.GetField ("field_s") });
777                 object f = vals [0];
778                 AssertValue (42, f);
779                 f = vals [1];
780                 AssertValue ("S", f);
781
782                 // Argument checking
783                 AssertThrows<ArgumentNullException> (delegate () {
784                         o.GetValues (null);
785                         });
786
787                 AssertThrows<ArgumentNullException> (delegate () {
788                         o.GetValues (new FieldInfoMirror [] { null });
789                         });
790
791                 // field of another class
792                 AssertThrows<ArgumentException> (delegate () {
793                                 o.GetValue (val2.Type.GetField ("field_j"));
794                         });
795         }
796
797         void TestSetValue (ObjectMirror o, string field_name, object val) {
798                 if (val is string)
799                         o.SetValue (o.Type.GetField (field_name), vm.RootDomain.CreateString ((string)val));
800                 else
801                         o.SetValue (o.Type.GetField (field_name), vm.CreateValue (val));
802                 Value f = o.GetValue (o.Type.GetField (field_name));
803                 AssertValue (val, f);
804         }
805
806         [Test]
807         public void Object_SetValues () {
808                 var e = run_until ("o1");
809                 var frame = e.Thread.GetFrames () [0];
810
811                 object val = frame.GetThis ();
812                 Assert.IsTrue (val is ObjectMirror);
813                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
814                 ObjectMirror o = (val as ObjectMirror);
815
816                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
817
818                 TestSetValue (o, "field_i", 22);
819                 TestSetValue (o, "field_bool1", false);
820                 TestSetValue (o, "field_bool2", true);
821                 TestSetValue (o, "field_char", 'B');
822                 TestSetValue (o, "field_byte", (byte)129);
823                 TestSetValue (o, "field_sbyte", (sbyte)-33);
824                 TestSetValue (o, "field_short", (short)(Int16.MaxValue - 5));
825                 TestSetValue (o, "field_ushort", (ushort)(UInt16.MaxValue - 5));
826                 TestSetValue (o, "field_long", Int64.MaxValue - 5);
827                 TestSetValue (o, "field_ulong", (ulong)(UInt64.MaxValue - 5));
828                 TestSetValue (o, "field_float", 6.28f);
829                 TestSetValue (o, "field_double", 6.28);
830                 TestSetValue (o, "static_i", 23);
831                 TestSetValue (o, "field_s", "CDEF");
832
833                 Value f;
834
835                 // intptrs
836                 f = o.GetValue (o.Type.GetField ("field_intptr"));
837                 Assert.IsInstanceOfType (typeof (StructMirror), f);
838                 AssertValue (Int32.MaxValue - 5, (f as StructMirror).Fields [0]);
839
840                 // enums
841
842                 FieldInfoMirror field = o.Type.GetField ("field_enum");
843                 f = o.GetValue (field);
844                 (f as EnumMirror).Value = 5;
845                 o.SetValue (field, f);
846                 f = o.GetValue (field);
847                 Assert.AreEqual (5, (f as EnumMirror).Value);
848
849                 // null
850                 o.SetValue (o.Type.GetField ("field_s"), vm.CreateValue (null));
851                 f = o.GetValue (o.Type.GetField ("field_s"));
852                 AssertValue (null, f);
853
854                 // vtype instances
855                 field = o.Type.GetField ("generic_field_struct");
856                 f = o.GetValue (field);
857                 o.SetValue (field, f);
858
859                 // Argument checking
860                 AssertThrows<ArgumentNullException> (delegate () {
861                                 o.SetValues (null, new Value [0]);
862                         });
863
864                 AssertThrows<ArgumentNullException> (delegate () {
865                                 o.SetValues (new FieldInfoMirror [0], null);
866                         });
867
868                 AssertThrows<ArgumentNullException> (delegate () {
869                                 o.SetValues (new FieldInfoMirror [] { null }, new Value [1] { null });
870                         });
871
872                 // vtype with a wrong type
873                 AssertThrows<ArgumentException> (delegate () {
874                                 o.SetValue (o.Type.GetField ("field_struct"), o.GetValue (o.Type.GetField ("field_enum")));
875                         });
876
877                 // reference type not assignment compatible
878                 AssertThrows<ArgumentException> (delegate () {
879                                 o.SetValue (o.Type.GetField ("field_class"), o);
880                         });
881
882                 // field of another class
883                 AssertThrows<ArgumentException> (delegate () {
884                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
885                         });
886         }
887
888         [Test]
889         public void Type_SetValue () {
890                 var e = run_until ("o1");
891                 var frame = e.Thread.GetFrames () [0];
892                 Value f;
893
894                 object val = frame.GetThis ();
895                 Assert.IsTrue (val is ObjectMirror);
896                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
897                 ObjectMirror o = (val as ObjectMirror);
898
899                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
900
901                 o.Type.SetValue (o.Type.GetField ("static_i"), vm.CreateValue (55));
902                 f = o.Type.GetValue (o.Type.GetField ("static_i"));
903                 AssertValue (55, f);
904
905                 o.Type.SetValue (o.Type.GetField ("static_s"), vm.RootDomain.CreateString ("B"));
906                 f = o.Type.GetValue (o.Type.GetField ("static_s"));
907                 AssertValue ("B", f);
908
909                 // Argument checking
910                 AssertThrows<ArgumentNullException> (delegate () {
911                                 o.Type.SetValue (null, vm.CreateValue (0));
912                         });
913
914                 AssertThrows<ArgumentNullException> (delegate () {
915                                 o.Type.SetValue (o.Type.GetField ("static_i"), null);
916                         });
917
918                 // field of another class
919                 AssertThrows<ArgumentException> (delegate () {
920                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
921                         });
922         }
923
924         [Test]
925         public void TypeInfo () {
926                 Event e = run_until ("ti2");
927                 StackFrame frame = e.Thread.GetFrames () [0];
928
929                 TypeMirror t;
930
931                 // Array types
932                 t = frame.Method.GetParameters ()[0].ParameterType;
933
934                 Assert.AreEqual ("String[]", t.Name);
935                 Assert.AreEqual ("string[]", t.CSharpName);
936                 Assert.AreEqual ("Array", t.BaseType.Name);
937                 Assert.AreEqual (true, t.HasElementType);
938                 Assert.AreEqual (true, t.IsArray);
939                 Assert.AreEqual (1, t.GetArrayRank ());
940                 Assert.AreEqual ("String", t.GetElementType ().Name);
941
942                 t = frame.Method.GetParameters ()[2].ParameterType;
943
944                 Assert.AreEqual ("Int32[,]", t.Name);
945                 // FIXME:
946                 //Assert.AreEqual ("int[,]", t.CSharpName);
947                 Assert.AreEqual ("Array", t.BaseType.Name);
948                 Assert.AreEqual (true, t.HasElementType);
949                 Assert.AreEqual (true, t.IsArray);
950                 Assert.AreEqual (2, t.GetArrayRank ());
951                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
952
953                 // Byref types
954                 t = frame.Method.GetParameters ()[3].ParameterType;
955                 // FIXME:
956                 //Assert.AreEqual ("Int32&", t.Name);
957                 //Assert.AreEqual (true, t.IsByRef);
958                 //Assert.AreEqual (true, t.HasElementType);
959
960                 // Pointer types
961                 t = frame.Method.GetParameters ()[4].ParameterType;
962                 // FIXME:
963                 //Assert.AreEqual ("Int32*", t.Name);
964                 Assert.AreEqual (true, t.IsPointer);
965                 Assert.AreEqual (true, t.HasElementType);
966                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
967                 Assert.AreEqual (false, t.IsPrimitive);
968
969                 // primitive types 
970                 t = frame.Method.GetParameters ()[5].ParameterType;
971                 Assert.AreEqual (true, t.IsPrimitive);
972
973                 // value types
974                 t = frame.Method.GetParameters ()[6].ParameterType;
975                 Assert.AreEqual ("AStruct", t.Name);
976                 Assert.AreEqual (false, t.IsPrimitive);
977                 Assert.AreEqual (true, t.IsValueType);
978                 Assert.AreEqual (false, t.IsClass);
979
980                 // reference types
981                 t = frame.Method.GetParameters ()[7].ParameterType;
982                 Assert.AreEqual ("Tests", t.Name);
983                 var nested = (from nt in t.GetNestedTypes () where nt.IsNestedPublic select nt).ToArray ();
984                 Assert.AreEqual (1, nested.Length);
985                 Assert.AreEqual ("NestedClass", nested [0].Name);
986                 Assert.IsTrue (t.BaseType.IsAssignableFrom (t));
987                 Assert.IsTrue (!t.IsAssignableFrom (t.BaseType));
988
989                 // generic instances
990                 t = frame.Method.GetParameters ()[9].ParameterType;
991                 Assert.AreEqual ("GClass`1", t.Name);
992
993                 // enums
994                 t = frame.Method.GetParameters ()[10].ParameterType;
995                 Assert.AreEqual ("AnEnum", t.Name);
996                 Assert.IsTrue (t.IsEnum);
997                 Assert.AreEqual ("Int32", t.EnumUnderlyingType.Name);
998
999                 // properties
1000                 t = frame.Method.GetParameters ()[7].ParameterType;
1001
1002                 var props = t.GetProperties ();
1003                 Assert.AreEqual (3, props.Length);
1004                 foreach (PropertyInfoMirror prop in props) {
1005                         ParameterInfoMirror[] indexes = prop.GetIndexParameters ();
1006
1007                         if (prop.Name == "IntProperty") {
1008                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1009                                 Assert.AreEqual ("get_IntProperty", prop.GetGetMethod ().Name);
1010                                 Assert.AreEqual ("set_IntProperty", prop.GetSetMethod ().Name);
1011                                 Assert.AreEqual (0, indexes.Length);
1012                         } else if (prop.Name == "ReadOnlyProperty") {
1013                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1014                                 Assert.AreEqual ("get_ReadOnlyProperty", prop.GetGetMethod ().Name);
1015                                 Assert.AreEqual (null, prop.GetSetMethod ());
1016                                 Assert.AreEqual (0, indexes.Length);
1017                         } else if (prop.Name == "IndexedProperty") {
1018                                 Assert.AreEqual (1, indexes.Length);
1019                                 Assert.AreEqual ("Int32", indexes [0].ParameterType.Name);
1020                         }
1021                 }
1022
1023                 // custom attributes
1024                 t = frame.Method.GetParameters ()[8].ParameterType;
1025                 Assert.AreEqual ("Tests2", t.Name);
1026                 var attrs = t.GetCustomAttributes (true);
1027                 Assert.AreEqual (2, attrs.Length);
1028                 foreach (var attr in attrs) {
1029                         if (attr.Constructor.DeclaringType.Name == "DebuggerDisplayAttribute") {
1030                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1031                                 Assert.AreEqual ("Tests", attr.ConstructorArguments [0].Value);
1032                                 Assert.AreEqual (2, attr.NamedArguments.Count);
1033                                 Assert.AreEqual ("Name", attr.NamedArguments [0].Property.Name);
1034                                 Assert.AreEqual ("FOO", attr.NamedArguments [0].TypedValue.Value);
1035                                 Assert.AreEqual ("Target", attr.NamedArguments [1].Property.Name);
1036                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.NamedArguments [1].TypedValue.Value);
1037                                 Assert.AreEqual ("Int32", (attr.NamedArguments [1].TypedValue.Value as TypeMirror).Name);
1038                         } else if (attr.Constructor.DeclaringType.Name == "DebuggerTypeProxyAttribute") {
1039                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1040                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.ConstructorArguments [0].Value);
1041                                 Assert.AreEqual ("Tests", (attr.ConstructorArguments [0].Value as TypeMirror).Name);
1042                         } else {
1043                                 Assert.Fail (attr.Constructor.DeclaringType.Name);
1044                         }
1045                 }
1046         }
1047
1048         [Test]
1049         public void FieldInfo () {
1050                 Event e = run_until ("ti2");
1051                 StackFrame frame = e.Thread.GetFrames () [0];
1052
1053                 TypeMirror t;
1054
1055                 t = frame.Method.GetParameters ()[8].ParameterType;
1056                 Assert.AreEqual ("Tests2", t.Name);
1057
1058                 var fi = t.GetField ("field_j");
1059                 var attrs = fi.GetCustomAttributes (true);
1060                 Assert.AreEqual (1, attrs.Length);
1061                 var attr = attrs [0];
1062                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1063                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1064                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1065                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1066         }
1067
1068         [Test]
1069         public void PropertyInfo () {
1070                 Event e = run_until ("ti2");
1071                 StackFrame frame = e.Thread.GetFrames () [0];
1072
1073                 TypeMirror t;
1074
1075                 t = frame.Method.GetParameters ()[8].ParameterType;
1076                 Assert.AreEqual ("Tests2", t.Name);
1077
1078                 var pi = t.GetProperty ("AProperty");
1079                 var attrs = pi.GetCustomAttributes (true);
1080                 Assert.AreEqual (1, attrs.Length);
1081                 var attr = attrs [0];
1082                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1083                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1084                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1085                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1086         }
1087
1088         [Test]
1089         public void Type_GetValue () {
1090                 Event e = run_until ("o1");
1091                 StackFrame frame = e.Thread.GetFrames () [0];
1092
1093                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1094
1095                 TypeMirror t = o.Type;
1096
1097                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1098
1099                 // static fields
1100                 object f = t.GetValue (o.Type.GetField ("static_i"));
1101                 AssertValue (55, f);
1102
1103                 f = t.GetValue (o.Type.GetField ("static_s"));
1104                 AssertValue ("A", f);
1105
1106                 // literal static fields
1107                 f = t.GetValue (o.Type.GetField ("literal_i"));
1108                 AssertValue (56, f);
1109
1110                 f = t.GetValue (o.Type.GetField ("literal_s"));
1111                 AssertValue ("B", f);
1112
1113                 // Inherited static fields
1114                 TypeMirror parent = t.BaseType;
1115                 f = t.GetValue (parent.GetField ("base_static_i"));
1116                 AssertValue (57, f);
1117
1118                 f = t.GetValue (parent.GetField ("base_static_s"));
1119                 AssertValue ("C", f);
1120
1121                 // Argument checking
1122                 AssertThrows<ArgumentNullException> (delegate () {
1123                         t.GetValue (null);
1124                         });
1125
1126                 // instance fields
1127                 AssertThrows<ArgumentException> (delegate () {
1128                         t.GetValue (o.Type.GetField ("field_i"));
1129                         });
1130
1131                 // field on another type
1132                 AssertThrows<ArgumentException> (delegate () {
1133                                 t.GetValue (val2.Type.GetField ("static_field_j"));
1134                         });
1135
1136                 // special static field
1137                 AssertThrows<ArgumentException> (delegate () {
1138                                 t.GetValue (t.GetField ("tls_i"));
1139                         });
1140         }
1141
1142         [Test]
1143         public void Type_GetValues () {
1144                 Event e = run_until ("o1");
1145                 StackFrame frame = e.Thread.GetFrames () [0];
1146
1147                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1148
1149                 TypeMirror t = o.Type;
1150
1151                 // static fields
1152                 object[] vals = t.GetValues (new FieldInfoMirror [] { t.GetField ("static_i"), t.GetField ("static_s") });
1153                 object f = vals [0];
1154                 AssertValue (55, f);
1155
1156                 f = vals [1];
1157                 AssertValue ("A", f);
1158
1159                 // Argument checking
1160                 AssertThrows<ArgumentNullException> (delegate () {
1161                         t.GetValues (null);
1162                         });
1163
1164                 AssertThrows<ArgumentNullException> (delegate () {
1165                         t.GetValues (new FieldInfoMirror [] { null });
1166                         });
1167         }
1168
1169         [Test]
1170         public void ObjRefs () {
1171                 Event e = run_until ("objrefs1");
1172                 StackFrame frame = e.Thread.GetFrames () [0];
1173
1174                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1175                 ObjectMirror child = o.GetValue (o.Type.GetField ("child")) as ObjectMirror;
1176
1177                 Assert.IsTrue (child.Address > 0);
1178
1179                 // Check that object references are internalized correctly
1180                 Assert.AreEqual (o, frame.GetThis ());
1181
1182                 run_until ("objrefs2");
1183
1184                 // child should be gc'd now
1185                 Assert.IsTrue (child.IsCollected);
1186
1187                 AssertThrows<ObjectCollectedException> (delegate () {
1188                         TypeMirror t = child.Type;
1189                         });
1190
1191                 AssertThrows<ObjectCollectedException> (delegate () {
1192                                 long addr = child.Address;
1193                         });
1194         }
1195
1196         [Test]
1197         public void Type_GetObject () {
1198                 Event e = run_until ("o1");
1199                 StackFrame frame = e.Thread.GetFrames () [0];
1200
1201                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1202
1203                 TypeMirror t = o.Type;
1204
1205                 Assert.AreEqual ("MonoType", t.GetTypeObject ().Type.Name);
1206         }
1207
1208         [Test]
1209         public void VTypes () {
1210                 Event e = run_until ("vtypes1");
1211                 StackFrame frame = e.Thread.GetFrames () [0];
1212
1213                 // vtypes as fields
1214                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1215                 var obj = o.GetValue (o.Type.GetField ("field_struct"));
1216                 Assert.IsTrue (obj is StructMirror);
1217                 var s = obj as StructMirror;
1218                 Assert.AreEqual ("AStruct", s.Type.Name);
1219                 AssertValue (42, s ["i"]);
1220                 obj = s ["s"];
1221                 AssertValue ("S", obj);
1222                 AssertValue (43, s ["k"]);
1223                 obj = o.GetValue (o.Type.GetField ("field_boxed_struct"));
1224                 Assert.IsTrue (obj is StructMirror);
1225                 s = obj as StructMirror;
1226                 Assert.AreEqual ("AStruct", s.Type.Name);
1227                 AssertValue (42, s ["i"]);
1228
1229                 // vtypes as arguments
1230                 s = frame.GetArgument (0) as StructMirror;
1231                 AssertValue (44, s ["i"]);
1232                 obj = s ["s"];
1233                 AssertValue ("T", obj);
1234                 AssertValue (45, s ["k"]);
1235
1236                 // vtypes as array entries
1237                 var arr = frame.GetArgument (1) as ArrayMirror;
1238                 obj = arr [0];
1239                 Assert.IsTrue (obj is StructMirror);
1240                 s = obj as StructMirror;
1241                 AssertValue (1, s ["i"]);
1242                 AssertValue ("S1", s ["s"]);
1243                 obj = arr [1];
1244                 Assert.IsTrue (obj is StructMirror);
1245                 s = obj as StructMirror;
1246                 AssertValue (2, s ["i"]);
1247                 AssertValue ("S2", s ["s"]);
1248
1249                 // Argument checking
1250                 s = frame.GetArgument (0) as StructMirror;
1251                 AssertThrows<ArgumentException> (delegate () {
1252                                 obj = s ["FOO"];
1253                         });
1254
1255                 // generic vtype instances
1256                 o = frame.GetThis () as ObjectMirror;
1257                 obj = o.GetValue (o.Type.GetField ("generic_field_struct"));
1258                 Assert.IsTrue (obj is StructMirror);
1259                 s = obj as StructMirror;
1260                 Assert.AreEqual ("GStruct`1", s.Type.Name);
1261                 AssertValue (42, s ["i"]);
1262
1263                 // this on vtype methods
1264                 e = run_until ("vtypes2");
1265                 
1266                 e = single_step (e.Thread);
1267
1268                 frame = e.Thread.GetFrames () [0];
1269
1270                 Assert.AreEqual ("foo", (e as StepEvent).Method.Name);
1271                 obj = frame.GetThis ();
1272
1273                 Assert.IsTrue (obj is StructMirror);
1274                 s = obj as StructMirror;
1275                 AssertValue (44, s ["i"]);
1276                 AssertValue ("T", s ["s"]);
1277                 AssertValue (45, s ["k"]);
1278
1279                 // this on static vtype methods
1280                 e = run_until ("vtypes3");
1281
1282                 e = single_step (e.Thread);
1283
1284                 frame = e.Thread.GetFrames () [0];
1285
1286                 Assert.AreEqual ("static_foo", (e as StepEvent).Method.Name);
1287                 obj = frame.GetThis ();
1288                 AssertValue (null, obj);
1289         }
1290
1291         [Test]
1292         public void AssemblyInfo () {
1293                 Event e = run_until ("single_stepping");
1294
1295                 StackFrame frame = e.Thread.GetFrames () [0];
1296
1297                 var aname = frame.Method.DeclaringType.Assembly.GetName ();
1298                 Assert.AreEqual ("dtest-app, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", aname.ToString ());
1299
1300                 ModuleMirror m = frame.Method.DeclaringType.Module;
1301
1302                 Assert.AreEqual ("dtest-app.exe", m.Name);
1303                 Assert.AreEqual ("dtest-app.exe", m.ScopeName);
1304                 Assert.IsTrue (m.FullyQualifiedName.IndexOf ("dtest-app.exe") != -1);
1305                 Guid guid = m.ModuleVersionId;
1306                 Assert.AreEqual (frame.Method.DeclaringType.Assembly, m.Assembly);
1307                 Assert.AreEqual (frame.Method.DeclaringType.Assembly.ManifestModule, m);
1308
1309                 Assert.AreEqual ("Assembly", frame.Method.DeclaringType.Assembly.GetAssemblyObject ().Type.Name);
1310
1311                 TypeMirror t = vm.RootDomain.Corlib.GetType ("System.Diagnostics.DebuggerDisplayAttribute");
1312                 Assert.AreEqual ("DebuggerDisplayAttribute", t.Name);
1313         }
1314
1315         [Test]
1316         public void LocalsInfo () {
1317                 Event e = run_until ("locals2");
1318
1319                 StackFrame frame = e.Thread.GetFrames () [0];
1320
1321                 var locals = frame.Method.GetLocals ();
1322                 Assert.AreEqual (6, locals.Length);
1323                 for (int i = 0; i < 6; ++i) {
1324                         if (locals [i].Name == "args") {
1325                                 Assert.IsTrue (locals [i].IsArg);
1326                                 Assert.AreEqual ("String[]", locals [i].Type.Name);
1327                         } else if (locals [i].Name == "arg") {
1328                                 Assert.IsTrue (locals [i].IsArg);
1329                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1330                         } else if (locals [i].Name == "i") {
1331                                 Assert.IsFalse (locals [i].IsArg);
1332                                 Assert.AreEqual ("Int64", locals [i].Type.Name);
1333                         } else if (locals [i].Name == "j") {
1334                                 Assert.IsFalse (locals [i].IsArg);
1335                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1336                         } else if (locals [i].Name == "s") {
1337                                 Assert.IsFalse (locals [i].IsArg);
1338                                 Assert.AreEqual ("String", locals [i].Type.Name);
1339                         } else if (locals [i].Name == "t") {
1340                                 // gshared
1341                                 Assert.IsTrue (locals [i].IsArg);
1342                                 Assert.AreEqual ("String", locals [i].Type.Name);
1343                         } else {
1344                                 Assert.Fail ();
1345                         }
1346                 }
1347         }
1348
1349         [Test]
1350         [Category ("only")]
1351         public void Locals () {
1352                 var be = run_until ("locals1");
1353
1354                 StackFrame frame = be.Thread.GetFrames () [0];
1355
1356                 MethodMirror m1 = frame.Method;
1357
1358                 be = run_until ("locals2");
1359
1360                 frame = be.Thread.GetFrames () [0];
1361
1362                 object val = frame.GetValue (frame.Method.GetLocal ("i"));
1363                 AssertValue (0, val);
1364
1365                 // Execute i = 42
1366                 var req = vm.CreateStepRequest (be.Thread);
1367                 req.Enable ();
1368
1369                 vm.Resume ();
1370                 var e = vm.GetNextEvent ();
1371                 Assert.IsTrue (e is StepEvent);
1372                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1373
1374                 // Execute s = "AB";
1375                 vm.Resume ();
1376                 e = vm.GetNextEvent ();
1377                 Assert.IsTrue (e is StepEvent);
1378                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1379
1380                 frame = e.Thread.GetFrames () [0];
1381
1382                 val = frame.GetValue (frame.Method.GetLocal ("i"));
1383                 AssertValue (42, val);
1384
1385                 LocalVariable[] locals = frame.Method.GetLocals ();
1386                 var vals = frame.GetValues (locals);
1387                 Assert.AreEqual (locals.Length, vals.Length);
1388                 for (int i = 0; i < locals.Length; ++i) {
1389                         if (locals [i].Name == "i")
1390                                 AssertValue (42, vals [i]);
1391                         if (locals [i].Name == "s")
1392                                 AssertValue ("AB", vals [i]);
1393                         if (locals [i].Name == "t")
1394                                 AssertValue ("ABC", vals [i]);
1395                 }
1396
1397                 // Argument checking
1398
1399                 // GetValue () null
1400                 AssertThrows<ArgumentNullException> (delegate () {
1401                                 frame.GetValue ((LocalVariable)null);
1402                         });
1403                 // GetValue () local from another method
1404                 AssertThrows<ArgumentException> (delegate () {
1405                                 frame.GetValue (m1.GetLocal ("foo"));
1406                         });
1407
1408                 // GetValue () null
1409                 AssertThrows<ArgumentNullException> (delegate () {
1410                                 frame.GetValue ((ParameterInfoMirror)null);
1411                         });
1412                 // GetValue () local from another method
1413                 AssertThrows<ArgumentException> (delegate () {
1414                                 frame.GetValue (m1.GetParameters ()[0]);
1415                         });
1416
1417                 // GetValues () null
1418                 AssertThrows<ArgumentNullException> (delegate () {
1419                                 frame.GetValues (null);
1420                         });
1421                 // GetValues () embedded null
1422                 AssertThrows<ArgumentNullException> (delegate () {
1423                                 frame.GetValues (new LocalVariable [] { null });
1424                         });
1425                 // GetValues () local from another method
1426                 AssertThrows<ArgumentException> (delegate () {
1427                                 frame.GetValues (new LocalVariable [] { m1.GetLocal ("foo") });
1428                         });
1429                 // return value
1430                 AssertThrows<ArgumentException> (delegate () {
1431                                 val = frame.GetValue (frame.Method.ReturnParameter);
1432                         });
1433
1434                 // invalid stack frames
1435                 vm.Resume ();
1436                 e = vm.GetNextEvent ();
1437                 Assert.IsTrue (e is StepEvent);
1438                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1439
1440                 AssertThrows<InvalidStackFrameException> (delegate () {
1441                                 frame.GetValue (frame.Method.GetLocal ("i"));
1442                         });
1443
1444                 req.Disable ();
1445         }
1446
1447         [Test]
1448         public void GetVisibleVariables () {
1449                 Event e = run_until ("locals4");
1450
1451                 // First scope
1452                 var locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1453                 Assert.AreEqual (2, locals.Count);
1454                 var loc = locals.First (l => l.Name == "i");
1455                 Assert.AreEqual ("Int64", loc.Type.Name);
1456                 loc = locals.First (l => l.Name == "s");
1457                 Assert.AreEqual ("String", loc.Type.Name);
1458
1459                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1460                 Assert.AreEqual ("i", loc.Name);
1461                 Assert.AreEqual ("Int64", loc.Type.Name);
1462
1463                 e = run_until ("locals5");
1464
1465                 // Second scope
1466                 locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1467                 Assert.AreEqual (2, locals.Count);
1468                 loc = locals.First (l => l.Name == "i");
1469                 Assert.AreEqual ("String", loc.Type.Name);
1470                 loc = locals.First (l => l.Name == "s");
1471                 Assert.AreEqual ("String", loc.Type.Name);
1472
1473                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1474                 Assert.AreEqual ("i", loc.Name);
1475                 Assert.AreEqual ("String", loc.Type.Name);
1476
1477                 // Variable in another scope
1478                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("j");
1479                 Assert.IsNull (loc);
1480         }
1481
1482         [Test]
1483         public void Exit () {
1484                 run_until ("Main");
1485
1486                 vm.Exit (5);
1487
1488                 var e = vm.GetNextEvent ();
1489                 Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
1490
1491                 var p = vm.Process;
1492                 /* Could be a remote vm with no process */
1493                 if (p != null) {
1494                         p.WaitForExit ();
1495                         Assert.AreEqual (5, p.ExitCode);
1496
1497                         // error handling
1498                         AssertThrows<VMDisconnectedException> (delegate () {
1499                                         vm.Resume ();
1500                                 });
1501                 }
1502
1503                 vm = null;
1504         }
1505
1506         [Test]
1507         public void Dispose () {
1508                 run_until ("Main");
1509
1510                 vm.Dispose ();
1511
1512                 var e = vm.GetNextEvent ();
1513                 Assert.IsInstanceOfType (typeof (VMDisconnectEvent), e);
1514
1515                 var p = vm.Process;
1516                 /* Could be a remote vm with no process */
1517                 if (p != null) {
1518                         p.WaitForExit ();
1519                         Assert.AreEqual (3, p.ExitCode);
1520
1521                         // error handling
1522                         AssertThrows<VMDisconnectedException> (delegate () {
1523                                         vm.Resume ();
1524                                 });
1525                 }
1526
1527                 vm = null;
1528         }
1529
1530         [Test]
1531         public void LineNumbers () {
1532                 Event e = run_until ("line_numbers");
1533
1534                 step_req = vm.CreateStepRequest (e.Thread);
1535                 step_req.Depth = StepDepth.Into;
1536                 step_req.Enable ();
1537
1538                 Location l;
1539                 
1540                 vm.Resume ();
1541
1542                 e = vm.GetNextEvent ();
1543                 Assert.IsTrue (e is StepEvent);
1544
1545                 l = e.Thread.GetFrames ()[0].Location;
1546
1547                 Assert.IsTrue (l.SourceFile.IndexOf ("dtest-app.cs") != -1);
1548                 Assert.AreEqual ("ln1", l.Method.Name);
1549                 
1550                 int line_base = l.LineNumber;
1551
1552                 vm.Resume ();
1553                 e = vm.GetNextEvent ();
1554                 Assert.IsTrue (e is StepEvent);
1555                 l = e.Thread.GetFrames ()[0].Location;
1556                 Assert.AreEqual ("ln2", l.Method.Name);
1557                 Assert.AreEqual (line_base + 6, l.LineNumber);
1558
1559                 vm.Resume ();
1560                 e = vm.GetNextEvent ();
1561                 Assert.IsTrue (e is StepEvent);
1562                 l = e.Thread.GetFrames ()[0].Location;
1563                 Assert.AreEqual ("ln1", l.Method.Name);
1564                 Assert.AreEqual (line_base + 1, l.LineNumber);
1565
1566                 vm.Resume ();
1567                 e = vm.GetNextEvent ();
1568                 Assert.IsTrue (e is StepEvent);
1569                 l = e.Thread.GetFrames ()[0].Location;
1570                 Assert.AreEqual ("ln3", l.Method.Name);
1571                 Assert.AreEqual (line_base + 10, l.LineNumber);
1572
1573                 vm.Resume ();
1574                 e = vm.GetNextEvent ();
1575                 Assert.IsTrue (e is StepEvent);
1576                 l = e.Thread.GetFrames ()[0].Location;
1577                 Assert.AreEqual ("ln1", l.Method.Name);
1578                 Assert.AreEqual (line_base + 2, l.LineNumber);
1579
1580                 // GetSourceFiles ()
1581                 string[] sources = l.Method.DeclaringType.GetSourceFiles ();
1582                 Assert.AreEqual (1, sources.Length);
1583                 Assert.AreEqual ("dtest-app.cs", sources [0]);
1584
1585                 sources = l.Method.DeclaringType.GetSourceFiles (true);
1586                 Assert.AreEqual (1, sources.Length);
1587                 Assert.IsTrue (sources [0].EndsWith ("dtest-app.cs"));
1588         }
1589
1590         [Test]
1591         public void Suspend () {
1592                 vm.Dispose ();
1593
1594                 Start (new string [] { "dtest-app.exe", "suspend-test" });
1595
1596                 Event e = run_until ("suspend");
1597
1598                 ThreadMirror main = e.Thread;
1599
1600                 vm.Resume ();
1601
1602                 Thread.Sleep (100);
1603
1604                 vm.Suspend ();
1605
1606                 // The debuggee should be suspended while it is running the infinite loop
1607                 // in suspend ()
1608                 StackFrame frame = main.GetFrames ()[0];
1609                 Assert.AreEqual ("suspend", frame.Method.Name);
1610
1611                 vm.Resume ();
1612
1613                 // resuming when not suspended
1614                 AssertThrows<InvalidOperationException> (delegate () {
1615                                 vm.Resume ();
1616                         });
1617
1618                 vm.Exit (0);
1619
1620                 vm = null;
1621         }
1622
1623         [Test]
1624         public void AssemblyLoad () {
1625                 Event e = run_until ("assembly_load");
1626
1627                 vm.Resume ();
1628
1629                 e = vm.GetNextEvent ();
1630                 Assert.IsInstanceOfType (typeof (AssemblyLoadEvent), e);
1631                 Assert.IsTrue ((e as AssemblyLoadEvent).Assembly.Location.EndsWith ("System.dll"));
1632
1633                 var frames = e.Thread.GetFrames ();
1634                 Assert.IsTrue (frames.Length > 0);
1635                 Assert.AreEqual ("assembly_load", frames [0].Method.Name);
1636         }
1637
1638         [Test]
1639         public void CreateValue () {
1640                 PrimitiveValue v;
1641
1642                 v = vm.CreateValue (1);
1643                 Assert.AreEqual (vm, v.VirtualMachine);
1644                 Assert.AreEqual (1, v.Value);
1645
1646                 v = vm.CreateValue (null);
1647                 Assert.AreEqual (vm, v.VirtualMachine);
1648                 Assert.AreEqual (null, v.Value);
1649
1650                 // Argument checking
1651                 AssertThrows <ArgumentException> (delegate () {
1652                                 v = vm.CreateValue ("FOO");
1653                         });
1654         }
1655
1656         [Test]
1657         public void CreateString () {
1658                 StringMirror s = vm.RootDomain.CreateString ("ABC");
1659
1660                 Assert.AreEqual (vm, s.VirtualMachine);
1661                 Assert.AreEqual ("ABC", s.Value);
1662                 Assert.AreEqual (vm.RootDomain, s.Domain);
1663
1664                 // Long strings
1665                 StringBuilder sb = new StringBuilder ();
1666                 for (int i = 0; i < 1024; ++i)
1667                         sb.Append ('A');
1668                 s = vm.RootDomain.CreateString (sb.ToString ());
1669
1670                 // Argument checking
1671                 AssertThrows <ArgumentNullException> (delegate () {
1672                                 s = vm.RootDomain.CreateString (null);
1673                         });
1674         }
1675
1676         [Test]
1677         public void CreateBoxedValue () {
1678                 ObjectMirror o = vm.RootDomain.CreateBoxedValue (new PrimitiveValue (vm, 42));
1679
1680                 Assert.AreEqual ("Int32", o.Type.Name);
1681                 //AssertValue (42, m.GetValue (o.Type.GetField ("m_value")));
1682
1683                 // Argument checking
1684                 AssertThrows <ArgumentNullException> (delegate () {
1685                                 vm.RootDomain.CreateBoxedValue (null);
1686                         });
1687
1688                 AssertThrows <ArgumentException> (delegate () {
1689                                 vm.RootDomain.CreateBoxedValue (o);
1690                         });
1691         }
1692
1693         [Test]
1694         public void Invoke () {
1695                 Event e = run_until ("invoke1");
1696
1697                 StackFrame frame = e.Thread.GetFrames () [0];
1698
1699                 TypeMirror t = frame.Method.DeclaringType;
1700                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
1701
1702                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
1703
1704                 MethodMirror m;
1705                 Value v;
1706
1707                 // return void
1708                 m = t.GetMethod ("invoke_return_void");
1709                 v = this_obj.InvokeMethod (e.Thread, m, null);
1710                 Assert.IsNull (v);
1711
1712                 // return ref
1713                 m = t.GetMethod ("invoke_return_ref");
1714                 v = this_obj.InvokeMethod (e.Thread, m, null);
1715                 AssertValue ("ABC", v);
1716
1717                 // return null
1718                 m = t.GetMethod ("invoke_return_null");
1719                 v = this_obj.InvokeMethod (e.Thread, m, null);
1720                 AssertValue (null, v);
1721
1722                 // return primitive
1723                 m = t.GetMethod ("invoke_return_primitive");
1724                 v = this_obj.InvokeMethod (e.Thread, m, null);
1725                 AssertValue (42, v);
1726
1727                 // pass primitive
1728                 m = t.GetMethod ("invoke_pass_primitive");
1729                 Value[] args = new Value [] {
1730                         vm.CreateValue ((byte)Byte.MaxValue),
1731                         vm.CreateValue ((sbyte)SByte.MaxValue),
1732                         vm.CreateValue ((short)1),
1733                         vm.CreateValue ((ushort)1),
1734                         vm.CreateValue ((int)1),
1735                         vm.CreateValue ((uint)1),
1736                         vm.CreateValue ((long)1),
1737                         vm.CreateValue ((ulong)1),
1738                         vm.CreateValue ('A'),
1739                         vm.CreateValue (true),
1740                         vm.CreateValue (3.14f),
1741                         vm.CreateValue (3.14) };
1742
1743                 v = this_obj.InvokeMethod (e.Thread, m, args);
1744                 AssertValue ((int)Byte.MaxValue + (int)SByte.MaxValue + 1 + 1 + 1 + 1 + 1 + 1 + 'A' + 1 + 3 + 3, v);
1745
1746                 // pass ref
1747                 m = t.GetMethod ("invoke_pass_ref");
1748                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1749                 AssertValue ("ABC", v);
1750
1751                 // pass null
1752                 m = t.GetMethod ("invoke_pass_ref");
1753                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (null) });
1754                 AssertValue (null, v);
1755
1756                 // static
1757                 m = t.GetMethod ("invoke_static_pass_ref");
1758                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1759                 AssertValue ("ABC", v);
1760
1761                 // static invoked using ObjectMirror.InvokeMethod
1762                 m = t.GetMethod ("invoke_static_pass_ref");
1763                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1764                 AssertValue ("ABC", v);
1765
1766                 // method which throws an exception
1767                 try {
1768                         m = t.GetMethod ("invoke_throws");
1769                         v = this_obj.InvokeMethod (e.Thread, m, null);
1770                         Assert.Fail ();
1771                 } catch (InvocationException ex) {
1772                         Assert.AreEqual ("Exception", ex.Exception.Type.Name);
1773                 }
1774
1775                 // newobj
1776                 m = t.GetMethod (".ctor");
1777                 v = t.InvokeMethod (e.Thread, m, null);
1778                 Assert.IsInstanceOfType (typeof (ObjectMirror), v);
1779                 Assert.AreEqual ("Tests", (v as ObjectMirror).Type.Name);
1780
1781                 // Argument checking
1782                 
1783                 // null thread
1784                 AssertThrows<ArgumentNullException> (delegate {
1785                                 m = t.GetMethod ("invoke_pass_ref");
1786                                 v = this_obj.InvokeMethod (null, m, new Value [] { vm.CreateValue (null) });                            
1787                         });
1788
1789                 // null method
1790                 AssertThrows<ArgumentNullException> (delegate {
1791                                 v = this_obj.InvokeMethod (e.Thread, null, new Value [] { vm.CreateValue (null) });                             
1792                         });
1793
1794                 // invalid number of arguments
1795                 m = t.GetMethod ("invoke_pass_ref");
1796                 AssertThrows<ArgumentException> (delegate {
1797                                 v = this_obj.InvokeMethod (e.Thread, m, null);
1798                         });
1799
1800                 // invalid type of argument (ref != primitive)
1801                 m = t.GetMethod ("invoke_pass_ref");
1802                 AssertThrows<ArgumentException> (delegate {
1803                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
1804                         });
1805
1806                 // invalid type of argument (primitive != primitive)
1807                 m = t.GetMethod ("invoke_pass_primitive_2");
1808                 AssertThrows<ArgumentException> (delegate {
1809                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
1810                         });
1811
1812                 // invoking a non-static method as static
1813                 m = t.GetMethod ("invoke_pass_ref");
1814                 AssertThrows<ArgumentException> (delegate {
1815                                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1816                         });
1817
1818                 // invoking a method defined in another class
1819                 m = t2.GetMethod ("invoke");
1820                 AssertThrows<ArgumentException> (delegate {
1821                                 v = this_obj.InvokeMethod (e.Thread, m, null);
1822                         });
1823         }
1824
1825         [Test]
1826         public void InvokeVType () {
1827                 Event e = run_until ("invoke1");
1828
1829                 StackFrame frame = e.Thread.GetFrames () [0];
1830
1831                 var s = frame.GetArgument (1) as StructMirror;
1832
1833                 TypeMirror t = s.Type;
1834
1835                 MethodMirror m;
1836                 Value v;
1837
1838                 // Pass struct as this, receive int
1839                 m = t.GetMethod ("invoke_return_int");
1840                 v = s.InvokeMethod (e.Thread, m, null);
1841                 AssertValue (42, v);
1842
1843                 // Pass struct as this, receive intptr
1844                 m = t.GetMethod ("invoke_return_intptr");
1845                 v = s.InvokeMethod (e.Thread, m, null);
1846                 AssertValue (43, v);
1847
1848                 // Static method
1849                 m = t.GetMethod ("invoke_static");
1850                 v = t.InvokeMethod (e.Thread, m, null);
1851                 AssertValue (5, v);
1852
1853                 // Pass generic struct as this
1854                 s = frame.GetArgument (2) as StructMirror;
1855                 t = s.Type;
1856                 m = t.GetMethod ("invoke_return_int");
1857                 v = s.InvokeMethod (e.Thread, m, null);
1858                 AssertValue (42, v);
1859         }
1860
1861         [Test]
1862         public void BreakpointDuringInvoke () {
1863                 Event e = run_until ("invoke1");
1864
1865                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
1866                 Assert.IsNotNull (m);
1867                 vm.SetBreakpoint (m, 0);
1868
1869                 StackFrame frame = e.Thread.GetFrames () [0];
1870                 var o = frame.GetThis () as ObjectMirror;
1871
1872                 bool failed = false;
1873
1874                 bool finished = false;
1875                 object wait = new object ();
1876
1877                 // Have to invoke in a separate thread as the invoke is suspended until we
1878                 // resume after the breakpoint
1879                 Thread t = new Thread (delegate () {
1880                                 try {
1881                                         o.InvokeMethod (e.Thread, m, null);
1882                                 } catch {
1883                                         failed = true;
1884                                 }
1885                                 lock (wait) {
1886                                         finished = true;
1887                                         Monitor.Pulse (wait);
1888                                 }
1889                         });
1890
1891                 t.Start ();
1892
1893                 StackFrame invoke_frame = null;
1894
1895                 try {
1896                         e = vm.GetNextEvent ();
1897                         Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
1898                         // Check stack trace support and invokes
1899                         var frames = e.Thread.GetFrames ();
1900                         invoke_frame = frames [0];
1901                         Assert.AreEqual ("invoke2", frames [0].Method.Name);
1902                         Assert.IsTrue (frames [0].IsDebuggerInvoke);
1903                         Assert.AreEqual ("invoke1", frames [1].Method.Name);
1904                 } finally {
1905                         vm.Resume ();
1906                 }
1907
1908                 // Check that the invoke frames are no longer valid
1909                 AssertThrows<InvalidStackFrameException> (delegate {
1910                                 invoke_frame.GetThis ();
1911                         });
1912
1913                 lock (wait) {
1914                         if (!finished)
1915                                 Monitor.Wait (wait);
1916                 }
1917
1918                 // Check InvokeOptions.DisableBreakpoints flag
1919                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
1920         }
1921
1922         [Test]
1923         public void DisabledExceptionDuringInvoke () {
1924                 Event e = run_until ("invoke_ex");
1925
1926                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_ex_inner");
1927
1928                 StackFrame frame = e.Thread.GetFrames () [0];
1929                 var o = frame.GetThis () as ObjectMirror;
1930
1931                 var req = vm.CreateExceptionRequest (null);
1932                 req.Enable ();
1933
1934                 // Check InvokeOptions.DisableBreakpoints flag
1935                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
1936
1937                 req.Disable ();
1938         }
1939
1940         [Test]
1941         public void InvokeSingleThreaded () {
1942                 vm.Dispose ();
1943
1944                 Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
1945
1946                 Event e = run_until ("invoke_single_threaded_2");
1947
1948                 StackFrame f = e.Thread.GetFrames ()[0];
1949
1950                 var obj = f.GetThis () as ObjectMirror;
1951
1952                 // Check that the counter value incremented by the other thread does not increase
1953                 // during the invoke.
1954                 object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
1955
1956                 var m = obj.Type.GetMethod ("invoke_return_void");
1957                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
1958
1959             object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
1960
1961                 Assert.AreEqual ((int)counter1, (int)counter2);
1962
1963                 // Test multiple invokes done in succession
1964                 m = obj.Type.GetMethod ("invoke_return_void");
1965                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
1966
1967                 // Test events during single-threaded invokes
1968                 vm.EnableEvents (EventType.TypeLoad);
1969                 m = obj.Type.GetMethod ("invoke_type_load");
1970                 obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
1971                                 vm.Resume ();
1972                         }, null);
1973
1974                 e = vm.GetNextEvent ();
1975                 Assert.AreEqual (EventType.TypeLoad, e.EventType);
1976         }
1977
1978         [Test]
1979         public void GetThreads () {
1980                 vm.GetThreads ();
1981         }
1982
1983         [Test]
1984         public void Threads () {
1985                 Event e = run_until ("threads");
1986
1987                 Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
1988
1989                 Assert.IsTrue (e.Thread.ThreadId > 0);
1990
1991                 vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
1992
1993                 vm.Resume ();
1994
1995                 e = vm.GetNextEvent ();
1996                 Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
1997                 var state = e.Thread.ThreadState;
1998                 Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
1999
2000                 vm.Resume ();
2001
2002                 e = vm.GetNextEvent ();
2003                 Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
2004                 Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
2005         }
2006
2007         [Test]
2008         [Category ("only")]
2009         public void Frame_SetValue () {
2010                 Event e = run_until ("locals2");
2011
2012                 StackFrame frame = e.Thread.GetFrames () [0];
2013
2014                 // primitive
2015                 var l = frame.Method.GetLocal ("i");
2016                 frame.SetValue (l, vm.CreateValue ((long)55));
2017                 AssertValue (55, frame.GetValue (l));
2018
2019                 // reference
2020                 l = frame.Method.GetLocal ("s");
2021                 frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
2022                 AssertValue ("DEF", frame.GetValue (l));
2023
2024                 // argument as local
2025                 l = frame.Method.GetLocal ("arg");
2026                 frame.SetValue (l, vm.CreateValue (6));
2027                 AssertValue (6, frame.GetValue (l));
2028
2029                 // argument
2030                 var p = frame.Method.GetParameters ()[1];
2031                 frame.SetValue (p, vm.CreateValue (7));
2032                 AssertValue (7, frame.GetValue (p));
2033
2034                 // gshared
2035                 p = frame.Method.GetParameters ()[2];
2036                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF"));
2037                 AssertValue ("DEF", frame.GetValue (p));
2038
2039                 // argument checking
2040
2041                 // variable null
2042                 AssertThrows<ArgumentNullException> (delegate () {
2043                                 frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
2044                         });
2045
2046                 // value null
2047                 AssertThrows<ArgumentNullException> (delegate () {
2048                                 l = frame.Method.GetLocal ("i");
2049                                 frame.SetValue (l, null);
2050                         });
2051
2052                 // value of invalid type
2053                 AssertThrows<ArgumentException> (delegate () {
2054                                 l = frame.Method.GetLocal ("i");
2055                                 frame.SetValue (l, vm.CreateValue (55));
2056                         });
2057         }
2058
2059         [Test]
2060         public void InvokeRegress () {
2061                 Event e = run_until ("invoke1");
2062
2063                 StackFrame frame = e.Thread.GetFrames () [0];
2064
2065                 TypeMirror t = frame.Method.DeclaringType;
2066                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2067
2068                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2069
2070                 MethodMirror m;
2071                 Value v;
2072
2073                 // do an invoke
2074                 m = t.GetMethod ("invoke_return_void");
2075                 v = this_obj.InvokeMethod (e.Thread, m, null);
2076                 Assert.IsNull (v);
2077
2078                 // Check that the stack frames remain valid during the invoke
2079                 Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
2080
2081                 // do another invoke
2082                 m = t.GetMethod ("invoke_return_void");
2083                 v = this_obj.InvokeMethod (e.Thread, m, null);
2084                 Assert.IsNull (v);
2085
2086                 // Try a single step after the invoke
2087                 var req = vm.CreateStepRequest (e.Thread);
2088                 req.Depth = StepDepth.Into;
2089                 req.Size = StepSize.Line;
2090                 req.Enable ();
2091
2092                 step_req = req;
2093
2094                 // Step into invoke2
2095                 vm.Resume ();
2096                 e = vm.GetNextEvent ();
2097                 Assert.IsTrue (e is StepEvent);
2098                 Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
2099
2100                 req.Disable ();
2101
2102                 frame = e.Thread.GetFrames () [0];
2103         }
2104
2105         [Test]
2106         public void Exceptions () {
2107                 Event e = run_until ("exceptions");
2108                 var req = vm.CreateExceptionRequest (null);
2109                 req.Enable ();
2110
2111                 vm.Resume ();
2112
2113                 e = vm.GetNextEvent ();
2114                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2115                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2116
2117                 var frames = e.Thread.GetFrames ();
2118                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2119                 req.Disable ();
2120
2121                 // exception type filter
2122
2123                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
2124                 req.Enable ();
2125
2126                 // Skip the throwing of the second OverflowException       
2127                 vm.Resume ();
2128
2129                 e = vm.GetNextEvent ();
2130                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2131                 Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
2132                 req.Disable ();
2133
2134                 // exception type filter for subclasses
2135                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
2136                 req.Enable ();
2137
2138                 vm.Resume ();
2139
2140                 e = vm.GetNextEvent ();
2141                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2142                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2143                 req.Disable ();
2144
2145                 // Implicit exceptions
2146                 req = vm.CreateExceptionRequest (null);
2147                 req.Enable ();
2148
2149                 vm.Resume ();
2150
2151                 e = vm.GetNextEvent ();
2152                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2153                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2154                 req.Disable ();
2155
2156                 // Single stepping after an exception
2157                 req = vm.CreateExceptionRequest (null);
2158                 req.Enable ();
2159
2160                 vm.Resume ();
2161
2162                 e = vm.GetNextEvent ();
2163                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2164                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
2165                 frames = e.Thread.GetFrames ();
2166                 Assert.AreEqual ("exceptions2", frames [0].Method.Name);
2167                 req.Disable ();
2168
2169                 var sreq = vm.CreateStepRequest (e.Thread);
2170                 sreq.Depth = StepDepth.Over;
2171                 sreq.Size = StepSize.Line;
2172                 sreq.Enable ();
2173
2174                 vm.Resume ();
2175                 e = vm.GetNextEvent ();
2176                 Assert.IsInstanceOfType (typeof (StepEvent), e);
2177                 frames = e.Thread.GetFrames ();
2178                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2179                 sreq.Disable ();
2180
2181                 // Argument checking
2182                 AssertThrows<ArgumentException> (delegate {
2183                                 vm.CreateExceptionRequest (e.Thread.Type);
2184                         });
2185         }
2186
2187         [Test]
2188         public void EventSets () {
2189                 //
2190                 // Create two filter which both match the same exception
2191                 //
2192                 Event e = run_until ("exceptions");
2193
2194                 var req = vm.CreateExceptionRequest (null);
2195                 req.Enable ();
2196
2197                 var req2 = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.OverflowException"));
2198                 req2.Enable ();
2199
2200                 vm.Resume ();
2201
2202                 var es = vm.GetNextEventSet ();
2203                 Assert.AreEqual (2, es.Events.Length);
2204
2205                 e = es [0];
2206                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2207                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2208
2209                 e = es [1];
2210                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2211                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2212
2213                 req.Disable ();
2214                 req2.Disable ();
2215         }
2216
2217         //
2218         // Test single threaded invokes during processing of nullref exceptions.
2219         // These won't work if the exception handling is done from the sigsegv signal
2220         // handler, since the sigsegv signal is disabled until control returns from the
2221         // signal handler.
2222         //
2223         [Test]
2224         [Category ("only3")]
2225         public void NullRefExceptionAndSingleThreadedInvoke () {
2226                 Event e = run_until ("exceptions");
2227                 var req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.NullReferenceException"));
2228                 req.Enable ();
2229
2230                 vm.Resume ();
2231
2232                 e = vm.GetNextEvent ();
2233                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2234                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2235
2236                 var ex = (e as ExceptionEvent).Exception;
2237                 var tostring_method = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2238                 ex.InvokeMethod (e.Thread, tostring_method, null, InvokeOptions.SingleThreaded);
2239         }
2240
2241         [Test]
2242         public void Domains () {
2243                 vm.Dispose ();
2244
2245                 Start (new string [] { "dtest-app.exe", "domain-test" });
2246
2247                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
2248
2249                 Event e = run_until ("domains");
2250
2251                 vm.Resume ();
2252                 
2253                 e = vm.GetNextEvent ();
2254                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
2255
2256                 var domain = (e as AppDomainCreateEvent).Domain;
2257
2258                 // Run until the callback in the domain
2259                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
2260                 Assert.IsNotNull (m);
2261                 vm.SetBreakpoint (m, 0);
2262
2263                 while (true) {
2264                         vm.Resume ();
2265                         e = vm.GetNextEvent ();
2266                         if (e is BreakpointEvent)
2267                                 break;
2268                 }
2269
2270                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
2271
2272                 // d_method is from another domain
2273                 MethodMirror d_method = (e as BreakpointEvent).Method;
2274                 Assert.IsTrue (m != d_method);
2275
2276                 var frames = e.Thread.GetFrames ();
2277                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
2278                 Assert.AreEqual ("invoke", frames [1].Method.Name);
2279                 Assert.AreEqual ("domains", frames [2].Method.Name);
2280
2281                 // Test breakpoints on already JITted methods in other domains
2282                 m = entry_point.DeclaringType.GetMethod ("invoke_in_domain_2");
2283                 Assert.IsNotNull (m);
2284                 vm.SetBreakpoint (m, 0);
2285
2286                 while (true) {
2287                         vm.Resume ();
2288                         e = vm.GetNextEvent ();
2289                         if (e is BreakpointEvent)
2290                                 break;
2291                 }
2292
2293                 Assert.AreEqual ("invoke_in_domain_2", (e as BreakpointEvent).Method.Name);
2294
2295                 // This is empty when receiving the AppDomainCreateEvent
2296                 Assert.AreEqual ("domain", domain.FriendlyName);
2297
2298                 // Run until the unload
2299                 while (true) {
2300                         vm.Resume ();
2301                         e = vm.GetNextEvent ();
2302                         if (e is AssemblyUnloadEvent) {
2303                                 continue;
2304                         } else {
2305                                 break;
2306                         }
2307                 }
2308                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
2309                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
2310
2311                 // Run past the unload
2312                 e = run_until ("domains_2");
2313
2314                 // Test access to unloaded types
2315                 // FIXME: Add an exception type for this
2316                 AssertThrows<Exception> (delegate {
2317                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
2318                         });
2319         }
2320
2321         [Test]
2322         public void DynamicMethods () {
2323                 Event e = run_until ("dyn_call");
2324
2325                 var m = e.Thread.GetFrames ()[1].Method;
2326                 Assert.AreEqual ("dyn_method", m.Name);
2327
2328                 // Test access to IL
2329                 var body = m.GetMethodBody ();
2330
2331                 ILInstruction ins = body.Instructions [0];
2332                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2333                 Assert.AreEqual ("FOO", ins.Operand);
2334         }
2335
2336         [Test]
2337         public void RefEmit () {
2338                 vm.Dispose ();
2339
2340                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
2341
2342                 Event e = run_until ("ref_emit_call");
2343
2344                 var m = e.Thread.GetFrames ()[1].Method;
2345                 Assert.AreEqual ("ref_emit_method", m.Name);
2346
2347                 // Test access to IL
2348                 var body = m.GetMethodBody ();
2349
2350                 ILInstruction ins;
2351
2352                 ins = body.Instructions [0];
2353                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2354                 Assert.AreEqual ("FOO", ins.Operand);
2355
2356                 ins = body.Instructions [1];
2357                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
2358                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
2359                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
2360         }
2361
2362         [Test]
2363         public void IsAttached () {
2364                 var f = entry_point.DeclaringType.GetField ("is_attached");
2365
2366                 Event e = run_until ("Main");
2367
2368                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
2369         }
2370
2371         [Test]
2372         public void StackTraceInNative () {
2373                 // Check that stack traces can be produced for threads in native code
2374                 vm.Dispose ();
2375
2376                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
2377
2378                 var e = run_until ("frames_in_native");
2379
2380                 // FIXME: This is racy
2381                 vm.Resume ();
2382
2383                 Thread.Sleep (100);
2384
2385                 vm.Suspend ();
2386
2387                 StackFrame[] frames = e.Thread.GetFrames ();
2388
2389                 int frame_index = -1;
2390                 for (int i = 0; i < frames.Length; ++i) {
2391                         if (frames [i].Method.Name == "Sleep") {
2392                                 frame_index = i;
2393                                 break;
2394                         }
2395                 }
2396
2397                 Assert.IsTrue (frame_index != -1);
2398                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
2399                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
2400                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
2401
2402                 // Check that invokes are disabled for such threads
2403                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
2404
2405                 // return void
2406                 var m = t.GetMethod ("invoke_static_return_void");
2407                 AssertThrows<InvalidOperationException> (delegate {
2408                                 t.InvokeMethod (e.Thread, m, null);
2409                         });
2410         }
2411
2412         [Test]
2413         public void VirtualMachine_CreateEnumMirror () {
2414                 var e = run_until ("o1");
2415                 var frame = e.Thread.GetFrames () [0];
2416
2417                 object val = frame.GetThis ();
2418                 Assert.IsTrue (val is ObjectMirror);
2419                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
2420                 ObjectMirror o = (val as ObjectMirror);
2421
2422                 FieldInfoMirror field = o.Type.GetField ("field_enum");
2423                 Value f = o.GetValue (field);
2424                 TypeMirror enumType = (f as EnumMirror).Type;
2425
2426                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
2427                 f = o.GetValue (field);
2428                 Assert.AreEqual (1, (f as EnumMirror).Value);
2429
2430                 // Argument checking
2431                 AssertThrows<ArgumentNullException> (delegate () {
2432                                 vm.CreateEnumMirror (enumType, null);
2433                         });
2434
2435                 AssertThrows<ArgumentNullException> (delegate () {
2436                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
2437                         });
2438
2439                 // null value
2440                 AssertThrows<ArgumentException> (delegate () {
2441                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
2442                         });
2443
2444                 // value of a wrong type
2445                 AssertThrows<ArgumentException> (delegate () {
2446                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
2447                         });
2448         }
2449
2450         [Test]
2451         public void VirtualMachine_EnableEvents_Breakpoint () {
2452                 AssertThrows<ArgumentException> (delegate () {
2453                                 vm.EnableEvents (EventType.Breakpoint);
2454                         });
2455         }
2456 }