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