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