2010-03-23 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                 // Pass generic struct as this
1803                 s = frame.GetArgument (2) as StructMirror;
1804                 t = s.Type;
1805                 m = t.GetMethod ("invoke_return_int");
1806                 v = s.InvokeMethod (e.Thread, m, null);
1807                 AssertValue (42, v);
1808         }
1809
1810         [Test]
1811         public void BreakpointDuringInvoke () {
1812                 Event e = run_until ("invoke1");
1813
1814                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
1815                 Assert.IsNotNull (m);
1816                 vm.SetBreakpoint (m, 0);
1817
1818                 StackFrame frame = e.Thread.GetFrames () [0];
1819                 var o = frame.GetThis () as ObjectMirror;
1820
1821                 bool failed = false;
1822
1823                 bool finished = false;
1824                 object wait = new object ();
1825
1826                 // Have to invoke in a separate thread as the invoke is suspended until we
1827                 // resume after the breakpoint
1828                 Thread t = new Thread (delegate () {
1829                                 try {
1830                                         o.InvokeMethod (e.Thread, m, null);
1831                                 } catch {
1832                                         failed = true;
1833                                 }
1834                                 lock (wait) {
1835                                         finished = true;
1836                                         Monitor.Pulse (wait);
1837                                 }
1838                         });
1839
1840                 t.Start ();
1841
1842                 StackFrame invoke_frame = null;
1843
1844                 try {
1845                         e = vm.GetNextEvent ();
1846                         Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
1847                         // Check stack trace support and invokes
1848                         var frames = e.Thread.GetFrames ();
1849                         invoke_frame = frames [0];
1850                         Assert.AreEqual ("invoke2", frames [0].Method.Name);
1851                         Assert.IsTrue (frames [0].IsDebuggerInvoke);
1852                         Assert.AreEqual ("invoke1", frames [1].Method.Name);
1853                 } finally {
1854                         vm.Resume ();
1855                 }
1856
1857                 // Check that the invoke frames are no longer valid
1858                 AssertThrows<InvalidStackFrameException> (delegate {
1859                                 invoke_frame.GetThis ();
1860                         });
1861
1862                 lock (wait) {
1863                         if (!finished)
1864                                 Monitor.Wait (wait);
1865                 }
1866
1867                 // Check InvokeOptions.DisableBreakpoints flag
1868                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
1869         }
1870
1871         [Test]
1872         public void InvokeSingleThreaded () {
1873                 vm.Dispose ();
1874
1875                 Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
1876
1877                 Event e = run_until ("invoke_single_threaded_2");
1878
1879                 StackFrame f = e.Thread.GetFrames ()[0];
1880
1881                 var obj = f.GetThis () as ObjectMirror;
1882
1883                 // Check that the counter value incremented by the other thread does not increase
1884                 // during the invoke.
1885                 object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
1886
1887                 var m = obj.Type.GetMethod ("invoke_return_void");
1888                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
1889
1890             object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
1891
1892                 Assert.AreEqual ((int)counter1, (int)counter2);
1893
1894                 // Test multiple invokes done in succession
1895                 m = obj.Type.GetMethod ("invoke_return_void");
1896                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
1897
1898                 // Test events during single-threaded invokes
1899                 vm.EnableEvents (EventType.TypeLoad);
1900                 m = obj.Type.GetMethod ("invoke_type_load");
1901                 obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
1902                                 vm.Resume ();
1903                         }, null);
1904
1905                 e = vm.GetNextEvent ();
1906                 Assert.AreEqual (EventType.TypeLoad, e.EventType);
1907         }
1908
1909         [Test]
1910         public void GetThreads () {
1911                 vm.GetThreads ();
1912         }
1913
1914         [Test]
1915         public void Threads () {
1916                 Event e = run_until ("threads");
1917
1918                 Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
1919
1920                 vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
1921
1922                 vm.Resume ();
1923
1924                 e = vm.GetNextEvent ();
1925                 Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
1926                 var state = e.Thread.ThreadState;
1927                 Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
1928
1929                 vm.Resume ();
1930
1931                 e = vm.GetNextEvent ();
1932                 Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
1933                 Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
1934         }
1935
1936         [Test]
1937         public void Frame_SetValue () {
1938                 Event e = run_until ("locals2");
1939
1940                 StackFrame frame = e.Thread.GetFrames () [0];
1941
1942                 // primitive
1943                 var l = frame.Method.GetLocal ("i");
1944                 frame.SetValue (l, vm.CreateValue ((long)55));
1945                 AssertValue (55, frame.GetValue (l));
1946
1947                 // reference
1948                 l = frame.Method.GetLocal ("s");
1949                 frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
1950                 AssertValue ("DEF", frame.GetValue (l));
1951
1952                 // argument as local
1953                 l = frame.Method.GetLocal ("arg");
1954                 frame.SetValue (l, vm.CreateValue (6));
1955                 AssertValue (6, frame.GetValue (l));
1956
1957                 // argument
1958                 var p = frame.Method.GetParameters ()[1];
1959                 frame.SetValue (p, vm.CreateValue (7));
1960                 AssertValue (7, frame.GetValue (p));
1961
1962                 // argument checking
1963
1964                 // variable null
1965                 AssertThrows<ArgumentNullException> (delegate () {
1966                                 frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
1967                         });
1968
1969                 // value null
1970                 AssertThrows<ArgumentNullException> (delegate () {
1971                                 l = frame.Method.GetLocal ("i");
1972                                 frame.SetValue (l, null);
1973                         });
1974
1975                 // value of invalid type
1976                 AssertThrows<ArgumentException> (delegate () {
1977                                 l = frame.Method.GetLocal ("i");
1978                                 frame.SetValue (l, vm.CreateValue (55));
1979                         });
1980         }
1981
1982         [Test]
1983         public void InvokeRegress () {
1984                 Event e = run_until ("invoke1");
1985
1986                 StackFrame frame = e.Thread.GetFrames () [0];
1987
1988                 TypeMirror t = frame.Method.DeclaringType;
1989                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
1990
1991                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
1992
1993                 MethodMirror m;
1994                 Value v;
1995
1996                 // do an invoke
1997                 m = t.GetMethod ("invoke_return_void");
1998                 v = this_obj.InvokeMethod (e.Thread, m, null);
1999                 Assert.IsNull (v);
2000
2001                 // Check that the stack frames remain valid during the invoke
2002                 Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
2003
2004                 // do another invoke
2005                 m = t.GetMethod ("invoke_return_void");
2006                 v = this_obj.InvokeMethod (e.Thread, m, null);
2007                 Assert.IsNull (v);
2008
2009                 // Try a single step after the invoke
2010                 var req = vm.CreateStepRequest (e.Thread);
2011                 req.Depth = StepDepth.Into;
2012                 req.Size = StepSize.Line;
2013                 req.Enable ();
2014
2015                 step_req = req;
2016
2017                 // Step into invoke2
2018                 vm.Resume ();
2019                 e = vm.GetNextEvent ();
2020                 Assert.IsTrue (e is StepEvent);
2021                 Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
2022
2023                 req.Disable ();
2024
2025                 frame = e.Thread.GetFrames () [0];
2026         }
2027
2028         [Test]
2029         public void Exceptions () {
2030                 Event e = run_until ("exceptions");
2031                 var req = vm.CreateExceptionRequest (null);
2032                 req.Enable ();
2033
2034                 vm.Resume ();
2035
2036                 e = vm.GetNextEvent ();
2037                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2038                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2039
2040                 var frames = e.Thread.GetFrames ();
2041                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2042                 req.Disable ();
2043
2044                 // exception type filter
2045
2046                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
2047                 req.Enable ();
2048
2049                 // Skip the throwing of the second OverflowException       
2050                 vm.Resume ();
2051
2052                 e = vm.GetNextEvent ();
2053                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2054                 Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
2055                 req.Disable ();
2056
2057                 // exception type filter for subclasses
2058                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
2059                 req.Enable ();
2060
2061                 vm.Resume ();
2062
2063                 e = vm.GetNextEvent ();
2064                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2065                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2066                 req.Disable ();
2067
2068                 // Implicit exceptions
2069                 req = vm.CreateExceptionRequest (null);
2070                 req.Enable ();
2071
2072                 vm.Resume ();
2073
2074                 e = vm.GetNextEvent ();
2075                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2076                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2077                 req.Disable ();
2078
2079                 // Argument checking
2080                 AssertThrows<ArgumentException> (delegate {
2081                                 vm.CreateExceptionRequest (e.Thread.Type);
2082                         });
2083         }
2084
2085         [Test]
2086         public void Domains () {
2087                 vm.Dispose ();
2088
2089                 Start (new string [] { "dtest-app.exe", "domain-test" });
2090
2091                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
2092
2093                 Event e = run_until ("domains");
2094
2095                 vm.Resume ();
2096                 
2097                 e = vm.GetNextEvent ();
2098                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
2099
2100                 var domain = (e as AppDomainCreateEvent).Domain;
2101
2102                 // Run until the callback in the domain
2103                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
2104                 Assert.IsNotNull (m);
2105                 vm.SetBreakpoint (m, 0);
2106
2107                 while (true) {
2108                         vm.Resume ();
2109                         e = vm.GetNextEvent ();
2110                         if (e is BreakpointEvent)
2111                                 break;
2112                 }
2113
2114                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
2115
2116                 // d_method is from another domain
2117                 MethodMirror d_method = (e as BreakpointEvent).Method;
2118                 Assert.IsTrue (m != d_method);
2119
2120                 var frames = e.Thread.GetFrames ();
2121                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
2122                 Assert.AreEqual ("invoke", frames [1].Method.Name);
2123                 Assert.AreEqual ("domains", frames [2].Method.Name);
2124
2125                 // This is empty when receiving the AppDomainCreateEvent
2126                 Assert.AreEqual ("domain", domain.FriendlyName);
2127
2128                 // Run until the unload
2129                 while (true) {
2130                         vm.Resume ();
2131                         e = vm.GetNextEvent ();
2132                         if (e is AssemblyUnloadEvent) {
2133                                 continue;
2134                         } else {
2135                                 break;
2136                         }
2137                 }
2138                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
2139                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
2140
2141                 // Run past the unload
2142                 e = run_until ("domains_2");
2143
2144                 // Test access to unloaded types
2145                 // FIXME: Add an exception type for this
2146                 AssertThrows<Exception> (delegate {
2147                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
2148                         });
2149         }
2150
2151         [Test]
2152         public void DynamicMethods () {
2153                 Event e = run_until ("dyn_call");
2154
2155                 var m = e.Thread.GetFrames ()[1].Method;
2156                 Assert.AreEqual ("dyn_method", m.Name);
2157
2158                 // Test access to IL
2159                 var body = m.GetMethodBody ();
2160
2161                 ILInstruction ins = body.Instructions [0];
2162                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2163                 Assert.AreEqual ("FOO", ins.Operand);
2164         }
2165
2166         [Test]
2167         public void RefEmit () {
2168                 vm.Dispose ();
2169
2170                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
2171
2172                 Event e = run_until ("ref_emit_call");
2173
2174                 var m = e.Thread.GetFrames ()[1].Method;
2175                 Assert.AreEqual ("ref_emit_method", m.Name);
2176
2177                 // Test access to IL
2178                 var body = m.GetMethodBody ();
2179
2180                 ILInstruction ins;
2181
2182                 ins = body.Instructions [0];
2183                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2184                 Assert.AreEqual ("FOO", ins.Operand);
2185
2186                 ins = body.Instructions [1];
2187                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
2188                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
2189                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
2190         }
2191
2192         [Test]
2193         public void IsAttached () {
2194                 var f = entry_point.DeclaringType.GetField ("is_attached");
2195
2196                 Event e = run_until ("Main");
2197
2198                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
2199         }
2200
2201         [Test]
2202         public void StackTraceInNative () {
2203                 // Check that stack traces can be produced for threads in native code
2204                 vm.Dispose ();
2205
2206                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
2207
2208                 var e = run_until ("frames_in_native");
2209
2210                 // FIXME: This is racy
2211                 vm.Resume ();
2212
2213                 Thread.Sleep (100);
2214
2215                 vm.Suspend ();
2216
2217                 StackFrame[] frames = e.Thread.GetFrames ();
2218
2219                 int frame_index = -1;
2220                 for (int i = 0; i < frames.Length; ++i) {
2221                         if (frames [i].Method.Name == "Sleep") {
2222                                 frame_index = i;
2223                                 break;
2224                         }
2225                 }
2226
2227                 Assert.IsTrue (frame_index != -1);
2228                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
2229                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
2230                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
2231
2232                 // Check that invokes are disabled for such threads
2233                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
2234
2235                 // return void
2236                 var m = t.GetMethod ("invoke_static_return_void");
2237                 AssertThrows<InvalidOperationException> (delegate {
2238                                 t.InvokeMethod (e.Thread, m, null);
2239                         });
2240         }
2241
2242         [Test]
2243         public void VirtualMachine_CreateEnumMirror () {
2244                 var e = run_until ("o1");
2245                 var frame = e.Thread.GetFrames () [0];
2246
2247                 object val = frame.GetThis ();
2248                 Assert.IsTrue (val is ObjectMirror);
2249                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
2250                 ObjectMirror o = (val as ObjectMirror);
2251
2252                 FieldInfoMirror field = o.Type.GetField ("field_enum");
2253                 Value f = o.GetValue (field);
2254                 TypeMirror enumType = (f as EnumMirror).Type;
2255
2256                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
2257                 f = o.GetValue (field);
2258                 Assert.AreEqual (1, (f as EnumMirror).Value);
2259
2260                 // Argument checking
2261                 AssertThrows<ArgumentNullException> (delegate () {
2262                                 vm.CreateEnumMirror (enumType, null);
2263                         });
2264
2265                 AssertThrows<ArgumentNullException> (delegate () {
2266                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
2267                         });
2268
2269                 // null value
2270                 AssertThrows<ArgumentException> (delegate () {
2271                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
2272                         });
2273
2274                 // value of a wrong type
2275                 AssertThrows<ArgumentException> (delegate () {
2276                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
2277                         });
2278         }
2279 }