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