Don't allow EventType.Breakpoint in vm.EnableEvents ().
[mono.git] / mcs / class / Mono.Debugger.Soft / Test / dtest.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Threading;
4 using System.Net;
5 using System.Reflection;
6 using 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 GetVisibleVariables () {
1442                 Event e = run_until ("locals4");
1443
1444                 // First scope
1445                 var locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1446                 Assert.AreEqual (2, locals.Count);
1447                 var loc = locals.First (l => l.Name == "i");
1448                 Assert.AreEqual ("Int64", loc.Type.Name);
1449                 loc = locals.First (l => l.Name == "s");
1450                 Assert.AreEqual ("String", loc.Type.Name);
1451
1452                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1453                 Assert.AreEqual ("i", loc.Name);
1454                 Assert.AreEqual ("Int64", loc.Type.Name);
1455
1456                 e = run_until ("locals5");
1457
1458                 // Second scope
1459                 locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1460                 Assert.AreEqual (2, locals.Count);
1461                 loc = locals.First (l => l.Name == "i");
1462                 Assert.AreEqual ("String", loc.Type.Name);
1463                 loc = locals.First (l => l.Name == "s");
1464                 Assert.AreEqual ("String", loc.Type.Name);
1465
1466                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1467                 Assert.AreEqual ("i", loc.Name);
1468                 Assert.AreEqual ("String", loc.Type.Name);
1469
1470                 // Variable in another scope
1471                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("j");
1472                 Assert.IsNull (loc);
1473         }
1474
1475         [Test]
1476         public void Exit () {
1477                 run_until ("Main");
1478
1479                 vm.Exit (5);
1480
1481                 var e = vm.GetNextEvent ();
1482                 Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
1483
1484                 var p = vm.Process;
1485                 /* Could be a remote vm with no process */
1486                 if (p != null) {
1487                         p.WaitForExit ();
1488                         Assert.AreEqual (5, p.ExitCode);
1489
1490                         // error handling
1491                         AssertThrows<VMDisconnectedException> (delegate () {
1492                                         vm.Resume ();
1493                                 });
1494                 }
1495
1496                 vm = null;
1497         }
1498
1499         [Test]
1500         public void Dispose () {
1501                 run_until ("Main");
1502
1503                 vm.Dispose ();
1504
1505                 var e = vm.GetNextEvent ();
1506                 Assert.IsInstanceOfType (typeof (VMDisconnectEvent), e);
1507
1508                 var p = vm.Process;
1509                 /* Could be a remote vm with no process */
1510                 if (p != null) {
1511                         p.WaitForExit ();
1512                         Assert.AreEqual (3, p.ExitCode);
1513
1514                         // error handling
1515                         AssertThrows<VMDisconnectedException> (delegate () {
1516                                         vm.Resume ();
1517                                 });
1518                 }
1519
1520                 vm = null;
1521         }
1522
1523         [Test]
1524         public void LineNumbers () {
1525                 Event e = run_until ("line_numbers");
1526
1527                 step_req = vm.CreateStepRequest (e.Thread);
1528                 step_req.Depth = StepDepth.Into;
1529                 step_req.Enable ();
1530
1531                 Location l;
1532                 
1533                 vm.Resume ();
1534
1535                 e = vm.GetNextEvent ();
1536                 Assert.IsTrue (e is StepEvent);
1537
1538                 l = e.Thread.GetFrames ()[0].Location;
1539
1540                 Assert.IsTrue (l.SourceFile.IndexOf ("dtest-app.cs") != -1);
1541                 Assert.AreEqual ("ln1", l.Method.Name);
1542                 
1543                 int line_base = l.LineNumber;
1544
1545                 vm.Resume ();
1546                 e = vm.GetNextEvent ();
1547                 Assert.IsTrue (e is StepEvent);
1548                 l = e.Thread.GetFrames ()[0].Location;
1549                 Assert.AreEqual ("ln2", l.Method.Name);
1550                 Assert.AreEqual (line_base + 6, l.LineNumber);
1551
1552                 vm.Resume ();
1553                 e = vm.GetNextEvent ();
1554                 Assert.IsTrue (e is StepEvent);
1555                 l = e.Thread.GetFrames ()[0].Location;
1556                 Assert.AreEqual ("ln1", l.Method.Name);
1557                 Assert.AreEqual (line_base + 1, l.LineNumber);
1558
1559                 vm.Resume ();
1560                 e = vm.GetNextEvent ();
1561                 Assert.IsTrue (e is StepEvent);
1562                 l = e.Thread.GetFrames ()[0].Location;
1563                 Assert.AreEqual ("ln3", l.Method.Name);
1564                 Assert.AreEqual (line_base + 10, l.LineNumber);
1565
1566                 vm.Resume ();
1567                 e = vm.GetNextEvent ();
1568                 Assert.IsTrue (e is StepEvent);
1569                 l = e.Thread.GetFrames ()[0].Location;
1570                 Assert.AreEqual ("ln1", l.Method.Name);
1571                 Assert.AreEqual (line_base + 2, l.LineNumber);
1572
1573                 // GetSourceFiles ()
1574                 string[] sources = l.Method.DeclaringType.GetSourceFiles ();
1575                 Assert.AreEqual (1, sources.Length);
1576                 Assert.AreEqual ("dtest-app.cs", sources [0]);
1577
1578                 sources = l.Method.DeclaringType.GetSourceFiles (true);
1579                 Assert.AreEqual (1, sources.Length);
1580                 Assert.IsTrue (sources [0].EndsWith ("dtest-app.cs"));
1581         }
1582
1583         [Test]
1584         public void Suspend () {
1585                 vm.Dispose ();
1586
1587                 Start (new string [] { "dtest-app.exe", "suspend-test" });
1588
1589                 Event e = run_until ("suspend");
1590
1591                 ThreadMirror main = e.Thread;
1592
1593                 vm.Resume ();
1594
1595                 Thread.Sleep (100);
1596
1597                 vm.Suspend ();
1598
1599                 // The debuggee should be suspended while it is running the infinite loop
1600                 // in suspend ()
1601                 StackFrame frame = main.GetFrames ()[0];
1602                 Assert.AreEqual ("suspend", frame.Method.Name);
1603
1604                 vm.Resume ();
1605
1606                 // resuming when not suspended
1607                 AssertThrows<InvalidOperationException> (delegate () {
1608                                 vm.Resume ();
1609                         });
1610
1611                 vm.Exit (0);
1612
1613                 vm = null;
1614         }
1615
1616         [Test]
1617         public void AssemblyLoad () {
1618                 Event e = run_until ("assembly_load");
1619
1620                 vm.Resume ();
1621
1622                 e = vm.GetNextEvent ();
1623                 Assert.IsInstanceOfType (typeof (AssemblyLoadEvent), e);
1624                 Assert.IsTrue ((e as AssemblyLoadEvent).Assembly.Location.EndsWith ("System.dll"));
1625
1626                 var frames = e.Thread.GetFrames ();
1627                 Assert.IsTrue (frames.Length > 0);
1628                 Assert.AreEqual ("assembly_load", frames [0].Method.Name);
1629         }
1630
1631         [Test]
1632         public void CreateValue () {
1633                 PrimitiveValue v;
1634
1635                 v = vm.CreateValue (1);
1636                 Assert.AreEqual (vm, v.VirtualMachine);
1637                 Assert.AreEqual (1, v.Value);
1638
1639                 v = vm.CreateValue (null);
1640                 Assert.AreEqual (vm, v.VirtualMachine);
1641                 Assert.AreEqual (null, v.Value);
1642
1643                 // Argument checking
1644                 AssertThrows <ArgumentException> (delegate () {
1645                                 v = vm.CreateValue ("FOO");
1646                         });
1647         }
1648
1649         [Test]
1650         public void CreateString () {
1651                 StringMirror s = vm.RootDomain.CreateString ("ABC");
1652
1653                 Assert.AreEqual (vm, s.VirtualMachine);
1654                 Assert.AreEqual ("ABC", s.Value);
1655                 Assert.AreEqual (vm.RootDomain, s.Domain);
1656
1657                 // Argument checking
1658                 AssertThrows <ArgumentNullException> (delegate () {
1659                                 s = vm.RootDomain.CreateString (null);
1660                         });
1661         }
1662
1663         [Test]
1664         [Category ("only")]
1665         public void CreateBoxedValue () {
1666                 ObjectMirror o = vm.RootDomain.CreateBoxedValue (new PrimitiveValue (vm, 42));
1667
1668                 Assert.AreEqual ("Int32", o.Type.Name);
1669                 //AssertValue (42, m.GetValue (o.Type.GetField ("m_value")));
1670
1671                 // Argument checking
1672                 AssertThrows <ArgumentNullException> (delegate () {
1673                                 vm.RootDomain.CreateBoxedValue (null);
1674                         });
1675
1676                 AssertThrows <ArgumentException> (delegate () {
1677                                 vm.RootDomain.CreateBoxedValue (o);
1678                         });
1679         }
1680
1681         [Test]
1682         public void Invoke () {
1683                 Event e = run_until ("invoke1");
1684
1685                 StackFrame frame = e.Thread.GetFrames () [0];
1686
1687                 TypeMirror t = frame.Method.DeclaringType;
1688                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
1689
1690                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
1691
1692                 MethodMirror m;
1693                 Value v;
1694
1695                 // return void
1696                 m = t.GetMethod ("invoke_return_void");
1697                 v = this_obj.InvokeMethod (e.Thread, m, null);
1698                 Assert.IsNull (v);
1699
1700                 // return ref
1701                 m = t.GetMethod ("invoke_return_ref");
1702                 v = this_obj.InvokeMethod (e.Thread, m, null);
1703                 AssertValue ("ABC", v);
1704
1705                 // return null
1706                 m = t.GetMethod ("invoke_return_null");
1707                 v = this_obj.InvokeMethod (e.Thread, m, null);
1708                 AssertValue (null, v);
1709
1710                 // return primitive
1711                 m = t.GetMethod ("invoke_return_primitive");
1712                 v = this_obj.InvokeMethod (e.Thread, m, null);
1713                 AssertValue (42, v);
1714
1715                 // pass primitive
1716                 m = t.GetMethod ("invoke_pass_primitive");
1717                 Value[] args = new Value [] {
1718                         vm.CreateValue ((byte)Byte.MaxValue),
1719                         vm.CreateValue ((sbyte)SByte.MaxValue),
1720                         vm.CreateValue ((short)1),
1721                         vm.CreateValue ((ushort)1),
1722                         vm.CreateValue ((int)1),
1723                         vm.CreateValue ((uint)1),
1724                         vm.CreateValue ((long)1),
1725                         vm.CreateValue ((ulong)1),
1726                         vm.CreateValue ('A'),
1727                         vm.CreateValue (true),
1728                         vm.CreateValue (3.14f),
1729                         vm.CreateValue (3.14) };
1730
1731                 v = this_obj.InvokeMethod (e.Thread, m, args);
1732                 AssertValue ((int)Byte.MaxValue + (int)SByte.MaxValue + 1 + 1 + 1 + 1 + 1 + 1 + 'A' + 1 + 3 + 3, v);
1733
1734                 // pass ref
1735                 m = t.GetMethod ("invoke_pass_ref");
1736                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1737                 AssertValue ("ABC", v);
1738
1739                 // pass null
1740                 m = t.GetMethod ("invoke_pass_ref");
1741                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (null) });
1742                 AssertValue (null, v);
1743
1744                 // static
1745                 m = t.GetMethod ("invoke_static_pass_ref");
1746                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1747                 AssertValue ("ABC", v);
1748
1749                 // static invoked using ObjectMirror.InvokeMethod
1750                 m = t.GetMethod ("invoke_static_pass_ref");
1751                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1752                 AssertValue ("ABC", v);
1753
1754                 // method which throws an exception
1755                 try {
1756                         m = t.GetMethod ("invoke_throws");
1757                         v = this_obj.InvokeMethod (e.Thread, m, null);
1758                         Assert.Fail ();
1759                 } catch (InvocationException ex) {
1760                         Assert.AreEqual ("Exception", ex.Exception.Type.Name);
1761                 }
1762
1763                 // newobj
1764                 m = t.GetMethod (".ctor");
1765                 v = t.InvokeMethod (e.Thread, m, null);
1766                 Assert.IsInstanceOfType (typeof (ObjectMirror), v);
1767                 Assert.AreEqual ("Tests", (v as ObjectMirror).Type.Name);
1768
1769                 // Argument checking
1770                 
1771                 // null thread
1772                 AssertThrows<ArgumentNullException> (delegate {
1773                                 m = t.GetMethod ("invoke_pass_ref");
1774                                 v = this_obj.InvokeMethod (null, m, new Value [] { vm.CreateValue (null) });                            
1775                         });
1776
1777                 // null method
1778                 AssertThrows<ArgumentNullException> (delegate {
1779                                 v = this_obj.InvokeMethod (e.Thread, null, new Value [] { vm.CreateValue (null) });                             
1780                         });
1781
1782                 // invalid number of arguments
1783                 m = t.GetMethod ("invoke_pass_ref");
1784                 AssertThrows<ArgumentException> (delegate {
1785                                 v = this_obj.InvokeMethod (e.Thread, m, null);
1786                         });
1787
1788                 // invalid type of argument (ref != primitive)
1789                 m = t.GetMethod ("invoke_pass_ref");
1790                 AssertThrows<ArgumentException> (delegate {
1791                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
1792                         });
1793
1794                 // invalid type of argument (primitive != primitive)
1795                 m = t.GetMethod ("invoke_pass_primitive_2");
1796                 AssertThrows<ArgumentException> (delegate {
1797                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
1798                         });
1799
1800                 // invoking a non-static method as static
1801                 m = t.GetMethod ("invoke_pass_ref");
1802                 AssertThrows<ArgumentException> (delegate {
1803                                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1804                         });
1805
1806                 // invoking a method defined in another class
1807                 m = t2.GetMethod ("invoke");
1808                 AssertThrows<ArgumentException> (delegate {
1809                                 v = this_obj.InvokeMethod (e.Thread, m, null);
1810                         });
1811         }
1812
1813         [Test]
1814         public void InvokeVType () {
1815                 Event e = run_until ("invoke1");
1816
1817                 StackFrame frame = e.Thread.GetFrames () [0];
1818
1819                 var s = frame.GetArgument (1) as StructMirror;
1820
1821                 TypeMirror t = s.Type;
1822
1823                 MethodMirror m;
1824                 Value v;
1825
1826                 // Pass struct as this, receive int
1827                 m = t.GetMethod ("invoke_return_int");
1828                 v = s.InvokeMethod (e.Thread, m, null);
1829                 AssertValue (42, v);
1830
1831                 // Pass struct as this, receive intptr
1832                 m = t.GetMethod ("invoke_return_intptr");
1833                 v = s.InvokeMethod (e.Thread, m, null);
1834                 AssertValue (43, v);
1835
1836                 // Static method
1837                 m = t.GetMethod ("invoke_static");
1838                 v = t.InvokeMethod (e.Thread, m, null);
1839                 AssertValue (5, v);
1840
1841                 // Pass generic struct as this
1842                 s = frame.GetArgument (2) as StructMirror;
1843                 t = s.Type;
1844                 m = t.GetMethod ("invoke_return_int");
1845                 v = s.InvokeMethod (e.Thread, m, null);
1846                 AssertValue (42, v);
1847         }
1848
1849         [Test]
1850         public void BreakpointDuringInvoke () {
1851                 Event e = run_until ("invoke1");
1852
1853                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
1854                 Assert.IsNotNull (m);
1855                 vm.SetBreakpoint (m, 0);
1856
1857                 StackFrame frame = e.Thread.GetFrames () [0];
1858                 var o = frame.GetThis () as ObjectMirror;
1859
1860                 bool failed = false;
1861
1862                 bool finished = false;
1863                 object wait = new object ();
1864
1865                 // Have to invoke in a separate thread as the invoke is suspended until we
1866                 // resume after the breakpoint
1867                 Thread t = new Thread (delegate () {
1868                                 try {
1869                                         o.InvokeMethod (e.Thread, m, null);
1870                                 } catch {
1871                                         failed = true;
1872                                 }
1873                                 lock (wait) {
1874                                         finished = true;
1875                                         Monitor.Pulse (wait);
1876                                 }
1877                         });
1878
1879                 t.Start ();
1880
1881                 StackFrame invoke_frame = null;
1882
1883                 try {
1884                         e = vm.GetNextEvent ();
1885                         Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
1886                         // Check stack trace support and invokes
1887                         var frames = e.Thread.GetFrames ();
1888                         invoke_frame = frames [0];
1889                         Assert.AreEqual ("invoke2", frames [0].Method.Name);
1890                         Assert.IsTrue (frames [0].IsDebuggerInvoke);
1891                         Assert.AreEqual ("invoke1", frames [1].Method.Name);
1892                 } finally {
1893                         vm.Resume ();
1894                 }
1895
1896                 // Check that the invoke frames are no longer valid
1897                 AssertThrows<InvalidStackFrameException> (delegate {
1898                                 invoke_frame.GetThis ();
1899                         });
1900
1901                 lock (wait) {
1902                         if (!finished)
1903                                 Monitor.Wait (wait);
1904                 }
1905
1906                 // Check InvokeOptions.DisableBreakpoints flag
1907                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
1908         }
1909
1910         [Test]
1911         public void InvokeSingleThreaded () {
1912                 vm.Dispose ();
1913
1914                 Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
1915
1916                 Event e = run_until ("invoke_single_threaded_2");
1917
1918                 StackFrame f = e.Thread.GetFrames ()[0];
1919
1920                 var obj = f.GetThis () as ObjectMirror;
1921
1922                 // Check that the counter value incremented by the other thread does not increase
1923                 // during the invoke.
1924                 object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
1925
1926                 var m = obj.Type.GetMethod ("invoke_return_void");
1927                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
1928
1929             object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
1930
1931                 Assert.AreEqual ((int)counter1, (int)counter2);
1932
1933                 // Test multiple invokes done in succession
1934                 m = obj.Type.GetMethod ("invoke_return_void");
1935                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
1936
1937                 // Test events during single-threaded invokes
1938                 vm.EnableEvents (EventType.TypeLoad);
1939                 m = obj.Type.GetMethod ("invoke_type_load");
1940                 obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
1941                                 vm.Resume ();
1942                         }, null);
1943
1944                 e = vm.GetNextEvent ();
1945                 Assert.AreEqual (EventType.TypeLoad, e.EventType);
1946         }
1947
1948         [Test]
1949         public void GetThreads () {
1950                 vm.GetThreads ();
1951         }
1952
1953         [Test]
1954         public void Threads () {
1955                 Event e = run_until ("threads");
1956
1957                 Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
1958
1959                 Assert.IsTrue (e.Thread.ThreadId > 0);
1960
1961                 vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
1962
1963                 vm.Resume ();
1964
1965                 e = vm.GetNextEvent ();
1966                 Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
1967                 var state = e.Thread.ThreadState;
1968                 Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
1969
1970                 vm.Resume ();
1971
1972                 e = vm.GetNextEvent ();
1973                 Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
1974                 Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
1975         }
1976
1977         [Test]
1978         public void Frame_SetValue () {
1979                 Event e = run_until ("locals2");
1980
1981                 StackFrame frame = e.Thread.GetFrames () [0];
1982
1983                 // primitive
1984                 var l = frame.Method.GetLocal ("i");
1985                 frame.SetValue (l, vm.CreateValue ((long)55));
1986                 AssertValue (55, frame.GetValue (l));
1987
1988                 // reference
1989                 l = frame.Method.GetLocal ("s");
1990                 frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
1991                 AssertValue ("DEF", frame.GetValue (l));
1992
1993                 // argument as local
1994                 l = frame.Method.GetLocal ("arg");
1995                 frame.SetValue (l, vm.CreateValue (6));
1996                 AssertValue (6, frame.GetValue (l));
1997
1998                 // argument
1999                 var p = frame.Method.GetParameters ()[1];
2000                 frame.SetValue (p, vm.CreateValue (7));
2001                 AssertValue (7, frame.GetValue (p));
2002
2003                 // argument checking
2004
2005                 // variable null
2006                 AssertThrows<ArgumentNullException> (delegate () {
2007                                 frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
2008                         });
2009
2010                 // value null
2011                 AssertThrows<ArgumentNullException> (delegate () {
2012                                 l = frame.Method.GetLocal ("i");
2013                                 frame.SetValue (l, null);
2014                         });
2015
2016                 // value of invalid type
2017                 AssertThrows<ArgumentException> (delegate () {
2018                                 l = frame.Method.GetLocal ("i");
2019                                 frame.SetValue (l, vm.CreateValue (55));
2020                         });
2021         }
2022
2023         [Test]
2024         public void InvokeRegress () {
2025                 Event e = run_until ("invoke1");
2026
2027                 StackFrame frame = e.Thread.GetFrames () [0];
2028
2029                 TypeMirror t = frame.Method.DeclaringType;
2030                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2031
2032                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2033
2034                 MethodMirror m;
2035                 Value v;
2036
2037                 // do an invoke
2038                 m = t.GetMethod ("invoke_return_void");
2039                 v = this_obj.InvokeMethod (e.Thread, m, null);
2040                 Assert.IsNull (v);
2041
2042                 // Check that the stack frames remain valid during the invoke
2043                 Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
2044
2045                 // do another invoke
2046                 m = t.GetMethod ("invoke_return_void");
2047                 v = this_obj.InvokeMethod (e.Thread, m, null);
2048                 Assert.IsNull (v);
2049
2050                 // Try a single step after the invoke
2051                 var req = vm.CreateStepRequest (e.Thread);
2052                 req.Depth = StepDepth.Into;
2053                 req.Size = StepSize.Line;
2054                 req.Enable ();
2055
2056                 step_req = req;
2057
2058                 // Step into invoke2
2059                 vm.Resume ();
2060                 e = vm.GetNextEvent ();
2061                 Assert.IsTrue (e is StepEvent);
2062                 Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
2063
2064                 req.Disable ();
2065
2066                 frame = e.Thread.GetFrames () [0];
2067         }
2068
2069         [Test]
2070         public void Exceptions () {
2071                 Event e = run_until ("exceptions");
2072                 var req = vm.CreateExceptionRequest (null);
2073                 req.Enable ();
2074
2075                 vm.Resume ();
2076
2077                 e = vm.GetNextEvent ();
2078                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2079                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2080
2081                 var frames = e.Thread.GetFrames ();
2082                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2083                 req.Disable ();
2084
2085                 // exception type filter
2086
2087                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
2088                 req.Enable ();
2089
2090                 // Skip the throwing of the second OverflowException       
2091                 vm.Resume ();
2092
2093                 e = vm.GetNextEvent ();
2094                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2095                 Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
2096                 req.Disable ();
2097
2098                 // exception type filter for subclasses
2099                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
2100                 req.Enable ();
2101
2102                 vm.Resume ();
2103
2104                 e = vm.GetNextEvent ();
2105                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2106                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2107                 req.Disable ();
2108
2109                 // Implicit exceptions
2110                 req = vm.CreateExceptionRequest (null);
2111                 req.Enable ();
2112
2113                 vm.Resume ();
2114
2115                 e = vm.GetNextEvent ();
2116                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2117                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2118                 req.Disable ();
2119
2120                 // Argument checking
2121                 AssertThrows<ArgumentException> (delegate {
2122                                 vm.CreateExceptionRequest (e.Thread.Type);
2123                         });
2124         }
2125
2126         [Test]
2127         public void EventSets () {
2128                 //
2129                 // Create two filter which both match the same exception
2130                 //
2131                 Event e = run_until ("exceptions");
2132
2133                 var req = vm.CreateExceptionRequest (null);
2134                 req.Enable ();
2135
2136                 var req2 = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.OverflowException"));
2137                 req2.Enable ();
2138
2139                 vm.Resume ();
2140
2141                 var es = vm.GetNextEventSet ();
2142                 Assert.AreEqual (2, es.Events.Length);
2143
2144                 e = es [0];
2145                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2146                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2147
2148                 e = es [1];
2149                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2150                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2151
2152                 req.Disable ();
2153                 req2.Disable ();
2154         }
2155
2156         //
2157         // Test single threaded invokes during processing of nullref exceptions.
2158         // These won't work if the exception handling is done from the sigsegv signal
2159         // handler, since the sigsegv signal is disabled until control returns from the
2160         // signal handler.
2161         //
2162         [Test]
2163         [Category ("only3")]
2164         public void NullRefExceptionAndSingleThreadedInvoke () {
2165                 Event e = run_until ("exceptions");
2166                 var req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.NullReferenceException"));
2167                 req.Enable ();
2168
2169                 vm.Resume ();
2170
2171                 e = vm.GetNextEvent ();
2172                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2173                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2174
2175                 var ex = (e as ExceptionEvent).Exception;
2176                 var tostring_method = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2177                 ex.InvokeMethod (e.Thread, tostring_method, null, InvokeOptions.SingleThreaded);
2178         }
2179
2180         [Test]
2181         public void Domains () {
2182                 vm.Dispose ();
2183
2184                 Start (new string [] { "dtest-app.exe", "domain-test" });
2185
2186                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
2187
2188                 Event e = run_until ("domains");
2189
2190                 vm.Resume ();
2191                 
2192                 e = vm.GetNextEvent ();
2193                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
2194
2195                 var domain = (e as AppDomainCreateEvent).Domain;
2196
2197                 // Run until the callback in the domain
2198                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
2199                 Assert.IsNotNull (m);
2200                 vm.SetBreakpoint (m, 0);
2201
2202                 while (true) {
2203                         vm.Resume ();
2204                         e = vm.GetNextEvent ();
2205                         if (e is BreakpointEvent)
2206                                 break;
2207                 }
2208
2209                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
2210
2211                 // d_method is from another domain
2212                 MethodMirror d_method = (e as BreakpointEvent).Method;
2213                 Assert.IsTrue (m != d_method);
2214
2215                 var frames = e.Thread.GetFrames ();
2216                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
2217                 Assert.AreEqual ("invoke", frames [1].Method.Name);
2218                 Assert.AreEqual ("domains", frames [2].Method.Name);
2219
2220                 // Test breakpoints on already JITted methods in other domains
2221                 m = entry_point.DeclaringType.GetMethod ("invoke_in_domain_2");
2222                 Assert.IsNotNull (m);
2223                 vm.SetBreakpoint (m, 0);
2224
2225                 while (true) {
2226                         vm.Resume ();
2227                         e = vm.GetNextEvent ();
2228                         if (e is BreakpointEvent)
2229                                 break;
2230                 }
2231
2232                 Assert.AreEqual ("invoke_in_domain_2", (e as BreakpointEvent).Method.Name);
2233
2234                 // This is empty when receiving the AppDomainCreateEvent
2235                 Assert.AreEqual ("domain", domain.FriendlyName);
2236
2237                 // Run until the unload
2238                 while (true) {
2239                         vm.Resume ();
2240                         e = vm.GetNextEvent ();
2241                         if (e is AssemblyUnloadEvent) {
2242                                 continue;
2243                         } else {
2244                                 break;
2245                         }
2246                 }
2247                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
2248                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
2249
2250                 // Run past the unload
2251                 e = run_until ("domains_2");
2252
2253                 // Test access to unloaded types
2254                 // FIXME: Add an exception type for this
2255                 AssertThrows<Exception> (delegate {
2256                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
2257                         });
2258         }
2259
2260         [Test]
2261         public void DynamicMethods () {
2262                 Event e = run_until ("dyn_call");
2263
2264                 var m = e.Thread.GetFrames ()[1].Method;
2265                 Assert.AreEqual ("dyn_method", m.Name);
2266
2267                 // Test access to IL
2268                 var body = m.GetMethodBody ();
2269
2270                 ILInstruction ins = body.Instructions [0];
2271                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2272                 Assert.AreEqual ("FOO", ins.Operand);
2273         }
2274
2275         [Test]
2276         public void RefEmit () {
2277                 vm.Dispose ();
2278
2279                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
2280
2281                 Event e = run_until ("ref_emit_call");
2282
2283                 var m = e.Thread.GetFrames ()[1].Method;
2284                 Assert.AreEqual ("ref_emit_method", m.Name);
2285
2286                 // Test access to IL
2287                 var body = m.GetMethodBody ();
2288
2289                 ILInstruction ins;
2290
2291                 ins = body.Instructions [0];
2292                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2293                 Assert.AreEqual ("FOO", ins.Operand);
2294
2295                 ins = body.Instructions [1];
2296                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
2297                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
2298                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
2299         }
2300
2301         [Test]
2302         public void IsAttached () {
2303                 var f = entry_point.DeclaringType.GetField ("is_attached");
2304
2305                 Event e = run_until ("Main");
2306
2307                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
2308         }
2309
2310         [Test]
2311         public void StackTraceInNative () {
2312                 // Check that stack traces can be produced for threads in native code
2313                 vm.Dispose ();
2314
2315                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
2316
2317                 var e = run_until ("frames_in_native");
2318
2319                 // FIXME: This is racy
2320                 vm.Resume ();
2321
2322                 Thread.Sleep (100);
2323
2324                 vm.Suspend ();
2325
2326                 StackFrame[] frames = e.Thread.GetFrames ();
2327
2328                 int frame_index = -1;
2329                 for (int i = 0; i < frames.Length; ++i) {
2330                         if (frames [i].Method.Name == "Sleep") {
2331                                 frame_index = i;
2332                                 break;
2333                         }
2334                 }
2335
2336                 Assert.IsTrue (frame_index != -1);
2337                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
2338                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
2339                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
2340
2341                 // Check that invokes are disabled for such threads
2342                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
2343
2344                 // return void
2345                 var m = t.GetMethod ("invoke_static_return_void");
2346                 AssertThrows<InvalidOperationException> (delegate {
2347                                 t.InvokeMethod (e.Thread, m, null);
2348                         });
2349         }
2350
2351         [Test]
2352         public void VirtualMachine_CreateEnumMirror () {
2353                 var e = run_until ("o1");
2354                 var frame = e.Thread.GetFrames () [0];
2355
2356                 object val = frame.GetThis ();
2357                 Assert.IsTrue (val is ObjectMirror);
2358                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
2359                 ObjectMirror o = (val as ObjectMirror);
2360
2361                 FieldInfoMirror field = o.Type.GetField ("field_enum");
2362                 Value f = o.GetValue (field);
2363                 TypeMirror enumType = (f as EnumMirror).Type;
2364
2365                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
2366                 f = o.GetValue (field);
2367                 Assert.AreEqual (1, (f as EnumMirror).Value);
2368
2369                 // Argument checking
2370                 AssertThrows<ArgumentNullException> (delegate () {
2371                                 vm.CreateEnumMirror (enumType, null);
2372                         });
2373
2374                 AssertThrows<ArgumentNullException> (delegate () {
2375                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
2376                         });
2377
2378                 // null value
2379                 AssertThrows<ArgumentException> (delegate () {
2380                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
2381                         });
2382
2383                 // value of a wrong type
2384                 AssertThrows<ArgumentException> (delegate () {
2385                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
2386                         });
2387         }
2388
2389         [Test]
2390         public void VirtualMachine_EnableEvents_Breakpoint () {
2391                 AssertThrows<ArgumentException> (delegate () {
2392                                 vm.EnableEvents (EventType.Breakpoint);
2393                         });
2394         }
2395 }