2010-03-01 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / tests / dtest.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Threading;
4 using System.Net;
5 using System.Reflection;
6 using Mono.Cecil.Cil;
7 using Mono.Debugger.Soft;
8 using Diag = System.Diagnostics;
9 using System.Linq;
10
11 using NUnit.Framework;
12
13 #pragma warning disable 0219
14
15 [TestFixture]
16 public class DebuggerTests
17 {
18         VirtualMachine vm;
19         MethodMirror entry_point;
20         StepEventRequest step_req;
21
22         void AssertThrows<ExType> (Action del) where ExType : Exception {
23                 bool thrown = false;
24
25                 try {
26                         del ();
27                 } catch (ExType) {
28                         thrown = true;
29                 }
30                 Assert.IsTrue (thrown);
31         }
32
33         // No other way to pass arguments to the tests ?
34         public static bool listening = Environment.GetEnvironmentVariable ("DBG_SUSPEND") != null;
35         public static string runtime = Environment.GetEnvironmentVariable ("DBG_RUNTIME");
36         public static string agent_args = Environment.GetEnvironmentVariable ("DBG_AGENT_ARGS");
37
38         void Start (string[] args) {
39                 if (!listening) {
40                         var pi = new Diag.ProcessStartInfo ();
41
42                         if (runtime != null)
43                                 pi.FileName = runtime;
44                         else
45                                 pi.FileName = "mono";
46                         pi.Arguments = String.Join (" ", args);
47                         vm = VirtualMachineManager.Launch (pi, new LaunchOptions { AgentArgs = agent_args });
48                 } else {
49                         Console.WriteLine ("Listening...");
50                         vm = VirtualMachineManager.Listen (new IPEndPoint (IPAddress.Any, 10000));
51                 }
52
53                 vm.EnableEvents (EventType.AssemblyLoad);
54
55                 Event vmstart = vm.GetNextEvent ();
56                 Assert.AreEqual (EventType.VMStart, vmstart.EventType);
57
58                 vm.Resume ();
59
60                 entry_point = null;
61                 step_req = null;
62
63                 Event e;
64
65                 /* Find out the entry point */
66                 while (true) {
67                         e = vm.GetNextEvent ();
68
69                         if (e is AssemblyLoadEvent) {
70                                 AssemblyLoadEvent ae = (AssemblyLoadEvent)e;
71                                 entry_point = ae.Assembly.EntryPoint;
72                                 if (entry_point != null)
73                                         break;
74                         }
75
76                         vm.Resume ();
77                 }
78         }
79
80         BreakpointEvent run_until (string name) {
81                 // String
82                 MethodMirror m = entry_point.DeclaringType.GetMethod (name);
83                 Assert.IsNotNull (m);
84                 vm.SetBreakpoint (m, 0);
85
86                 Event e = null;
87
88                 while (true) {
89                         vm.Resume ();
90                         e = vm.GetNextEvent ();
91                         if (e is BreakpointEvent)
92                                 break;
93                 }
94
95                 Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
96                 Assert.AreEqual (m, (e as BreakpointEvent).Method);
97
98                 return (e as BreakpointEvent);
99         }
100
101         Event single_step (ThreadMirror t) {
102                 var req = vm.CreateStepRequest (t);
103                 req.Enable ();
104
105                 vm.Resume ();
106                 Event e = vm.GetNextEvent ();
107                 Assert.IsTrue (e is StepEvent);
108
109                 req.Disable ();
110
111                 return e;
112         }
113
114         void check_arg_val (StackFrame frame, int pos, Type type, object eval) {
115                 object val = frame.GetArgument (pos);
116                 Assert.IsTrue (val is PrimitiveValue);
117                 object v = (val as PrimitiveValue).Value;
118                 Assert.AreEqual (type, v.GetType ());
119                 if (eval is float)
120                         Assert.IsTrue (Math.Abs ((float)eval - (float)v) < 0.0001);
121                 else if (eval is double)
122                         Assert.IsTrue (Math.Abs ((double)eval - (double)v) < 0.0001);
123                 else
124                         Assert.AreEqual (eval, v);
125         }
126
127         void AssertValue (object expected, object val) {
128                 if (expected is string) {
129                         Assert.IsTrue (val is StringMirror);
130                         Assert.AreEqual (expected, (val as StringMirror).Value);
131                 } else if (val is StructMirror && (val as StructMirror).Type.Name == "IntPtr") {
132                         AssertValue (expected, (val as StructMirror).Fields [0]);
133                 } else {
134                         Assert.IsTrue (val is PrimitiveValue);
135                         Assert.AreEqual (expected, (val as PrimitiveValue).Value);
136                 }
137         }
138
139         [SetUp]
140         public void SetUp () {
141                 Start (new string [] { "dtest-app.exe" });
142         }
143
144         [TearDown]
145         public void TearDown () {
146                 if (vm == null)
147                         return;
148
149                 if (step_req != null)
150                         step_req.Disable ();
151
152                 vm.Resume ();
153                 while (true) {
154                         Event e = vm.GetNextEvent ();
155
156                         if (e is VMDeathEvent)
157                                 break;
158
159                         vm.Resume ();
160                 }
161         }
162
163         [Test]
164         public void SimpleBreakpoint () {
165                 Event e;
166
167                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp1");
168                 Assert.IsNotNull (m);
169
170                 vm.SetBreakpoint (m, 0);
171
172                 vm.Resume ();
173
174                 e = vm.GetNextEvent ();
175                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
176                 Assert.IsTrue (e is BreakpointEvent);
177                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
178
179                 // Argument checking
180                 AssertThrows<ArgumentException> (delegate {
181                                 // Invalid IL offset
182                                 vm.SetBreakpoint (m, 1);
183                         });
184         }
185
186         [Test]
187         public void BreakpointsSameLocation () {
188                 Event e;
189
190                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp2");
191                 Assert.IsNotNull (m);
192
193                 vm.SetBreakpoint (m, 0);
194                 vm.SetBreakpoint (m, 0);
195
196                 vm.Resume ();
197
198                 e = vm.GetNextEvent ();
199                 Assert.IsTrue (e is BreakpointEvent);
200                 Assert.AreEqual (m, (e as BreakpointEvent).Method);
201
202                 e = vm.GetNextEvent ();
203                 Assert.IsTrue (e is BreakpointEvent);
204                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
205         }
206
207         [Test]
208         public void BreakpointAlreadyJITted () {
209                 Event e = run_until ("bp1");
210
211                 /* Place a breakpoint on bp3 */
212                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp3");
213                 Assert.IsNotNull (m);
214                 vm.SetBreakpoint (m, 0);
215
216                 /* Same with generic instances */
217                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp7");
218                 Assert.IsNotNull (m2);
219                 vm.SetBreakpoint (m2, 0);
220
221                 vm.Resume ();
222
223                 e = vm.GetNextEvent ();
224                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
225                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
226
227                 vm.Resume ();
228
229                 /* Non-shared instance */
230                 e = vm.GetNextEvent ();
231                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
232                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
233
234                 vm.Resume ();
235
236                 /* Shared instance */
237                 e = vm.GetNextEvent ();
238                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
239                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
240         }
241
242         [Test]
243         public void ClearBreakpoint () {
244                 Event e;
245
246                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
247                 Assert.IsNotNull (m);
248                 EventRequest req1 = vm.SetBreakpoint (m, 0);
249                 EventRequest req2 = vm.SetBreakpoint (m, 0);
250
251                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
252                 Assert.IsNotNull (m2);
253                 vm.SetBreakpoint (m2, 0);
254
255                 /* Run until bp4 */
256                 vm.Resume ();
257
258                 e = vm.GetNextEvent ();
259                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
260                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
261                 e = vm.GetNextEvent ();
262                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
263                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
264
265                 /* Clear one of them */
266                 req1.Disable ();
267
268                 vm.Resume ();
269
270                 e = vm.GetNextEvent ();
271                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
272                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
273
274                 /* Clear the other */
275                 req2.Disable ();
276
277                 vm.Resume ();
278
279                 e = vm.GetNextEvent ();
280                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
281                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
282         }
283
284         [Test]
285         public void ClearAllBreakpoints () {
286                 Event e;
287
288                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
289                 Assert.IsNotNull (m);
290                 vm.SetBreakpoint (m, 0);
291
292                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
293                 Assert.IsNotNull (m2);
294                 vm.SetBreakpoint (m2, 0);
295
296                 vm.ClearAllBreakpoints ();
297
298                 vm.Resume ();
299
300                 e = vm.GetNextEvent ();
301                 Assert.IsTrue (!(e is BreakpointEvent));
302                 if (e is VMDeathEvent)
303                         vm = null;
304         }
305
306         [Test]
307         public void BreakpointOnGShared () {
308                 Event e;
309
310                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp6");
311                 Assert.IsNotNull (m);
312
313                 vm.SetBreakpoint (m, 0);
314
315                 vm.Resume ();
316
317                 e = vm.GetNextEvent ();
318                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
319                 Assert.IsTrue (e is BreakpointEvent);
320                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
321         }
322
323         [Test]
324         public void SingleStepping () {
325                 Event e = run_until ("single_stepping");
326
327                 var req = vm.CreateStepRequest (e.Thread);
328                 req.Enable ();
329
330                 step_req = req;
331
332                 // Step into ss1
333                 vm.Resume ();
334                 e = vm.GetNextEvent ();
335                 Assert.IsTrue (e is StepEvent);
336                 Assert.AreEqual ("ss1", (e as StepEvent).Method.Name);
337
338                 // Step out of ss1
339                 vm.Resume ();
340                 e = vm.GetNextEvent ();
341                 Assert.IsTrue (e is StepEvent);
342                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
343
344                 // Change to step over
345                 req.Disable ();
346                 req.Depth = StepDepth.Over;
347                 req.Enable ();
348
349                 // Step over ss2
350                 vm.Resume ();
351                 e = vm.GetNextEvent ();
352                 Assert.IsTrue (e is StepEvent);
353                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
354
355                 // Change to step into
356                 req.Disable ();
357                 req.Depth = StepDepth.Into;
358                 req.Enable ();
359
360                 // Step into ss3
361                 vm.Resume ();
362                 e = vm.GetNextEvent ();
363                 Assert.IsTrue (e is StepEvent);
364                 Assert.AreEqual ("ss3", (e as StepEvent).Method.Name);
365
366                 // Change to step out
367                 req.Disable ();
368                 req.Depth = StepDepth.Out;
369                 req.Enable ();
370
371                 // Step back into single_stepping
372                 vm.Resume ();
373                 e = vm.GetNextEvent ();
374                 Assert.IsTrue (e is StepEvent);
375                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
376
377                 // Change to step into
378                 req.Disable ();
379                 req.Depth = StepDepth.Into;
380                 req.Enable ();
381
382                 // Step into ss3_2 ()
383                 vm.Resume ();
384                 e = vm.GetNextEvent ();
385                 Assert.IsTrue (e is StepEvent);
386                 Assert.AreEqual ("ss3_2", (e as StepEvent).Method.Name);
387
388                 // Change to step over
389                 req.Disable ();
390                 req.Depth = StepDepth.Over;
391                 req.Enable ();
392
393                 // Step over ss3_2_2 ()
394                 vm.Resume ();
395                 e = vm.GetNextEvent ();
396                 Assert.IsTrue (e is StepEvent);
397                 Assert.AreEqual ("ss3_2", (e as StepEvent).Method.Name);
398
399                 // Recreate the request
400                 req.Disable ();
401                 req.Enable ();
402
403                 // Step back into single_stepping () with the new request
404                 vm.Resume ();
405                 e = vm.GetNextEvent ();
406                 Assert.IsTrue (e is StepEvent);
407                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
408
409                 // Change to step into
410                 req.Disable ();
411                 req.Depth = StepDepth.Into;
412                 req.Enable ();
413
414                 // Step into ss4 ()
415                 vm.Resume ();
416                 e = vm.GetNextEvent ();
417                 Assert.IsTrue (e is StepEvent);
418                 Assert.AreEqual ("ss4", (e as StepEvent).Method.Name);
419
420                 // Change to StepSize.Line
421                 req.Disable ();
422                 req.Depth = StepDepth.Over;
423                 req.Size = StepSize.Line;
424                 req.Enable ();
425
426                 // Step over ss1 (); ss1 ();
427                 vm.Resume ();
428                 e = vm.GetNextEvent ();
429                 Assert.IsTrue (e is StepEvent);
430
431                 // Step into ss2 ()
432                 req.Disable ();
433                 req.Depth = StepDepth.Into;
434                 req.Enable ();
435
436                 vm.Resume ();
437                 e = vm.GetNextEvent ();
438                 Assert.IsTrue (e is StepEvent);
439                 Assert.AreEqual ("ss2", (e as StepEvent).Method.Name);
440
441                 req.Disable ();
442
443                 // Run until ss5
444                 e = run_until ("ss5");
445
446                 // Add an assembly filter
447                 req.AssemblyFilter = new AssemblyMirror [] { (e as BreakpointEvent).Method.DeclaringType.Assembly };
448                 req.Enable ();
449
450                 // Step into is_even, skipping the linq stuff
451                 vm.Resume ();
452                 e = vm.GetNextEvent ();
453                 Assert.IsTrue (e is StepEvent);
454                 Assert.AreEqual ("is_even", (e as StepEvent).Method.Name);
455
456                 // FIXME: Check that single stepping works with lock (obj)
457                 
458                 req.Disable ();
459
460                 // Run until ss6
461                 e = run_until ("ss6");
462
463                 req = vm.CreateStepRequest (e.Thread);
464                 req.Depth = StepDepth.Over;
465                 req.Enable ();
466
467                 // Check that single stepping works in out-of-line bblocks
468                 vm.Resume ();
469                 e = vm.GetNextEvent ();
470                 Assert.IsTrue (e is StepEvent);
471                 vm.Resume ();
472                 e = vm.GetNextEvent ();
473                 Assert.IsTrue (e is StepEvent);
474                 Assert.AreEqual ("ss6", (e as StepEvent).Method.Name);
475
476                 req.Disable ();
477         }
478
479         [Test]
480         public void MethodEntryExit () {
481                 run_until ("single_stepping");
482
483                 var req1 = vm.CreateMethodEntryRequest ();
484                 var req2 = vm.CreateMethodExitRequest ();
485
486                 req1.Enable ();
487                 req2.Enable ();
488
489                 vm.Resume ();
490                 Event e = vm.GetNextEvent ();
491                 Assert.IsTrue (e is MethodEntryEvent);
492                 Assert.AreEqual ("ss1", (e as MethodEntryEvent).Method.Name);
493
494                 vm.Resume ();
495                 e = vm.GetNextEvent ();
496                 Assert.IsTrue (e is MethodExitEvent);
497                 Assert.AreEqual ("ss1", (e as MethodExitEvent).Method.Name);
498
499                 req1.Disable ();
500                 req2.Disable ();
501         }
502
503         [Test]
504         public void CountFilter () {
505                 run_until ("single_stepping");
506
507                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("ss3");
508                 Assert.IsNotNull (m2);
509                 vm.SetBreakpoint (m2, 0);
510
511                 var req1 = vm.CreateMethodEntryRequest ();
512                 req1.Count = 2;
513                 req1.Enable ();
514
515                 // Enter ss2, ss1 is skipped
516                 vm.Resume ();
517                 Event e = vm.GetNextEvent ();
518                 Assert.IsTrue (e is MethodEntryEvent);
519                 Assert.AreEqual ("ss2", (e as MethodEntryEvent).Method.Name);
520
521                 // Breakpoint on ss3, the entry event is no longer reported
522                 vm.Resume ();
523                 e = vm.GetNextEvent ();
524                 Assert.IsTrue (e is BreakpointEvent);
525
526                 req1.Disable ();
527         }
528
529         [Test]
530         public void Arguments () {
531                 object val;
532
533                 var e = run_until ("arg1");
534
535                 StackFrame frame = e.Thread.GetFrames () [0];
536
537                 check_arg_val (frame, 0, typeof (sbyte), SByte.MaxValue - 5);
538                 check_arg_val (frame, 1, typeof (byte), Byte.MaxValue - 5);
539                 check_arg_val (frame, 2, typeof (bool), true);
540                 check_arg_val (frame, 3, typeof (short), Int16.MaxValue - 5);
541                 check_arg_val (frame, 4, typeof (ushort), UInt16.MaxValue - 5);
542                 check_arg_val (frame, 5, typeof (char), 'F');
543                 check_arg_val (frame, 6, typeof (int), Int32.MaxValue - 5);
544                 check_arg_val (frame, 7, typeof (uint), UInt32.MaxValue - 5);
545                 check_arg_val (frame, 8, typeof (long), Int64.MaxValue - 5);
546                 check_arg_val (frame, 9, typeof (ulong), UInt64.MaxValue - 5);
547                 check_arg_val (frame, 10, typeof (float), 1.2345f);
548                 check_arg_val (frame, 11, typeof (double), 6.78910);
549
550                 e = run_until ("arg2");
551
552                 frame = e.Thread.GetFrames () [0];
553
554                 // String
555                 val = frame.GetArgument (0);
556                 AssertValue ("FOO", val);
557                 Assert.AreEqual ("String", (val as ObjectMirror).Type.Name);
558
559                 // null
560                 val = frame.GetArgument (1);
561                 AssertValue (null, val);
562
563                 // object
564                 val = frame.GetArgument (2);
565                 AssertValue ("BLA", val);
566
567                 // byref
568                 val = frame.GetArgument (3);
569                 AssertValue (42, val);
570
571                 // generic instance
572                 val = frame.GetArgument (4);
573                 Assert.IsTrue (val is ObjectMirror);
574                 Assert.AreEqual ("GClass`1", (val as ObjectMirror).Type.Name);
575
576                 // System.Object
577                 val = frame.GetArgument (5);
578                 Assert.IsTrue (val is ObjectMirror);
579                 Assert.AreEqual ("Object", (val as ObjectMirror).Type.Name);
580
581                 // this on static methods
582                 val = frame.GetThis ();
583                 AssertValue (null, val);
584
585                 e = run_until ("arg3");
586
587                 frame = e.Thread.GetFrames () [0];
588
589                 // this
590                 val = frame.GetThis ();
591                 Assert.IsTrue (val is ObjectMirror);
592                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
593
594                 // objref in register
595                 val = frame.GetArgument (0);
596                 AssertValue ("BLA", val);
597         }
598
599         [Test]
600         public void Arrays () {
601                 object val;
602
603                 var e = run_until ("o2");
604
605                 StackFrame frame = e.Thread.GetFrames () [0];
606
607                 // String[]
608                 val = frame.GetArgument (0);
609                 Assert.IsTrue (val is ArrayMirror);
610                 ArrayMirror arr = val as ArrayMirror;
611                 Assert.AreEqual (2, arr.Length);
612                 AssertValue ("BAR", arr [0]);
613                 AssertValue ("BAZ", arr [1]);
614
615                 var vals = arr.GetValues (0, 2);
616                 Assert.AreEqual (2, vals.Count);
617                 AssertValue ("BAR", vals [0]);
618                 AssertValue ("BAZ", vals [1]);
619
620                 arr [0] = vm.RootDomain.CreateString ("ABC");
621                 AssertValue ("ABC", arr [0]);
622
623                 arr [0] = vm.CreateValue (null);
624                 AssertValue (null, arr [0]);
625
626                 arr.SetValues (0, new Value [] { vm.RootDomain.CreateString ("D1"), vm.RootDomain.CreateString ("D2") });
627                 AssertValue ("D1", arr [0]);
628                 AssertValue ("D2", arr [1]);
629
630                 // int
631                 val = frame.GetArgument (1);
632                 Assert.IsTrue (val is ArrayMirror);
633                 arr = val as ArrayMirror;
634                 Assert.AreEqual (2, arr.Length);
635                 AssertValue (42, arr [0]);
636                 AssertValue (43, arr [1]);
637
638                 // Argument checking
639                 AssertThrows<IndexOutOfRangeException> (delegate () {
640                                 val = arr [2];
641                         });
642
643                 AssertThrows<IndexOutOfRangeException> (delegate () {
644                                 val = arr [Int32.MinValue];
645                         });
646
647                 AssertThrows<IndexOutOfRangeException> (delegate () {
648                                 vals = arr.GetValues (0, 3);
649                         });
650
651                 AssertThrows<IndexOutOfRangeException> (delegate () {
652                                 arr [2] = vm.CreateValue (null);
653                         });
654
655                 AssertThrows<IndexOutOfRangeException> (delegate () {
656                                 arr [Int32.MinValue] = vm.CreateValue (null);
657                         });
658
659                 AssertThrows<IndexOutOfRangeException> (delegate () {
660                                 arr.SetValues (0, new Value [] { null, null, null });
661                         });
662
663                 // Multidim arrays
664                 val = frame.GetArgument (2);
665                 Assert.IsTrue (val is ArrayMirror);
666                 arr = val as ArrayMirror;
667                 Assert.AreEqual (2, arr.Rank);
668                 Assert.AreEqual (4, arr.Length);
669                 Assert.AreEqual (2, arr.GetLength (0));
670                 Assert.AreEqual (2, arr.GetLength (1));
671                 Assert.AreEqual (0, arr.GetLowerBound (0));
672                 Assert.AreEqual (0, arr.GetLowerBound (1));
673                 vals = arr.GetValues (0, 4);
674                 AssertValue (1, vals [0]);
675                 AssertValue (2, vals [1]);
676                 AssertValue (3, vals [2]);
677                 AssertValue (4, vals [3]);
678
679                 val = frame.GetArgument (3);
680                 Assert.IsTrue (val is ArrayMirror);
681                 arr = val as ArrayMirror;
682                 Assert.AreEqual (2, arr.Rank);
683                 Assert.AreEqual (4, arr.Length);
684                 Assert.AreEqual (2, arr.GetLength (0));
685                 Assert.AreEqual (2, arr.GetLength (1));
686                 Assert.AreEqual (1, arr.GetLowerBound (0));
687                 Assert.AreEqual (3, arr.GetLowerBound (1));
688
689                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
690                                 arr.GetLength (-1);
691                         });
692                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
693                                 arr.GetLength (2);
694                         });
695
696                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
697                                 arr.GetLowerBound (-1);
698                         });
699                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
700                                 arr.GetLowerBound (2);
701                         });
702
703                 // arrays treated as generic collections
704                 val = frame.GetArgument (4);
705                 Assert.IsTrue (val is ArrayMirror);
706                 arr = val as ArrayMirror;
707         }
708
709         [Test]
710         public void Object_GetValue () {
711                 var e = run_until ("o1");
712                 var frame = e.Thread.GetFrames () [0];
713
714                 object val = frame.GetThis ();
715                 Assert.IsTrue (val is ObjectMirror);
716                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
717                 ObjectMirror o = (val as ObjectMirror);
718
719                 TypeMirror t = o.Type;
720
721                 // object fields
722                 object f = o.GetValue (t.GetField ("field_i"));
723                 AssertValue (42, f);
724                 f = o.GetValue (t.GetField ("field_s"));
725                 AssertValue ("S", f);
726                 f = o.GetValue (t.GetField ("field_enum"));
727                 Assert.IsTrue (f is EnumMirror);
728                 Assert.AreEqual (1, (f as EnumMirror).Value);
729                 Assert.AreEqual ("B", (f as EnumMirror).StringValue);
730
731                 // Inherited object fields
732                 TypeMirror parent = t.BaseType;
733                 f = o.GetValue (parent.GetField ("base_field_i"));
734                 AssertValue (43, f);
735                 f = o.GetValue (parent.GetField ("base_field_s"));
736                 AssertValue ("T", f);
737
738                 // Static fields
739                 f = o.GetValue (o.Type.GetField ("static_i"));
740                 AssertValue (55, f);
741
742                 // generic instances
743                 ObjectMirror o2 = frame.GetValue (frame.Method.GetParameters ()[1]) as ObjectMirror;
744                 Assert.AreEqual ("GClass`1", o2.Type.Name);
745                 TypeMirror t2 = o2.Type;
746                 f = o2.GetValue (t2.GetField ("field"));
747                 AssertValue (42, f);
748
749                 ObjectMirror o3 = frame.GetValue (frame.Method.GetParameters ()[2]) as ObjectMirror;
750                 Assert.AreEqual ("GClass`1", o3.Type.Name);
751                 TypeMirror t3 = o3.Type;
752                 f = o3.GetValue (t3.GetField ("field"));
753                 AssertValue ("FOO", f);
754
755                 // Argument checking
756                 AssertThrows<ArgumentNullException> (delegate () {
757                         o.GetValue (null);
758                         });
759         }
760
761         [Test]
762         public void Object_GetValues () {
763                 var e = run_until ("o1");
764                 var frame = e.Thread.GetFrames () [0];
765
766                 object val = frame.GetThis ();
767                 Assert.IsTrue (val is ObjectMirror);
768                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
769                 ObjectMirror o = (val as ObjectMirror);
770
771                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
772
773                 TypeMirror t = o.Type;
774
775                 object[] vals = o.GetValues (new FieldInfoMirror [] { t.GetField ("field_i"), t.GetField ("field_s") });
776                 object f = vals [0];
777                 AssertValue (42, f);
778                 f = vals [1];
779                 AssertValue ("S", f);
780
781                 // Argument checking
782                 AssertThrows<ArgumentNullException> (delegate () {
783                         o.GetValues (null);
784                         });
785
786                 AssertThrows<ArgumentNullException> (delegate () {
787                         o.GetValues (new FieldInfoMirror [] { null });
788                         });
789
790                 // field of another class
791                 AssertThrows<ArgumentException> (delegate () {
792                                 o.GetValue (val2.Type.GetField ("field_j"));
793                         });
794         }
795
796         void TestSetValue (ObjectMirror o, string field_name, object val) {
797                 if (val is string)
798                         o.SetValue (o.Type.GetField (field_name), vm.RootDomain.CreateString ((string)val));
799                 else
800                         o.SetValue (o.Type.GetField (field_name), vm.CreateValue (val));
801                 Value f = o.GetValue (o.Type.GetField (field_name));
802                 AssertValue (val, f);
803         }
804
805         [Test]
806         public void Object_SetValues () {
807                 var e = run_until ("o1");
808                 var frame = e.Thread.GetFrames () [0];
809
810                 object val = frame.GetThis ();
811                 Assert.IsTrue (val is ObjectMirror);
812                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
813                 ObjectMirror o = (val as ObjectMirror);
814
815                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
816
817                 TestSetValue (o, "field_i", 22);
818                 TestSetValue (o, "field_bool1", false);
819                 TestSetValue (o, "field_bool2", true);
820                 TestSetValue (o, "field_char", 'B');
821                 TestSetValue (o, "field_byte", (byte)129);
822                 TestSetValue (o, "field_sbyte", (sbyte)-33);
823                 TestSetValue (o, "field_short", (short)(Int16.MaxValue - 5));
824                 TestSetValue (o, "field_ushort", (ushort)(UInt16.MaxValue - 5));
825                 TestSetValue (o, "field_long", Int64.MaxValue - 5);
826                 TestSetValue (o, "field_ulong", (ulong)(UInt64.MaxValue - 5));
827                 TestSetValue (o, "field_float", 6.28f);
828                 TestSetValue (o, "field_double", 6.28);
829                 TestSetValue (o, "static_i", 23);
830                 TestSetValue (o, "field_s", "CDEF");
831
832                 Value f;
833
834                 // intptrs
835                 f = o.GetValue (o.Type.GetField ("field_intptr"));
836                 Assert.IsInstanceOfType (typeof (StructMirror), f);
837                 AssertValue (Int32.MaxValue - 5, (f as StructMirror).Fields [0]);
838
839                 // enums
840
841                 FieldInfoMirror field = o.Type.GetField ("field_enum");
842                 f = o.GetValue (field);
843                 (f as EnumMirror).Value = 5;
844                 o.SetValue (field, f);
845                 f = o.GetValue (field);
846                 Assert.AreEqual (5, (f as EnumMirror).Value);
847
848                 // null
849                 o.SetValue (o.Type.GetField ("field_s"), vm.CreateValue (null));
850                 f = o.GetValue (o.Type.GetField ("field_s"));
851                 AssertValue (null, f);
852
853                 // vtype instances
854                 field = o.Type.GetField ("generic_field_struct");
855                 f = o.GetValue (field);
856                 o.SetValue (field, f);
857
858                 // Argument checking
859                 AssertThrows<ArgumentNullException> (delegate () {
860                                 o.SetValues (null, new Value [0]);
861                         });
862
863                 AssertThrows<ArgumentNullException> (delegate () {
864                                 o.SetValues (new FieldInfoMirror [0], null);
865                         });
866
867                 AssertThrows<ArgumentNullException> (delegate () {
868                                 o.SetValues (new FieldInfoMirror [] { null }, new Value [1] { null });
869                         });
870
871                 // vtype with a wrong type
872                 AssertThrows<ArgumentException> (delegate () {
873                                 o.SetValue (o.Type.GetField ("field_struct"), o.GetValue (o.Type.GetField ("field_enum")));
874                         });
875
876                 // reference type not assignment compatible
877                 AssertThrows<ArgumentException> (delegate () {
878                                 o.SetValue (o.Type.GetField ("field_class"), o);
879                         });
880
881                 // field of another class
882                 AssertThrows<ArgumentException> (delegate () {
883                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
884                         });
885         }
886
887         [Test]
888         [Category ("only")]
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 (5, locals.Length);
1323                 for (int i = 0; i < 5; ++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 {
1340                                 Assert.Fail ();
1341                         }
1342                 }
1343         }
1344
1345         [Test]
1346         public void Locals () {
1347                 var be = run_until ("locals1");
1348
1349                 StackFrame frame = be.Thread.GetFrames () [0];
1350
1351                 MethodMirror m1 = frame.Method;
1352
1353                 be = run_until ("locals2");
1354
1355                 frame = be.Thread.GetFrames () [0];
1356
1357                 object val = frame.GetValue (frame.Method.GetLocal ("i"));
1358                 AssertValue (0, val);
1359
1360                 // Execute i = 42
1361                 var req = vm.CreateStepRequest (be.Thread);
1362                 req.Enable ();
1363
1364                 vm.Resume ();
1365                 var e = vm.GetNextEvent ();
1366                 Assert.IsTrue (e is StepEvent);
1367                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1368
1369                 // Execute s = "AB";
1370                 vm.Resume ();
1371                 e = vm.GetNextEvent ();
1372                 Assert.IsTrue (e is StepEvent);
1373                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1374
1375                 frame = e.Thread.GetFrames () [0];
1376
1377                 val = frame.GetValue (frame.Method.GetLocal ("i"));
1378                 AssertValue (42, val);
1379
1380                 LocalVariable[] locals = frame.Method.GetLocals ();
1381                 var vals = frame.GetValues (locals);
1382                 Assert.AreEqual (locals.Length, vals.Length);
1383                 for (int i = 0; i < locals.Length; ++i) {
1384                         if (locals [i].Name == "i")
1385                                 AssertValue (42, vals [i]);
1386                         if (locals [i].Name == "s")
1387                                 AssertValue ("AB", vals [i]);
1388                 }
1389
1390                 // Argument checking
1391
1392                 // GetValue () null
1393                 AssertThrows<ArgumentNullException> (delegate () {
1394                                 frame.GetValue ((LocalVariable)null);
1395                         });
1396                 // GetValue () local from another method
1397                 AssertThrows<ArgumentException> (delegate () {
1398                                 frame.GetValue (m1.GetLocal ("foo"));
1399                         });
1400
1401                 // GetValue () null
1402                 AssertThrows<ArgumentNullException> (delegate () {
1403                                 frame.GetValue ((ParameterInfoMirror)null);
1404                         });
1405                 // GetValue () local from another method
1406                 AssertThrows<ArgumentException> (delegate () {
1407                                 frame.GetValue (m1.GetParameters ()[0]);
1408                         });
1409
1410                 // GetValues () null
1411                 AssertThrows<ArgumentNullException> (delegate () {
1412                                 frame.GetValues (null);
1413                         });
1414                 // GetValues () embedded null
1415                 AssertThrows<ArgumentNullException> (delegate () {
1416                                 frame.GetValues (new LocalVariable [] { null });
1417                         });
1418                 // GetValues () local from another method
1419                 AssertThrows<ArgumentException> (delegate () {
1420                                 frame.GetValues (new LocalVariable [] { m1.GetLocal ("foo") });
1421                         });
1422                 // return value
1423                 AssertThrows<ArgumentException> (delegate () {
1424                                 val = frame.GetValue (frame.Method.ReturnParameter);
1425                         });
1426
1427                 // invalid stack frames
1428                 vm.Resume ();
1429                 e = vm.GetNextEvent ();
1430                 Assert.IsTrue (e is StepEvent);
1431                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1432
1433                 AssertThrows<InvalidStackFrameException> (delegate () {
1434                                 frame.GetValue (frame.Method.GetLocal ("i"));
1435                         });
1436
1437                 req.Disable ();
1438         }
1439
1440         [Test]
1441         public void Exit () {
1442                 run_until ("Main");
1443
1444                 vm.Exit (5);
1445
1446                 var e = vm.GetNextEvent ();
1447                 Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
1448
1449                 var p = vm.Process;
1450                 /* Could be a remote vm with no process */
1451                 if (p != null) {
1452                         p.WaitForExit ();
1453                         Assert.AreEqual (5, p.ExitCode);
1454
1455                         // error handling
1456                         AssertThrows<VMDisconnectedException> (delegate () {
1457                                         vm.Resume ();
1458                                 });
1459                 }
1460
1461                 vm = null;
1462         }
1463
1464         [Test]
1465         public void Dispose () {
1466                 run_until ("Main");
1467
1468                 vm.Dispose ();
1469
1470                 var e = vm.GetNextEvent ();
1471                 Assert.IsInstanceOfType (typeof (VMDisconnectEvent), e);
1472
1473                 var p = vm.Process;
1474                 /* Could be a remote vm with no process */
1475                 if (p != null) {
1476                         p.WaitForExit ();
1477                         Assert.AreEqual (3, p.ExitCode);
1478
1479                         // error handling
1480                         AssertThrows<VMDisconnectedException> (delegate () {
1481                                         vm.Resume ();
1482                                 });
1483                 }
1484
1485                 vm = null;
1486         }
1487
1488         [Test]
1489         public void LineNumbers () {
1490                 Event e = run_until ("line_numbers");
1491
1492                 step_req = vm.CreateStepRequest (e.Thread);
1493                 step_req.Depth = StepDepth.Into;
1494                 step_req.Enable ();
1495
1496                 Location l;
1497                 
1498                 vm.Resume ();
1499
1500                 e = vm.GetNextEvent ();
1501                 Assert.IsTrue (e is StepEvent);
1502
1503                 l = e.Thread.GetFrames ()[0].Location;
1504
1505                 Assert.IsTrue (l.SourceFile.IndexOf ("dtest-app.cs") != -1);
1506                 Assert.AreEqual ("ln1", l.Method.Name);
1507                 
1508                 int line_base = l.LineNumber;
1509
1510                 vm.Resume ();
1511                 e = vm.GetNextEvent ();
1512                 Assert.IsTrue (e is StepEvent);
1513                 l = e.Thread.GetFrames ()[0].Location;
1514                 Assert.AreEqual ("ln2", l.Method.Name);
1515                 Assert.AreEqual (line_base + 6, l.LineNumber);
1516
1517                 vm.Resume ();
1518                 e = vm.GetNextEvent ();
1519                 Assert.IsTrue (e is StepEvent);
1520                 l = e.Thread.GetFrames ()[0].Location;
1521                 Assert.AreEqual ("ln1", l.Method.Name);
1522                 Assert.AreEqual (line_base + 1, l.LineNumber);
1523
1524                 vm.Resume ();
1525                 e = vm.GetNextEvent ();
1526                 Assert.IsTrue (e is StepEvent);
1527                 l = e.Thread.GetFrames ()[0].Location;
1528                 Assert.AreEqual ("ln3", l.Method.Name);
1529                 Assert.AreEqual (line_base + 10, l.LineNumber);
1530
1531                 vm.Resume ();
1532                 e = vm.GetNextEvent ();
1533                 Assert.IsTrue (e is StepEvent);
1534                 l = e.Thread.GetFrames ()[0].Location;
1535                 Assert.AreEqual ("ln1", l.Method.Name);
1536                 Assert.AreEqual (line_base + 2, l.LineNumber);
1537
1538                 // GetSourceFiles ()
1539                 string[] sources = l.Method.DeclaringType.GetSourceFiles ();
1540                 Assert.AreEqual (1, sources.Length);
1541                 Assert.AreEqual ("dtest-app.cs", sources [0]);
1542         }
1543
1544         [Test]
1545         public void Suspend () {
1546                 vm.Dispose ();
1547
1548                 Start (new string [] { "dtest-app.exe", "suspend-test" });
1549
1550                 Event e = run_until ("suspend");
1551
1552                 ThreadMirror main = e.Thread;
1553
1554                 vm.Resume ();
1555
1556                 Thread.Sleep (100);
1557
1558                 vm.Suspend ();
1559
1560                 // The debuggee should be suspended while it is running the infinite loop
1561                 // in suspend ()
1562                 StackFrame frame = main.GetFrames ()[0];
1563                 Assert.AreEqual ("suspend", frame.Method.Name);
1564
1565                 vm.Resume ();
1566
1567                 // resuming when not suspended
1568                 AssertThrows<InvalidOperationException> (delegate () {
1569                                 vm.Resume ();
1570                         });
1571
1572                 vm.Exit (0);
1573
1574                 vm = null;
1575         }
1576
1577         [Test]
1578         public void AssemblyLoad () {
1579                 Event e = run_until ("assembly_load");
1580
1581                 vm.Resume ();
1582
1583                 e = vm.GetNextEvent ();
1584                 Assert.IsInstanceOfType (typeof (AssemblyLoadEvent), e);
1585                 Assert.IsTrue ((e as AssemblyLoadEvent).Assembly.Location.EndsWith ("System.dll"));
1586
1587                 var frames = e.Thread.GetFrames ();
1588                 Assert.IsTrue (frames.Length > 0);
1589                 Assert.AreEqual ("assembly_load", frames [0].Method.Name);
1590         }
1591
1592         [Test]
1593         public void CreateValue () {
1594                 PrimitiveValue v;
1595
1596                 v = vm.CreateValue (1);
1597                 Assert.AreEqual (vm, v.VirtualMachine);
1598                 Assert.AreEqual (1, v.Value);
1599
1600                 v = vm.CreateValue (null);
1601                 Assert.AreEqual (vm, v.VirtualMachine);
1602                 Assert.AreEqual (null, v.Value);
1603
1604                 // Argument checking
1605                 AssertThrows <ArgumentException> (delegate () {
1606                                 v = vm.CreateValue ("FOO");
1607                         });
1608         }
1609
1610         [Test]
1611         public void CreateString () {
1612                 StringMirror s = vm.RootDomain.CreateString ("ABC");
1613
1614                 Assert.AreEqual (vm, s.VirtualMachine);
1615                 Assert.AreEqual ("ABC", s.Value);
1616                 Assert.AreEqual (vm.RootDomain, s.Domain);
1617
1618                 // Argument checking
1619                 AssertThrows <ArgumentNullException> (delegate () {
1620                                 s = vm.RootDomain.CreateString (null);
1621                         });
1622         }
1623
1624         [Test]
1625         [Category ("only")]
1626         public void CreateBoxedValue () {
1627                 ObjectMirror o = vm.RootDomain.CreateBoxedValue (new PrimitiveValue (vm, 42));
1628
1629                 Assert.AreEqual ("Int32", o.Type.Name);
1630                 //AssertValue (42, m.GetValue (o.Type.GetField ("m_value")));
1631
1632                 // Argument checking
1633                 AssertThrows <ArgumentNullException> (delegate () {
1634                                 vm.RootDomain.CreateBoxedValue (null);
1635                         });
1636
1637                 AssertThrows <ArgumentException> (delegate () {
1638                                 vm.RootDomain.CreateBoxedValue (o);
1639                         });
1640         }
1641
1642         [Test]
1643         public void Invoke () {
1644                 Event e = run_until ("invoke1");
1645
1646                 StackFrame frame = e.Thread.GetFrames () [0];
1647
1648                 TypeMirror t = frame.Method.DeclaringType;
1649                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
1650
1651                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
1652
1653                 MethodMirror m;
1654                 Value v;
1655
1656                 // return void
1657                 m = t.GetMethod ("invoke_return_void");
1658                 v = this_obj.InvokeMethod (e.Thread, m, null);
1659                 Assert.IsNull (v);
1660
1661                 // return ref
1662                 m = t.GetMethod ("invoke_return_ref");
1663                 v = this_obj.InvokeMethod (e.Thread, m, null);
1664                 AssertValue ("ABC", v);
1665
1666                 // return null
1667                 m = t.GetMethod ("invoke_return_null");
1668                 v = this_obj.InvokeMethod (e.Thread, m, null);
1669                 AssertValue (null, v);
1670
1671                 // return primitive
1672                 m = t.GetMethod ("invoke_return_primitive");
1673                 v = this_obj.InvokeMethod (e.Thread, m, null);
1674                 AssertValue (42, v);
1675
1676                 // pass primitive
1677                 m = t.GetMethod ("invoke_pass_primitive");
1678                 Value[] args = new Value [] {
1679                         vm.CreateValue ((byte)Byte.MaxValue),
1680                         vm.CreateValue ((sbyte)SByte.MaxValue),
1681                         vm.CreateValue ((short)1),
1682                         vm.CreateValue ((ushort)1),
1683                         vm.CreateValue ((int)1),
1684                         vm.CreateValue ((uint)1),
1685                         vm.CreateValue ((long)1),
1686                         vm.CreateValue ((ulong)1),
1687                         vm.CreateValue ('A'),
1688                         vm.CreateValue (true),
1689                         vm.CreateValue (3.14f),
1690                         vm.CreateValue (3.14) };
1691
1692                 v = this_obj.InvokeMethod (e.Thread, m, args);
1693                 AssertValue ((int)Byte.MaxValue + (int)SByte.MaxValue + 1 + 1 + 1 + 1 + 1 + 1 + 'A' + 1 + 3 + 3, v);
1694
1695                 // pass ref
1696                 m = t.GetMethod ("invoke_pass_ref");
1697                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1698                 AssertValue ("ABC", v);
1699
1700                 // pass null
1701                 m = t.GetMethod ("invoke_pass_ref");
1702                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (null) });
1703                 AssertValue (null, v);
1704
1705                 // static
1706                 m = t.GetMethod ("invoke_static_pass_ref");
1707                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1708                 AssertValue ("ABC", v);
1709
1710                 // static invoked using ObjectMirror.InvokeMethod
1711                 m = t.GetMethod ("invoke_static_pass_ref");
1712                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1713                 AssertValue ("ABC", v);
1714
1715                 // method which throws an exception
1716                 try {
1717                         m = t.GetMethod ("invoke_throws");
1718                         v = this_obj.InvokeMethod (e.Thread, m, null);
1719                         Assert.Fail ();
1720                 } catch (InvocationException ex) {
1721                         Assert.AreEqual ("Exception", ex.Exception.Type.Name);
1722                 }
1723
1724                 // newobj
1725                 m = t.GetMethod (".ctor");
1726                 v = t.InvokeMethod (e.Thread, m, null);
1727                 Assert.IsInstanceOfType (typeof (ObjectMirror), v);
1728                 Assert.AreEqual ("Tests", (v as ObjectMirror).Type.Name);
1729
1730                 // Argument checking
1731                 
1732                 // null thread
1733                 AssertThrows<ArgumentNullException> (delegate {
1734                                 m = t.GetMethod ("invoke_pass_ref");
1735                                 v = this_obj.InvokeMethod (null, m, new Value [] { vm.CreateValue (null) });                            
1736                         });
1737
1738                 // null method
1739                 AssertThrows<ArgumentNullException> (delegate {
1740                                 v = this_obj.InvokeMethod (e.Thread, null, new Value [] { vm.CreateValue (null) });                             
1741                         });
1742
1743                 // invalid number of arguments
1744                 m = t.GetMethod ("invoke_pass_ref");
1745                 AssertThrows<ArgumentException> (delegate {
1746                                 v = this_obj.InvokeMethod (e.Thread, m, null);
1747                         });
1748
1749                 // invalid type of argument (ref != primitive)
1750                 m = t.GetMethod ("invoke_pass_ref");
1751                 AssertThrows<ArgumentException> (delegate {
1752                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
1753                         });
1754
1755                 // invalid type of argument (primitive != primitive)
1756                 m = t.GetMethod ("invoke_pass_primitive_2");
1757                 AssertThrows<ArgumentException> (delegate {
1758                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
1759                         });
1760
1761                 // invoking a non-static method as static
1762                 m = t.GetMethod ("invoke_pass_ref");
1763                 AssertThrows<ArgumentException> (delegate {
1764                                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1765                         });
1766
1767                 // invoking a method defined in another class
1768                 m = t2.GetMethod ("invoke");
1769                 AssertThrows<ArgumentException> (delegate {
1770                                 v = this_obj.InvokeMethod (e.Thread, m, null);
1771                         });
1772         }
1773
1774         [Test]
1775         public void InvokeVType () {
1776                 Event e = run_until ("invoke1");
1777
1778                 StackFrame frame = e.Thread.GetFrames () [0];
1779
1780                 var s = frame.GetArgument (1) as StructMirror;
1781
1782                 TypeMirror t = s.Type;
1783
1784                 MethodMirror m;
1785                 Value v;
1786
1787                 // Pass struct as this, receive int
1788                 m = t.GetMethod ("invoke_return_int");
1789                 v = s.InvokeMethod (e.Thread, m, null);
1790                 AssertValue (42, v);
1791
1792                 // Pass struct as this, receive intptr
1793                 m = t.GetMethod ("invoke_return_intptr");
1794                 v = s.InvokeMethod (e.Thread, m, null);
1795                 AssertValue (43, v);
1796
1797                 // Static method
1798                 m = t.GetMethod ("invoke_static");
1799                 v = t.InvokeMethod (e.Thread, m, null);
1800                 AssertValue (5, v);
1801         }
1802
1803         [Test]
1804         public void BreakpointDuringInvoke () {
1805                 Event e = run_until ("invoke1");
1806
1807                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
1808                 Assert.IsNotNull (m);
1809                 vm.SetBreakpoint (m, 0);
1810
1811                 StackFrame frame = e.Thread.GetFrames () [0];
1812                 var o = frame.GetThis () as ObjectMirror;
1813
1814                 bool failed = false;
1815
1816                 bool finished = false;
1817                 object wait = new object ();
1818
1819                 // Have to invoke in a separate thread as the invoke is suspended until we
1820                 // resume after the breakpoint
1821                 Thread t = new Thread (delegate () {
1822                                 try {
1823                                         o.InvokeMethod (e.Thread, m, null);
1824                                 } catch {
1825                                         failed = true;
1826                                 }
1827                                 lock (wait) {
1828                                         finished = true;
1829                                         Monitor.Pulse (wait);
1830                                 }
1831                         });
1832
1833                 t.Start ();
1834
1835                 StackFrame invoke_frame = null;
1836
1837                 try {
1838                         e = vm.GetNextEvent ();
1839                         Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
1840                         // Check stack trace support and invokes
1841                         var frames = e.Thread.GetFrames ();
1842                         invoke_frame = frames [0];
1843                         Assert.AreEqual ("invoke2", frames [0].Method.Name);
1844                         Assert.IsTrue (frames [0].IsDebuggerInvoke);
1845                         Assert.AreEqual ("invoke1", frames [1].Method.Name);
1846                 } finally {
1847                         vm.Resume ();
1848                 }
1849
1850                 // Check that the invoke frames are no longer valid
1851                 AssertThrows<InvalidStackFrameException> (delegate {
1852                                 invoke_frame.GetThis ();
1853                         });
1854
1855                 lock (wait) {
1856                         if (!finished)
1857                                 Monitor.Wait (wait);
1858                 }
1859
1860                 // Check InvokeOptions.DisableBreakpoints flag
1861                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
1862         }
1863
1864         [Test]
1865         public void InvokeSingleThreaded () {
1866                 vm.Dispose ();
1867
1868                 Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
1869
1870                 Event e = run_until ("invoke_single_threaded_2");
1871
1872                 StackFrame f = e.Thread.GetFrames ()[0];
1873
1874                 var obj = f.GetThis () as ObjectMirror;
1875
1876                 // Check that the counter value incremented by the other thread does not increase
1877                 // during the invoke.
1878                 object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
1879
1880                 var m = obj.Type.GetMethod ("invoke_return_void");
1881                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
1882
1883             object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
1884
1885                 Assert.AreEqual ((int)counter1, (int)counter2);
1886
1887                 // Test multiple invokes done in succession
1888                 m = obj.Type.GetMethod ("invoke_return_void");
1889                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
1890
1891                 // Test events during single-threaded invokes
1892                 vm.EnableEvents (EventType.TypeLoad);
1893                 m = obj.Type.GetMethod ("invoke_type_load");
1894                 obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
1895                                 vm.Resume ();
1896                         }, null);
1897
1898                 e = vm.GetNextEvent ();
1899                 Assert.AreEqual (EventType.TypeLoad, e.EventType);
1900         }
1901
1902         [Test]
1903         public void GetThreads () {
1904                 vm.GetThreads ();
1905         }
1906
1907         [Test]
1908         public void Threads () {
1909                 Event e = run_until ("threads");
1910
1911                 Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
1912
1913                 vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
1914
1915                 vm.Resume ();
1916
1917                 e = vm.GetNextEvent ();
1918                 Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
1919                 var state = e.Thread.ThreadState;
1920                 Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
1921
1922                 vm.Resume ();
1923
1924                 e = vm.GetNextEvent ();
1925                 Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
1926                 Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
1927         }
1928
1929         [Test]
1930         public void Frame_SetValue () {
1931                 Event e = run_until ("locals2");
1932
1933                 StackFrame frame = e.Thread.GetFrames () [0];
1934
1935                 // primitive
1936                 var l = frame.Method.GetLocal ("i");
1937                 frame.SetValue (l, vm.CreateValue ((long)55));
1938                 AssertValue (55, frame.GetValue (l));
1939
1940                 // reference
1941                 l = frame.Method.GetLocal ("s");
1942                 frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
1943                 AssertValue ("DEF", frame.GetValue (l));
1944
1945                 // argument as local
1946                 l = frame.Method.GetLocal ("arg");
1947                 frame.SetValue (l, vm.CreateValue (6));
1948                 AssertValue (6, frame.GetValue (l));
1949
1950                 // argument
1951                 var p = frame.Method.GetParameters ()[1];
1952                 frame.SetValue (p, vm.CreateValue (7));
1953                 AssertValue (7, frame.GetValue (p));
1954
1955                 // argument checking
1956
1957                 // variable null
1958                 AssertThrows<ArgumentNullException> (delegate () {
1959                                 frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
1960                         });
1961
1962                 // value null
1963                 AssertThrows<ArgumentNullException> (delegate () {
1964                                 l = frame.Method.GetLocal ("i");
1965                                 frame.SetValue (l, null);
1966                         });
1967
1968                 // value of invalid type
1969                 AssertThrows<ArgumentException> (delegate () {
1970                                 l = frame.Method.GetLocal ("i");
1971                                 frame.SetValue (l, vm.CreateValue (55));
1972                         });
1973         }
1974
1975         [Test]
1976         public void InvokeRegress () {
1977                 Event e = run_until ("invoke1");
1978
1979                 StackFrame frame = e.Thread.GetFrames () [0];
1980
1981                 TypeMirror t = frame.Method.DeclaringType;
1982                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
1983
1984                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
1985
1986                 MethodMirror m;
1987                 Value v;
1988
1989                 // do an invoke
1990                 m = t.GetMethod ("invoke_return_void");
1991                 v = this_obj.InvokeMethod (e.Thread, m, null);
1992                 Assert.IsNull (v);
1993
1994                 // Check that the stack frames remain valid during the invoke
1995                 Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
1996
1997                 // do another invoke
1998                 m = t.GetMethod ("invoke_return_void");
1999                 v = this_obj.InvokeMethod (e.Thread, m, null);
2000                 Assert.IsNull (v);
2001
2002                 // Try a single step after the invoke
2003                 var req = vm.CreateStepRequest (e.Thread);
2004                 req.Depth = StepDepth.Into;
2005                 req.Size = StepSize.Line;
2006                 req.Enable ();
2007
2008                 step_req = req;
2009
2010                 // Step into invoke2
2011                 vm.Resume ();
2012                 e = vm.GetNextEvent ();
2013                 Assert.IsTrue (e is StepEvent);
2014                 Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
2015
2016                 req.Disable ();
2017
2018                 frame = e.Thread.GetFrames () [0];
2019         }
2020
2021         [Test]
2022         public void Exceptions () {
2023                 Event e = run_until ("exceptions");
2024                 var req = vm.CreateExceptionRequest (null);
2025                 req.Enable ();
2026
2027                 vm.Resume ();
2028
2029                 e = vm.GetNextEvent ();
2030                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2031                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2032
2033                 var frames = e.Thread.GetFrames ();
2034                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2035                 req.Disable ();
2036
2037                 // exception type filter
2038
2039                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
2040                 req.Enable ();
2041
2042                 // Skip the throwing of the second OverflowException       
2043                 vm.Resume ();
2044
2045                 e = vm.GetNextEvent ();
2046                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2047                 Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
2048                 req.Disable ();
2049
2050                 // exception type filter for subclasses
2051                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
2052                 req.Enable ();
2053
2054                 vm.Resume ();
2055
2056                 e = vm.GetNextEvent ();
2057                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2058                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2059                 req.Disable ();
2060
2061                 // Implicit exceptions
2062                 req = vm.CreateExceptionRequest (null);
2063                 req.Enable ();
2064
2065                 vm.Resume ();
2066
2067                 e = vm.GetNextEvent ();
2068                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2069                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2070                 req.Disable ();
2071
2072                 // Argument checking
2073                 AssertThrows<ArgumentException> (delegate {
2074                                 vm.CreateExceptionRequest (e.Thread.Type);
2075                         });
2076         }
2077
2078         [Test]
2079         public void Domains () {
2080                 vm.Dispose ();
2081
2082                 Start (new string [] { "dtest-app.exe", "domain-test" });
2083
2084                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
2085
2086                 Event e = run_until ("domains");
2087
2088                 vm.Resume ();
2089                 
2090                 e = vm.GetNextEvent ();
2091                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
2092
2093                 var domain = (e as AppDomainCreateEvent).Domain;
2094
2095                 // Run until the callback in the domain
2096                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
2097                 Assert.IsNotNull (m);
2098                 vm.SetBreakpoint (m, 0);
2099
2100                 while (true) {
2101                         vm.Resume ();
2102                         e = vm.GetNextEvent ();
2103                         if (e is BreakpointEvent)
2104                                 break;
2105                 }
2106
2107                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
2108
2109                 // d_method is from another domain
2110                 MethodMirror d_method = (e as BreakpointEvent).Method;
2111                 Assert.IsTrue (m != d_method);
2112
2113                 var frames = e.Thread.GetFrames ();
2114                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
2115                 Assert.AreEqual ("invoke", frames [1].Method.Name);
2116                 Assert.AreEqual ("domains", frames [2].Method.Name);
2117
2118                 // This is empty when receiving the AppDomainCreateEvent
2119                 Assert.AreEqual ("domain", domain.FriendlyName);
2120
2121                 // Run until the unload
2122                 while (true) {
2123                         vm.Resume ();
2124                         e = vm.GetNextEvent ();
2125                         if (e is AssemblyUnloadEvent) {
2126                                 continue;
2127                         } else {
2128                                 break;
2129                         }
2130                 }
2131                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
2132                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
2133
2134                 // Run past the unload
2135                 e = run_until ("domains_2");
2136
2137                 // Test access to unloaded types
2138                 // FIXME: Add an exception type for this
2139                 AssertThrows<Exception> (delegate {
2140                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
2141                         });
2142         }
2143
2144         [Test]
2145         public void DynamicMethods () {
2146                 Event e = run_until ("dyn_call");
2147
2148                 var m = e.Thread.GetFrames ()[1].Method;
2149                 Assert.AreEqual ("dyn_method", m.Name);
2150
2151                 // Test access to IL
2152                 var body = m.GetMethodBody ();
2153
2154                 ILInstruction ins = body.Instructions [0];
2155                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2156                 Assert.AreEqual ("FOO", ins.Operand);
2157         }
2158
2159         [Test]
2160         public void RefEmit () {
2161                 vm.Dispose ();
2162
2163                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
2164
2165                 Event e = run_until ("ref_emit_call");
2166
2167                 var m = e.Thread.GetFrames ()[1].Method;
2168                 Assert.AreEqual ("ref_emit_method", m.Name);
2169
2170                 // Test access to IL
2171                 var body = m.GetMethodBody ();
2172
2173                 ILInstruction ins;
2174
2175                 ins = body.Instructions [0];
2176                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2177                 Assert.AreEqual ("FOO", ins.Operand);
2178
2179                 ins = body.Instructions [1];
2180                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
2181                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
2182                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
2183         }
2184
2185         [Test]
2186         public void IsAttached () {
2187                 var f = entry_point.DeclaringType.GetField ("is_attached");
2188
2189                 Event e = run_until ("Main");
2190
2191                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
2192         }
2193
2194         [Test]
2195         public void StackTraceInNative () {
2196                 // Check that stack traces can be produced for threads in native code
2197                 vm.Dispose ();
2198
2199                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
2200
2201                 var e = run_until ("frames_in_native");
2202
2203                 // FIXME: This is racy
2204                 vm.Resume ();
2205
2206                 Thread.Sleep (100);
2207
2208                 vm.Suspend ();
2209
2210                 StackFrame[] frames = e.Thread.GetFrames ();
2211
2212                 int frame_index = -1;
2213                 for (int i = 0; i < frames.Length; ++i) {
2214                         if (frames [i].Method.Name == "Sleep") {
2215                                 frame_index = i;
2216                                 break;
2217                         }
2218                 }
2219
2220                 Assert.IsTrue (frame_index != -1);
2221                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
2222                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
2223                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
2224
2225                 // Check that invokes are disabled for such threads
2226                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
2227
2228                 // return void
2229                 var m = t.GetMethod ("invoke_static_return_void");
2230                 AssertThrows<InvalidOperationException> (delegate {
2231                                 t.InvokeMethod (e.Thread, m, null);
2232                         });
2233         }
2234
2235         [Test]
2236         public void VirtualMachine_CreateEnumMirror () {
2237                 var e = run_until ("o1");
2238                 var frame = e.Thread.GetFrames () [0];
2239
2240                 object val = frame.GetThis ();
2241                 Assert.IsTrue (val is ObjectMirror);
2242                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
2243                 ObjectMirror o = (val as ObjectMirror);
2244
2245                 FieldInfoMirror field = o.Type.GetField ("field_enum");
2246                 Value f = o.GetValue (field);
2247                 TypeMirror enumType = (f as EnumMirror).Type;
2248
2249                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
2250                 f = o.GetValue (field);
2251                 Assert.AreEqual (1, (f as EnumMirror).Value);
2252
2253                 // Argument checking
2254                 AssertThrows<ArgumentNullException> (delegate () {
2255                                 vm.CreateEnumMirror (enumType, null);
2256                         });
2257
2258                 AssertThrows<ArgumentNullException> (delegate () {
2259                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
2260                         });
2261
2262                 // null value
2263                 AssertThrows<ArgumentException> (delegate () {
2264                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
2265                         });
2266
2267                 // value of a wrong type
2268                 AssertThrows<ArgumentException> (delegate () {
2269                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
2270                         });
2271         }
2272 }