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