2010-01-28 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         BreakpointEvent run_until (string name) {
81                 // String
82                 MethodMirror m = entry_point.DeclaringType.GetMethod (name);
83                 Assert.IsNotNull (m);
84                 vm.SetBreakpoint (m, 0);
85
86                 Event e = null;
87
88                 while (true) {
89                         vm.Resume ();
90                         e = vm.GetNextEvent ();
91                         if (e is BreakpointEvent)
92                                 break;
93                 }
94
95                 Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
96                 Assert.AreEqual (m, (e as BreakpointEvent).Method);
97
98                 return (e as BreakpointEvent);
99         }
100
101         Event single_step (ThreadMirror t) {
102                 var req = vm.CreateStepRequest (t);
103                 req.Enable ();
104
105                 vm.Resume ();
106                 Event e = vm.GetNextEvent ();
107                 Assert.IsTrue (e is StepEvent);
108
109                 req.Disable ();
110
111                 return e;
112         }
113
114         void check_arg_val (StackFrame frame, int pos, Type type, object eval) {
115                 object val = frame.GetArgument (pos);
116                 Assert.IsTrue (val is PrimitiveValue);
117                 object v = (val as PrimitiveValue).Value;
118                 Assert.AreEqual (type, v.GetType ());
119                 if (eval is float)
120                         Assert.IsTrue (Math.Abs ((float)eval - (float)v) < 0.0001);
121                 else if (eval is double)
122                         Assert.IsTrue (Math.Abs ((double)eval - (double)v) < 0.0001);
123                 else
124                         Assert.AreEqual (eval, v);
125         }
126
127         void AssertValue (object expected, object val) {
128                 if (expected is string) {
129                         Assert.IsTrue (val is StringMirror);
130                         Assert.AreEqual (expected, (val as StringMirror).Value);
131                 } else if (val is StructMirror && (val as StructMirror).Type.Name == "IntPtr") {
132                         AssertValue (expected, (val as StructMirror).Fields [0]);
133                 } else {
134                         Assert.IsTrue (val is PrimitiveValue);
135                         Assert.AreEqual (expected, (val as PrimitiveValue).Value);
136                 }
137         }
138
139         [SetUp]
140         public void SetUp () {
141                 Start (new string [] { "dtest-app.exe" });
142         }
143
144         [TearDown]
145         public void TearDown () {
146                 if (vm == null)
147                         return;
148
149                 if (step_req != null)
150                         step_req.Disable ();
151
152                 vm.Resume ();
153                 while (true) {
154                         Event e = vm.GetNextEvent ();
155
156                         if (e is VMDeathEvent)
157                                 break;
158
159                         vm.Resume ();
160                 }
161         }
162
163         [Test]
164         public void SimpleBreakpoint () {
165                 Event e;
166
167                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp1");
168                 Assert.IsNotNull (m);
169
170                 vm.SetBreakpoint (m, 0);
171
172                 vm.Resume ();
173
174                 e = vm.GetNextEvent ();
175                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
176                 Assert.IsTrue (e is BreakpointEvent);
177                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
178
179                 // Argument checking
180                 AssertThrows<ArgumentException> (delegate {
181                                 // Invalid IL offset
182                                 vm.SetBreakpoint (m, 1);
183                         });
184         }
185
186         [Test]
187         public void BreakpointsSameLocation () {
188                 Event e;
189
190                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp2");
191                 Assert.IsNotNull (m);
192
193                 vm.SetBreakpoint (m, 0);
194                 vm.SetBreakpoint (m, 0);
195
196                 vm.Resume ();
197
198                 e = vm.GetNextEvent ();
199                 Assert.IsTrue (e is BreakpointEvent);
200                 Assert.AreEqual (m, (e as BreakpointEvent).Method);
201
202                 e = vm.GetNextEvent ();
203                 Assert.IsTrue (e is BreakpointEvent);
204                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
205         }
206
207         [Test]
208         public void BreakpointAlreadyJITted () {
209                 Event e = run_until ("bp1");
210
211                 /* Place a breakpoint on bp3 */
212                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp3");
213                 Assert.IsNotNull (m);
214                 vm.SetBreakpoint (m, 0);
215
216                 /* Same with generic instances */
217                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp7");
218                 Assert.IsNotNull (m2);
219                 vm.SetBreakpoint (m2, 0);
220
221                 vm.Resume ();
222
223                 e = vm.GetNextEvent ();
224                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
225                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
226
227                 vm.Resume ();
228
229                 /* Non-shared instance */
230                 e = vm.GetNextEvent ();
231                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
232                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
233
234                 vm.Resume ();
235
236                 /* Shared instance */
237                 e = vm.GetNextEvent ();
238                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
239                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
240         }
241
242         [Test]
243         public void ClearBreakpoint () {
244                 Event e;
245
246                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
247                 Assert.IsNotNull (m);
248                 EventRequest req1 = vm.SetBreakpoint (m, 0);
249                 EventRequest req2 = vm.SetBreakpoint (m, 0);
250
251                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
252                 Assert.IsNotNull (m2);
253                 vm.SetBreakpoint (m2, 0);
254
255                 /* Run until bp4 */
256                 vm.Resume ();
257
258                 e = vm.GetNextEvent ();
259                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
260                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
261                 e = vm.GetNextEvent ();
262                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
263                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
264
265                 /* Clear one of them */
266                 req1.Disable ();
267
268                 vm.Resume ();
269
270                 e = vm.GetNextEvent ();
271                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
272                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
273
274                 /* Clear the other */
275                 req2.Disable ();
276
277                 vm.Resume ();
278
279                 e = vm.GetNextEvent ();
280                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
281                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
282         }
283
284         [Test]
285         public void ClearAllBreakpoints () {
286                 Event e;
287
288                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
289                 Assert.IsNotNull (m);
290                 vm.SetBreakpoint (m, 0);
291
292                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
293                 Assert.IsNotNull (m2);
294                 vm.SetBreakpoint (m2, 0);
295
296                 vm.ClearAllBreakpoints ();
297
298                 vm.Resume ();
299
300                 e = vm.GetNextEvent ();
301                 Assert.IsTrue (!(e is BreakpointEvent));
302                 if (e is VMDeathEvent)
303                         vm = null;
304         }
305
306         [Test]
307         public void BreakpointOnGShared () {
308                 Event e;
309
310                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp6");
311                 Assert.IsNotNull (m);
312
313                 vm.SetBreakpoint (m, 0);
314
315                 vm.Resume ();
316
317                 e = vm.GetNextEvent ();
318                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
319                 Assert.IsTrue (e is BreakpointEvent);
320                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
321         }
322
323         [Test]
324         public void SingleStepping () {
325                 Event e = run_until ("single_stepping");
326
327                 var req = vm.CreateStepRequest (e.Thread);
328                 req.Enable ();
329
330                 step_req = req;
331
332                 // Step into ss1
333                 vm.Resume ();
334                 e = vm.GetNextEvent ();
335                 Assert.IsTrue (e is StepEvent);
336                 Assert.AreEqual ("ss1", (e as StepEvent).Method.Name);
337
338                 // Step out of ss1
339                 vm.Resume ();
340                 e = vm.GetNextEvent ();
341                 Assert.IsTrue (e is StepEvent);
342                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
343
344                 // Change to step over
345                 req.Disable ();
346                 req.Depth = StepDepth.Over;
347                 req.Enable ();
348
349                 // Step over ss2
350                 vm.Resume ();
351                 e = vm.GetNextEvent ();
352                 Assert.IsTrue (e is StepEvent);
353                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
354
355                 // Change to step into
356                 req.Disable ();
357                 req.Depth = StepDepth.Into;
358                 req.Enable ();
359
360                 // Step into ss3
361                 vm.Resume ();
362                 e = vm.GetNextEvent ();
363                 Assert.IsTrue (e is StepEvent);
364                 Assert.AreEqual ("ss3", (e as StepEvent).Method.Name);
365
366                 // Change to step out
367                 req.Disable ();
368                 req.Depth = StepDepth.Out;
369                 req.Enable ();
370
371                 // Step back into single_stepping
372                 vm.Resume ();
373                 e = vm.GetNextEvent ();
374                 Assert.IsTrue (e is StepEvent);
375                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
376
377                 // Change to step into
378                 req.Disable ();
379                 req.Depth = StepDepth.Into;
380                 req.Enable ();
381
382                 // Step into ss3_2 ()
383                 vm.Resume ();
384                 e = vm.GetNextEvent ();
385                 Assert.IsTrue (e is StepEvent);
386                 Assert.AreEqual ("ss3_2", (e as StepEvent).Method.Name);
387
388                 // Change to step over
389                 req.Disable ();
390                 req.Depth = StepDepth.Over;
391                 req.Enable ();
392
393                 // Step over ss3_2_2 ()
394                 vm.Resume ();
395                 e = vm.GetNextEvent ();
396                 Assert.IsTrue (e is StepEvent);
397                 Assert.AreEqual ("ss3_2", (e as StepEvent).Method.Name);
398
399                 // Recreate the request
400                 req.Disable ();
401                 req.Enable ();
402
403                 // Step back into single_stepping () with the new request
404                 vm.Resume ();
405                 e = vm.GetNextEvent ();
406                 Assert.IsTrue (e is StepEvent);
407                 Assert.AreEqual ("single_stepping", (e as StepEvent).Method.Name);
408
409                 // Change to step into
410                 req.Disable ();
411                 req.Depth = StepDepth.Into;
412                 req.Enable ();
413
414                 // Step into ss4 ()
415                 vm.Resume ();
416                 e = vm.GetNextEvent ();
417                 Assert.IsTrue (e is StepEvent);
418                 Assert.AreEqual ("ss4", (e as StepEvent).Method.Name);
419
420                 // Change to StepSize.Line
421                 req.Disable ();
422                 req.Depth = StepDepth.Over;
423                 req.Size = StepSize.Line;
424                 req.Enable ();
425
426                 // Step over ss1 (); ss1 ();
427                 vm.Resume ();
428                 e = vm.GetNextEvent ();
429                 Assert.IsTrue (e is StepEvent);
430
431                 // Step into ss2 ()
432                 req.Disable ();
433                 req.Depth = StepDepth.Into;
434                 req.Enable ();
435
436                 vm.Resume ();
437                 e = vm.GetNextEvent ();
438                 Assert.IsTrue (e is StepEvent);
439                 Assert.AreEqual ("ss2", (e as StepEvent).Method.Name);
440
441                 req.Disable ();
442
443                 // Run until ss5
444                 e = run_until ("ss5");
445
446                 // Add an assembly filter
447                 req.AssemblyFilter = new AssemblyMirror [] { (e as BreakpointEvent).Method.DeclaringType.Assembly };
448                 req.Enable ();
449
450                 // Step into is_even, skipping the linq stuff
451                 vm.Resume ();
452                 e = vm.GetNextEvent ();
453                 Assert.IsTrue (e is StepEvent);
454                 Assert.AreEqual ("is_even", (e as StepEvent).Method.Name);
455
456                 // FIXME: Check that single stepping works with lock (obj)
457                 
458                 req.Disable ();
459
460                 // Run until ss6
461                 e = run_until ("ss6");
462
463                 req = vm.CreateStepRequest (e.Thread);
464                 req.Depth = StepDepth.Over;
465                 req.Enable ();
466
467                 // Check that single stepping works in out-of-line bblocks
468                 vm.Resume ();
469                 e = vm.GetNextEvent ();
470                 Assert.IsTrue (e is StepEvent);
471                 vm.Resume ();
472                 e = vm.GetNextEvent ();
473                 Assert.IsTrue (e is StepEvent);
474                 Assert.AreEqual ("ss6", (e as StepEvent).Method.Name);
475
476                 req.Disable ();
477         }
478
479         [Test]
480         public void MethodEntryExit () {
481                 run_until ("single_stepping");
482
483                 var req1 = vm.CreateMethodEntryRequest ();
484                 var req2 = vm.CreateMethodExitRequest ();
485
486                 req1.Enable ();
487                 req2.Enable ();
488
489                 vm.Resume ();
490                 Event e = vm.GetNextEvent ();
491                 Assert.IsTrue (e is MethodEntryEvent);
492                 Assert.AreEqual ("ss1", (e as MethodEntryEvent).Method.Name);
493
494                 vm.Resume ();
495                 e = vm.GetNextEvent ();
496                 Assert.IsTrue (e is MethodExitEvent);
497                 Assert.AreEqual ("ss1", (e as MethodExitEvent).Method.Name);
498
499                 req1.Disable ();
500                 req2.Disable ();
501         }
502
503         [Test]
504         public void CountFilter () {
505                 run_until ("single_stepping");
506
507                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("ss3");
508                 Assert.IsNotNull (m2);
509                 vm.SetBreakpoint (m2, 0);
510
511                 var req1 = vm.CreateMethodEntryRequest ();
512                 req1.Count = 2;
513                 req1.Enable ();
514
515                 // Enter ss2, ss1 is skipped
516                 vm.Resume ();
517                 Event e = vm.GetNextEvent ();
518                 Assert.IsTrue (e is MethodEntryEvent);
519                 Assert.AreEqual ("ss2", (e as MethodEntryEvent).Method.Name);
520
521                 // Breakpoint on ss3, the entry event is no longer reported
522                 vm.Resume ();
523                 e = vm.GetNextEvent ();
524                 Assert.IsTrue (e is BreakpointEvent);
525
526                 req1.Disable ();
527         }
528
529         [Test]
530         public void Arguments () {
531                 object val;
532
533                 var e = run_until ("arg1");
534
535                 StackFrame frame = e.Thread.GetFrames () [0];
536
537                 check_arg_val (frame, 0, typeof (sbyte), SByte.MaxValue - 5);
538                 check_arg_val (frame, 1, typeof (byte), Byte.MaxValue - 5);
539                 check_arg_val (frame, 2, typeof (bool), true);
540                 check_arg_val (frame, 3, typeof (short), Int16.MaxValue - 5);
541                 check_arg_val (frame, 4, typeof (ushort), UInt16.MaxValue - 5);
542                 check_arg_val (frame, 5, typeof (char), 'F');
543                 check_arg_val (frame, 6, typeof (int), Int32.MaxValue - 5);
544                 check_arg_val (frame, 7, typeof (uint), UInt32.MaxValue - 5);
545                 check_arg_val (frame, 8, typeof (long), Int64.MaxValue - 5);
546                 check_arg_val (frame, 9, typeof (ulong), UInt64.MaxValue - 5);
547                 check_arg_val (frame, 10, typeof (float), 1.2345f);
548                 check_arg_val (frame, 11, typeof (double), 6.78910);
549
550                 e = run_until ("arg2");
551
552                 frame = e.Thread.GetFrames () [0];
553
554                 // String
555                 val = frame.GetArgument (0);
556                 AssertValue ("FOO", val);
557                 Assert.AreEqual ("String", (val as ObjectMirror).Type.Name);
558
559                 // null
560                 val = frame.GetArgument (1);
561                 AssertValue (null, val);
562
563                 // object
564                 val = frame.GetArgument (2);
565                 AssertValue ("BLA", val);
566
567                 // byref
568                 val = frame.GetArgument (3);
569                 AssertValue (42, val);
570
571                 // generic instance
572                 val = frame.GetArgument (4);
573                 Assert.IsTrue (val is ObjectMirror);
574                 Assert.AreEqual ("GClass`1", (val as ObjectMirror).Type.Name);
575
576                 // System.Object
577                 val = frame.GetArgument (5);
578                 Assert.IsTrue (val is ObjectMirror);
579                 Assert.AreEqual ("Object", (val as ObjectMirror).Type.Name);
580
581                 // this on static methods
582                 val = frame.GetThis ();
583                 AssertValue (null, val);
584
585                 e = run_until ("arg3");
586
587                 frame = e.Thread.GetFrames () [0];
588
589                 // this
590                 val = frame.GetThis ();
591                 Assert.IsTrue (val is ObjectMirror);
592                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
593
594                 // objref in register
595                 val = frame.GetArgument (0);
596                 AssertValue ("BLA", val);
597         }
598
599         [Test]
600         public void Arrays () {
601                 object val;
602
603                 var e = run_until ("o2");
604
605                 StackFrame frame = e.Thread.GetFrames () [0];
606
607                 // String[]
608                 val = frame.GetArgument (0);
609                 Assert.IsTrue (val is ArrayMirror);
610                 ArrayMirror arr = val as ArrayMirror;
611                 Assert.AreEqual (2, arr.Length);
612                 AssertValue ("BAR", arr [0]);
613                 AssertValue ("BAZ", arr [1]);
614
615                 var vals = arr.GetValues (0, 2);
616                 Assert.AreEqual (2, vals.Count);
617                 AssertValue ("BAR", vals [0]);
618                 AssertValue ("BAZ", vals [1]);
619
620                 arr [0] = vm.RootDomain.CreateString ("ABC");
621                 AssertValue ("ABC", arr [0]);
622
623                 arr [0] = vm.CreateValue (null);
624                 AssertValue (null, arr [0]);
625
626                 arr.SetValues (0, new Value [] { vm.RootDomain.CreateString ("D1"), vm.RootDomain.CreateString ("D2") });
627                 AssertValue ("D1", arr [0]);
628                 AssertValue ("D2", arr [1]);
629
630                 // int
631                 val = frame.GetArgument (1);
632                 Assert.IsTrue (val is ArrayMirror);
633                 arr = val as ArrayMirror;
634                 Assert.AreEqual (2, arr.Length);
635                 AssertValue (42, arr [0]);
636                 AssertValue (43, arr [1]);
637
638                 // Argument checking
639                 AssertThrows<IndexOutOfRangeException> (delegate () {
640                                 val = arr [2];
641                         });
642
643                 AssertThrows<IndexOutOfRangeException> (delegate () {
644                                 val = arr [Int32.MinValue];
645                         });
646
647                 AssertThrows<IndexOutOfRangeException> (delegate () {
648                                 vals = arr.GetValues (0, 3);
649                         });
650
651                 AssertThrows<IndexOutOfRangeException> (delegate () {
652                                 arr [2] = vm.CreateValue (null);
653                         });
654
655                 AssertThrows<IndexOutOfRangeException> (delegate () {
656                                 arr [Int32.MinValue] = vm.CreateValue (null);
657                         });
658
659                 AssertThrows<IndexOutOfRangeException> (delegate () {
660                                 arr.SetValues (0, new Value [] { null, null, null });
661                         });
662
663                 // Multidim arrays
664                 val = frame.GetArgument (2);
665                 Assert.IsTrue (val is ArrayMirror);
666                 arr = val as ArrayMirror;
667                 Assert.AreEqual (2, arr.Rank);
668                 Assert.AreEqual (4, arr.Length);
669                 Assert.AreEqual (2, arr.GetLength (0));
670                 Assert.AreEqual (2, arr.GetLength (1));
671                 Assert.AreEqual (0, arr.GetLowerBound (0));
672                 Assert.AreEqual (0, arr.GetLowerBound (1));
673                 vals = arr.GetValues (0, 4);
674                 AssertValue (1, vals [0]);
675                 AssertValue (2, vals [1]);
676                 AssertValue (3, vals [2]);
677                 AssertValue (4, vals [3]);
678
679                 val = frame.GetArgument (3);
680                 Assert.IsTrue (val is ArrayMirror);
681                 arr = val as ArrayMirror;
682                 Assert.AreEqual (2, arr.Rank);
683                 Assert.AreEqual (4, arr.Length);
684                 Assert.AreEqual (2, arr.GetLength (0));
685                 Assert.AreEqual (2, arr.GetLength (1));
686                 Assert.AreEqual (1, arr.GetLowerBound (0));
687                 Assert.AreEqual (3, arr.GetLowerBound (1));
688
689                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
690                                 arr.GetLength (-1);
691                         });
692                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
693                                 arr.GetLength (2);
694                         });
695
696                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
697                                 arr.GetLowerBound (-1);
698                         });
699                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
700                                 arr.GetLowerBound (2);
701                         });
702
703                 // arrays treated as generic collections
704                 val = frame.GetArgument (4);
705                 Assert.IsTrue (val is ArrayMirror);
706                 arr = val as ArrayMirror;
707         }
708
709         [Test]
710         public void Object_GetValue () {
711                 var e = run_until ("o1");
712                 var frame = e.Thread.GetFrames () [0];
713
714                 object val = frame.GetThis ();
715                 Assert.IsTrue (val is ObjectMirror);
716                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
717                 ObjectMirror o = (val as ObjectMirror);
718
719                 TypeMirror t = o.Type;
720
721                 // object fields
722                 object f = o.GetValue (t.GetField ("field_i"));
723                 AssertValue (42, f);
724                 f = o.GetValue (t.GetField ("field_s"));
725                 AssertValue ("S", f);
726                 f = o.GetValue (t.GetField ("field_enum"));
727                 Assert.IsTrue (f is EnumMirror);
728                 Assert.AreEqual (1, (f as EnumMirror).Value);
729                 Assert.AreEqual ("B", (f as EnumMirror).StringValue);
730
731                 // Inherited object fields
732                 TypeMirror parent = t.BaseType;
733                 f = o.GetValue (parent.GetField ("base_field_i"));
734                 AssertValue (43, f);
735                 f = o.GetValue (parent.GetField ("base_field_s"));
736                 AssertValue ("T", f);
737
738                 // Static fields
739                 f = o.GetValue (o.Type.GetField ("static_i"));
740                 AssertValue (55, f);
741
742                 // generic instances
743                 ObjectMirror o2 = frame.GetValue (frame.Method.GetParameters ()[1]) as ObjectMirror;
744                 Assert.AreEqual ("GClass`1", o2.Type.Name);
745                 TypeMirror t2 = o2.Type;
746                 f = o2.GetValue (t2.GetField ("field"));
747                 AssertValue (42, f);
748
749                 ObjectMirror o3 = frame.GetValue (frame.Method.GetParameters ()[2]) as ObjectMirror;
750                 Assert.AreEqual ("GClass`1", o3.Type.Name);
751                 TypeMirror t3 = o3.Type;
752                 f = o3.GetValue (t3.GetField ("field"));
753                 AssertValue ("FOO", f);
754
755                 // Argument checking
756                 AssertThrows<ArgumentNullException> (delegate () {
757                         o.GetValue (null);
758                         });
759         }
760
761         [Test]
762         public void Object_GetValues () {
763                 var e = run_until ("o1");
764                 var frame = e.Thread.GetFrames () [0];
765
766                 object val = frame.GetThis ();
767                 Assert.IsTrue (val is ObjectMirror);
768                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
769                 ObjectMirror o = (val as ObjectMirror);
770
771                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
772
773                 TypeMirror t = o.Type;
774
775                 object[] vals = o.GetValues (new FieldInfoMirror [] { t.GetField ("field_i"), t.GetField ("field_s") });
776                 object f = vals [0];
777                 AssertValue (42, f);
778                 f = vals [1];
779                 AssertValue ("S", f);
780
781                 // Argument checking
782                 AssertThrows<ArgumentNullException> (delegate () {
783                         o.GetValues (null);
784                         });
785
786                 AssertThrows<ArgumentNullException> (delegate () {
787                         o.GetValues (new FieldInfoMirror [] { null });
788                         });
789
790                 // field of another class
791                 AssertThrows<ArgumentException> (delegate () {
792                                 o.GetValue (val2.Type.GetField ("field_j"));
793                         });
794         }
795
796         void TestSetValue (ObjectMirror o, string field_name, object val) {
797                 if (val is string)
798                         o.SetValue (o.Type.GetField (field_name), vm.RootDomain.CreateString ((string)val));
799                 else
800                         o.SetValue (o.Type.GetField (field_name), vm.CreateValue (val));
801                 Value f = o.GetValue (o.Type.GetField (field_name));
802                 AssertValue (val, f);
803         }
804
805         [Test]
806         public void Object_SetValues () {
807                 var e = run_until ("o1");
808                 var frame = e.Thread.GetFrames () [0];
809
810                 object val = frame.GetThis ();
811                 Assert.IsTrue (val is ObjectMirror);
812                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
813                 ObjectMirror o = (val as ObjectMirror);
814
815                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
816
817                 TestSetValue (o, "field_i", 22);
818                 TestSetValue (o, "field_bool1", false);
819                 TestSetValue (o, "field_bool2", true);
820                 TestSetValue (o, "field_char", 'B');
821                 TestSetValue (o, "field_byte", (byte)129);
822                 TestSetValue (o, "field_sbyte", (sbyte)-33);
823                 TestSetValue (o, "field_short", (short)(Int16.MaxValue - 5));
824                 TestSetValue (o, "field_ushort", (ushort)(UInt16.MaxValue - 5));
825                 TestSetValue (o, "field_long", Int64.MaxValue - 5);
826                 TestSetValue (o, "field_ulong", (ulong)(UInt64.MaxValue - 5));
827                 TestSetValue (o, "field_float", 6.28f);
828                 TestSetValue (o, "field_double", 6.28);
829                 TestSetValue (o, "static_i", 23);
830                 TestSetValue (o, "field_s", "CDEF");
831
832                 Value f;
833
834                 // intptrs
835                 f = o.GetValue (o.Type.GetField ("field_intptr"));
836                 Assert.IsInstanceOfType (typeof (StructMirror), f);
837                 AssertValue (Int32.MaxValue - 5, (f as StructMirror).Fields [0]);
838
839                 // enums
840
841                 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, EventType.AssemblyUnload);
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                 while (true) {
2073                         vm.Resume ();
2074                         e = vm.GetNextEvent ();
2075                         if (e is AssemblyUnloadEvent) {
2076                                 continue;
2077                         } else {
2078                                 break;
2079                         }
2080                 }
2081                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
2082                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
2083
2084                 // Run past the unload
2085                 e = run_until ("domains_2");
2086
2087                 // Test access to unloaded types
2088                 // FIXME: Add an exception type for this
2089                 AssertThrows<Exception> (delegate {
2090                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
2091                         });
2092         }
2093
2094         [Test]
2095         public void DynamicMethods () {
2096                 Event e = run_until ("dyn_call");
2097
2098                 var m = e.Thread.GetFrames ()[1].Method;
2099                 Assert.AreEqual ("dyn_method", m.Name);
2100
2101                 // Test access to IL
2102                 var body = m.GetMethodBody ();
2103
2104                 ILInstruction ins = body.Instructions [0];
2105                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2106                 Assert.AreEqual ("FOO", ins.Operand);
2107         }
2108
2109         [Test]
2110         public void RefEmit () {
2111                 vm.Dispose ();
2112
2113                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
2114
2115                 Event e = run_until ("ref_emit_call");
2116
2117                 var m = e.Thread.GetFrames ()[1].Method;
2118                 Assert.AreEqual ("ref_emit_method", m.Name);
2119
2120                 // Test access to IL
2121                 var body = m.GetMethodBody ();
2122
2123                 ILInstruction ins;
2124
2125                 ins = body.Instructions [0];
2126                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2127                 Assert.AreEqual ("FOO", ins.Operand);
2128
2129                 ins = body.Instructions [1];
2130                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
2131                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
2132                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
2133         }
2134
2135         [Test]
2136         public void IsAttached () {
2137                 var f = entry_point.DeclaringType.GetField ("is_attached");
2138
2139                 Event e = run_until ("Main");
2140
2141                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
2142         }
2143
2144         [Test]
2145         public void StackTraceInNative () {
2146                 // Check that stack traces can be produced for threads in native code
2147                 vm.Dispose ();
2148
2149                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
2150
2151                 var e = run_until ("frames_in_native");
2152
2153                 // FIXME: This is racy
2154                 vm.Resume ();
2155
2156                 Thread.Sleep (100);
2157
2158                 vm.Suspend ();
2159
2160                 StackFrame[] frames = e.Thread.GetFrames ();
2161
2162                 int frame_index = -1;
2163                 for (int i = 0; i < frames.Length; ++i) {
2164                         if (frames [i].Method.Name == "Sleep") {
2165                                 frame_index = i;
2166                                 break;
2167                         }
2168                 }
2169
2170                 Assert.IsTrue (frame_index != -1);
2171                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
2172                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
2173                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
2174
2175                 // Check that invokes are disabled for such threads
2176                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
2177
2178                 // return void
2179                 var m = t.GetMethod ("invoke_static_return_void");
2180                 AssertThrows<InvalidOperationException> (delegate {
2181                                 t.InvokeMethod (e.Thread, m, null);
2182                         });
2183         }
2184 }