b785abc5da83fbda0bb9472ca443cbd6685b385c
[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                 FieldInfoMirror field = o.Type.GetField ("field_enum");
842                 f = o.GetValue (field);
843                 (f as EnumMirror).Value = 5;
844                 o.SetValue (field, f);
845                 f = o.GetValue (field);
846                 Assert.AreEqual (5, (f as EnumMirror).Value);
847
848                 // null
849                 o.SetValue (o.Type.GetField ("field_s"), vm.CreateValue (null));
850                 f = o.GetValue (o.Type.GetField ("field_s"));
851                 AssertValue (null, f);
852
853                 // vtype instances
854                 field = o.Type.GetField ("generic_field_struct");
855                 f = o.GetValue (field);
856                 o.SetValue (field, f);
857
858                 // Argument checking
859                 AssertThrows<ArgumentNullException> (delegate () {
860                                 o.SetValues (null, new Value [0]);
861                         });
862
863                 AssertThrows<ArgumentNullException> (delegate () {
864                                 o.SetValues (new FieldInfoMirror [0], null);
865                         });
866
867                 AssertThrows<ArgumentNullException> (delegate () {
868                                 o.SetValues (new FieldInfoMirror [] { null }, new Value [1] { null });
869                         });
870
871                 // vtype with a wrong type
872                 AssertThrows<ArgumentException> (delegate () {
873                                 o.SetValue (o.Type.GetField ("field_struct"), o.GetValue (o.Type.GetField ("field_enum")));
874                         });
875
876                 // reference type not assignment compatible
877                 AssertThrows<ArgumentException> (delegate () {
878                                 o.SetValue (o.Type.GetField ("field_class"), o);
879                         });
880
881                 // field of another class
882                 AssertThrows<ArgumentException> (delegate () {
883                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
884                         });
885         }
886
887         [Test]
888         public void Type_SetValue () {
889                 var e = run_until ("o1");
890                 var frame = e.Thread.GetFrames () [0];
891                 Value f;
892
893                 object val = frame.GetThis ();
894                 Assert.IsTrue (val is ObjectMirror);
895                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
896                 ObjectMirror o = (val as ObjectMirror);
897
898                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
899
900                 o.Type.SetValue (o.Type.GetField ("static_i"), vm.CreateValue (55));
901                 f = o.Type.GetValue (o.Type.GetField ("static_i"));
902                 AssertValue (55, f);
903
904                 // Argument checking
905                 AssertThrows<ArgumentNullException> (delegate () {
906                                 o.Type.SetValue (null, vm.CreateValue (0));
907                         });
908
909                 AssertThrows<ArgumentNullException> (delegate () {
910                                 o.Type.SetValue (o.Type.GetField ("static_i"), null);
911                         });
912
913                 // field of another class
914                 AssertThrows<ArgumentException> (delegate () {
915                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
916                         });
917         }
918
919         [Test]
920         public void TypeInfo () {
921                 Event e = run_until ("ti2");
922                 StackFrame frame = e.Thread.GetFrames () [0];
923
924                 TypeMirror t;
925
926                 // Array types
927                 t = frame.Method.GetParameters ()[0].ParameterType;
928
929                 Assert.AreEqual ("String[]", t.Name);
930                 Assert.AreEqual ("string[]", t.CSharpName);
931                 Assert.AreEqual ("Array", t.BaseType.Name);
932                 Assert.AreEqual (true, t.HasElementType);
933                 Assert.AreEqual (true, t.IsArray);
934                 Assert.AreEqual (1, t.GetArrayRank ());
935                 Assert.AreEqual ("String", t.GetElementType ().Name);
936
937                 t = frame.Method.GetParameters ()[2].ParameterType;
938
939                 Assert.AreEqual ("Int32[,]", t.Name);
940                 // FIXME:
941                 //Assert.AreEqual ("int[,]", t.CSharpName);
942                 Assert.AreEqual ("Array", t.BaseType.Name);
943                 Assert.AreEqual (true, t.HasElementType);
944                 Assert.AreEqual (true, t.IsArray);
945                 Assert.AreEqual (2, t.GetArrayRank ());
946                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
947
948                 // Byref types
949                 t = frame.Method.GetParameters ()[3].ParameterType;
950                 // FIXME:
951                 //Assert.AreEqual ("Int32&", t.Name);
952                 //Assert.AreEqual (true, t.IsByRef);
953                 //Assert.AreEqual (true, t.HasElementType);
954
955                 // Pointer types
956                 t = frame.Method.GetParameters ()[4].ParameterType;
957                 // FIXME:
958                 //Assert.AreEqual ("Int32*", t.Name);
959                 Assert.AreEqual (true, t.IsPointer);
960                 Assert.AreEqual (true, t.HasElementType);
961                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
962                 Assert.AreEqual (false, t.IsPrimitive);
963
964                 // primitive types 
965                 t = frame.Method.GetParameters ()[5].ParameterType;
966                 Assert.AreEqual (true, t.IsPrimitive);
967
968                 // value types
969                 t = frame.Method.GetParameters ()[6].ParameterType;
970                 Assert.AreEqual ("AStruct", t.Name);
971                 Assert.AreEqual (false, t.IsPrimitive);
972                 Assert.AreEqual (true, t.IsValueType);
973                 Assert.AreEqual (false, t.IsClass);
974
975                 // reference types
976                 t = frame.Method.GetParameters ()[7].ParameterType;
977                 Assert.AreEqual ("Tests", t.Name);
978                 var nested = (from nt in t.GetNestedTypes () where nt.IsNestedPublic select nt).ToArray ();
979                 Assert.AreEqual (1, nested.Length);
980                 Assert.AreEqual ("NestedClass", nested [0].Name);
981                 Assert.IsTrue (t.BaseType.IsAssignableFrom (t));
982                 Assert.IsTrue (!t.IsAssignableFrom (t.BaseType));
983
984                 // generic instances
985                 t = frame.Method.GetParameters ()[9].ParameterType;
986                 Assert.AreEqual ("GClass`1", t.Name);
987
988                 // enums
989                 t = frame.Method.GetParameters ()[10].ParameterType;
990                 Assert.AreEqual ("AnEnum", t.Name);
991                 Assert.IsTrue (t.IsEnum);
992                 Assert.AreEqual ("Int32", t.EnumUnderlyingType.Name);
993
994                 // properties
995                 t = frame.Method.GetParameters ()[7].ParameterType;
996
997                 var props = t.GetProperties ();
998                 Assert.AreEqual (3, props.Length);
999                 foreach (PropertyInfoMirror prop in props) {
1000                         ParameterInfoMirror[] indexes = prop.GetIndexParameters ();
1001
1002                         if (prop.Name == "IntProperty") {
1003                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1004                                 Assert.AreEqual ("get_IntProperty", prop.GetGetMethod ().Name);
1005                                 Assert.AreEqual ("set_IntProperty", prop.GetSetMethod ().Name);
1006                                 Assert.AreEqual (0, indexes.Length);
1007                         } else if (prop.Name == "ReadOnlyProperty") {
1008                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1009                                 Assert.AreEqual ("get_ReadOnlyProperty", prop.GetGetMethod ().Name);
1010                                 Assert.AreEqual (null, prop.GetSetMethod ());
1011                                 Assert.AreEqual (0, indexes.Length);
1012                         } else if (prop.Name == "IndexedProperty") {
1013                                 Assert.AreEqual (1, indexes.Length);
1014                                 Assert.AreEqual ("Int32", indexes [0].ParameterType.Name);
1015                         }
1016                 }
1017
1018                 // custom attributes
1019                 t = frame.Method.GetParameters ()[8].ParameterType;
1020                 Assert.AreEqual ("Tests2", t.Name);
1021                 var attrs = t.GetCustomAttributes (true);
1022                 Assert.AreEqual (2, attrs.Length);
1023                 foreach (var attr in attrs) {
1024                         if (attr.Constructor.DeclaringType.Name == "DebuggerDisplayAttribute") {
1025                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1026                                 Assert.AreEqual ("Tests", attr.ConstructorArguments [0].Value);
1027                                 Assert.AreEqual (2, attr.NamedArguments.Count);
1028                                 Assert.AreEqual ("Name", attr.NamedArguments [0].Property.Name);
1029                                 Assert.AreEqual ("FOO", attr.NamedArguments [0].TypedValue.Value);
1030                                 Assert.AreEqual ("Target", attr.NamedArguments [1].Property.Name);
1031                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.NamedArguments [1].TypedValue.Value);
1032                                 Assert.AreEqual ("Int32", (attr.NamedArguments [1].TypedValue.Value as TypeMirror).Name);
1033                         } else if (attr.Constructor.DeclaringType.Name == "DebuggerTypeProxyAttribute") {
1034                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1035                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.ConstructorArguments [0].Value);
1036                                 Assert.AreEqual ("Tests", (attr.ConstructorArguments [0].Value as TypeMirror).Name);
1037                         } else {
1038                                 Assert.Fail (attr.Constructor.DeclaringType.Name);
1039                         }
1040                 }
1041         }
1042
1043         [Test]
1044         public void FieldInfo () {
1045                 Event e = run_until ("ti2");
1046                 StackFrame frame = e.Thread.GetFrames () [0];
1047
1048                 TypeMirror t;
1049
1050                 t = frame.Method.GetParameters ()[8].ParameterType;
1051                 Assert.AreEqual ("Tests2", t.Name);
1052
1053                 var fi = t.GetField ("field_j");
1054                 var attrs = fi.GetCustomAttributes (true);
1055                 Assert.AreEqual (1, attrs.Length);
1056                 var attr = attrs [0];
1057                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1058                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1059                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1060                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1061         }
1062
1063         [Test]
1064         public void PropertyInfo () {
1065                 Event e = run_until ("ti2");
1066                 StackFrame frame = e.Thread.GetFrames () [0];
1067
1068                 TypeMirror t;
1069
1070                 t = frame.Method.GetParameters ()[8].ParameterType;
1071                 Assert.AreEqual ("Tests2", t.Name);
1072
1073                 var pi = t.GetProperty ("AProperty");
1074                 var attrs = pi.GetCustomAttributes (true);
1075                 Assert.AreEqual (1, attrs.Length);
1076                 var attr = attrs [0];
1077                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1078                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1079                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1080                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1081         }
1082
1083         [Test]
1084         public void Type_GetValue () {
1085                 Event e = run_until ("o1");
1086                 StackFrame frame = e.Thread.GetFrames () [0];
1087
1088                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1089
1090                 TypeMirror t = o.Type;
1091
1092                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1093
1094                 // static fields
1095                 object f = t.GetValue (o.Type.GetField ("static_i"));
1096                 AssertValue (55, f);
1097
1098                 f = t.GetValue (o.Type.GetField ("static_s"));
1099                 AssertValue ("A", f);
1100
1101                 // literal static fields
1102                 f = t.GetValue (o.Type.GetField ("literal_i"));
1103                 AssertValue (56, f);
1104
1105                 f = t.GetValue (o.Type.GetField ("literal_s"));
1106                 AssertValue ("B", f);
1107
1108                 // Inherited static fields
1109                 TypeMirror parent = t.BaseType;
1110                 f = t.GetValue (parent.GetField ("base_static_i"));
1111                 AssertValue (57, f);
1112
1113                 f = t.GetValue (parent.GetField ("base_static_s"));
1114                 AssertValue ("C", f);
1115
1116                 // Argument checking
1117                 AssertThrows<ArgumentNullException> (delegate () {
1118                         t.GetValue (null);
1119                         });
1120
1121                 // instance fields
1122                 AssertThrows<ArgumentException> (delegate () {
1123                         t.GetValue (o.Type.GetField ("field_i"));
1124                         });
1125
1126                 // field on another type
1127                 AssertThrows<ArgumentException> (delegate () {
1128                                 t.GetValue (val2.Type.GetField ("static_field_j"));
1129                         });
1130
1131                 // special static field
1132                 AssertThrows<ArgumentException> (delegate () {
1133                                 t.GetValue (t.GetField ("tls_i"));
1134                         });
1135         }
1136
1137         [Test]
1138         public void Type_GetValues () {
1139                 Event e = run_until ("o1");
1140                 StackFrame frame = e.Thread.GetFrames () [0];
1141
1142                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1143
1144                 TypeMirror t = o.Type;
1145
1146                 // static fields
1147                 object[] vals = t.GetValues (new FieldInfoMirror [] { t.GetField ("static_i"), t.GetField ("static_s") });
1148                 object f = vals [0];
1149                 AssertValue (55, f);
1150
1151                 f = vals [1];
1152                 AssertValue ("A", f);
1153
1154                 // Argument checking
1155                 AssertThrows<ArgumentNullException> (delegate () {
1156                         t.GetValues (null);
1157                         });
1158
1159                 AssertThrows<ArgumentNullException> (delegate () {
1160                         t.GetValues (new FieldInfoMirror [] { null });
1161                         });
1162         }
1163
1164         [Test]
1165         public void ObjRefs () {
1166                 Event e = run_until ("objrefs1");
1167                 StackFrame frame = e.Thread.GetFrames () [0];
1168
1169                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1170                 ObjectMirror child = o.GetValue (o.Type.GetField ("child")) as ObjectMirror;
1171
1172                 Assert.IsTrue (child.Address > 0);
1173
1174                 // Check that object references are internalized correctly
1175                 Assert.AreEqual (o, frame.GetThis ());
1176
1177                 run_until ("objrefs2");
1178
1179                 // child should be gc'd now
1180                 Assert.IsTrue (child.IsCollected);
1181
1182                 AssertThrows<ObjectCollectedException> (delegate () {
1183                         TypeMirror t = child.Type;
1184                         });
1185
1186                 AssertThrows<ObjectCollectedException> (delegate () {
1187                                 long addr = child.Address;
1188                         });
1189         }
1190
1191         [Test]
1192         public void Type_GetObject () {
1193                 Event e = run_until ("o1");
1194                 StackFrame frame = e.Thread.GetFrames () [0];
1195
1196                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1197
1198                 TypeMirror t = o.Type;
1199
1200                 Assert.AreEqual ("MonoType", t.GetTypeObject ().Type.Name);
1201         }
1202
1203         [Test]
1204         public void VTypes () {
1205                 Event e = run_until ("vtypes1");
1206                 StackFrame frame = e.Thread.GetFrames () [0];
1207
1208                 // vtypes as fields
1209                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1210                 var obj = o.GetValue (o.Type.GetField ("field_struct"));
1211                 Assert.IsTrue (obj is StructMirror);
1212                 var s = obj as StructMirror;
1213                 Assert.AreEqual ("AStruct", s.Type.Name);
1214                 AssertValue (42, s ["i"]);
1215                 obj = s ["s"];
1216                 AssertValue ("S", obj);
1217                 AssertValue (43, s ["k"]);
1218                 obj = o.GetValue (o.Type.GetField ("field_boxed_struct"));
1219                 Assert.IsTrue (obj is StructMirror);
1220                 s = obj as StructMirror;
1221                 Assert.AreEqual ("AStruct", s.Type.Name);
1222                 AssertValue (42, s ["i"]);
1223
1224                 // vtypes as arguments
1225                 s = frame.GetArgument (0) as StructMirror;
1226                 AssertValue (44, s ["i"]);
1227                 obj = s ["s"];
1228                 AssertValue ("T", obj);
1229                 AssertValue (45, s ["k"]);
1230
1231                 // vtypes as array entries
1232                 var arr = frame.GetArgument (1) as ArrayMirror;
1233                 obj = arr [0];
1234                 Assert.IsTrue (obj is StructMirror);
1235                 s = obj as StructMirror;
1236                 AssertValue (1, s ["i"]);
1237                 AssertValue ("S1", s ["s"]);
1238                 obj = arr [1];
1239                 Assert.IsTrue (obj is StructMirror);
1240                 s = obj as StructMirror;
1241                 AssertValue (2, s ["i"]);
1242                 AssertValue ("S2", s ["s"]);
1243
1244                 // Argument checking
1245                 s = frame.GetArgument (0) as StructMirror;
1246                 AssertThrows<ArgumentException> (delegate () {
1247                                 obj = s ["FOO"];
1248                         });
1249
1250                 // generic vtype instances
1251                 o = frame.GetThis () as ObjectMirror;
1252                 obj = o.GetValue (o.Type.GetField ("generic_field_struct"));
1253                 Assert.IsTrue (obj is StructMirror);
1254                 s = obj as StructMirror;
1255                 Assert.AreEqual ("GStruct`1", s.Type.Name);
1256                 AssertValue (42, s ["i"]);
1257
1258                 // this on vtype methods
1259                 e = run_until ("vtypes2");
1260                 
1261                 e = single_step (e.Thread);
1262
1263                 frame = e.Thread.GetFrames () [0];
1264
1265                 Assert.AreEqual ("foo", (e as StepEvent).Method.Name);
1266                 obj = frame.GetThis ();
1267
1268                 Assert.IsTrue (obj is StructMirror);
1269                 s = obj as StructMirror;
1270                 AssertValue (44, s ["i"]);
1271                 AssertValue ("T", s ["s"]);
1272                 AssertValue (45, s ["k"]);
1273
1274                 // this on static vtype methods
1275                 e = run_until ("vtypes3");
1276
1277                 e = single_step (e.Thread);
1278
1279                 frame = e.Thread.GetFrames () [0];
1280
1281                 Assert.AreEqual ("static_foo", (e as StepEvent).Method.Name);
1282                 obj = frame.GetThis ();
1283                 AssertValue (null, obj);
1284         }
1285
1286         [Test]
1287         public void AssemblyInfo () {
1288                 Event e = run_until ("single_stepping");
1289
1290                 StackFrame frame = e.Thread.GetFrames () [0];
1291
1292                 var aname = frame.Method.DeclaringType.Assembly.GetName ();
1293                 Assert.AreEqual ("dtest-app, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", aname.ToString ());
1294
1295                 ModuleMirror m = frame.Method.DeclaringType.Module;
1296
1297                 Assert.AreEqual ("dtest-app.exe", m.Name);
1298                 Assert.AreEqual ("dtest-app.exe", m.ScopeName);
1299                 Assert.IsTrue (m.FullyQualifiedName.IndexOf ("dtest-app.exe") != -1);
1300                 Guid guid = m.ModuleVersionId;
1301                 Assert.AreEqual (frame.Method.DeclaringType.Assembly, m.Assembly);
1302                 Assert.AreEqual (frame.Method.DeclaringType.Assembly.ManifestModule, m);
1303
1304                 Assert.AreEqual ("Assembly", frame.Method.DeclaringType.Assembly.GetAssemblyObject ().Type.Name);
1305
1306                 TypeMirror t = vm.RootDomain.Corlib.GetType ("System.Diagnostics.DebuggerDisplayAttribute");
1307                 Assert.AreEqual ("DebuggerDisplayAttribute", t.Name);
1308         }
1309
1310         [Test]
1311         public void LocalsInfo () {
1312                 Event e = run_until ("locals2");
1313
1314                 StackFrame frame = e.Thread.GetFrames () [0];
1315
1316                 var locals = frame.Method.GetLocals ();
1317                 Assert.AreEqual (5, locals.Length);
1318                 for (int i = 0; i < 5; ++i) {
1319                         if (locals [i].Name == "args") {
1320                                 Assert.IsTrue (locals [i].IsArg);
1321                                 Assert.AreEqual ("String[]", locals [i].Type.Name);
1322                         } else if (locals [i].Name == "arg") {
1323                                 Assert.IsTrue (locals [i].IsArg);
1324                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1325                         } else if (locals [i].Name == "i") {
1326                                 Assert.IsFalse (locals [i].IsArg);
1327                                 Assert.AreEqual ("Int64", locals [i].Type.Name);
1328                         } else if (locals [i].Name == "j") {
1329                                 Assert.IsFalse (locals [i].IsArg);
1330                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1331                         } else if (locals [i].Name == "s") {
1332                                 Assert.IsFalse (locals [i].IsArg);
1333                                 Assert.AreEqual ("String", locals [i].Type.Name);
1334                         } else {
1335                                 Assert.Fail ();
1336                         }
1337                 }
1338         }
1339
1340         [Test]
1341         public void Locals () {
1342                 var be = run_until ("locals1");
1343
1344                 StackFrame frame = be.Thread.GetFrames () [0];
1345
1346                 MethodMirror m1 = frame.Method;
1347
1348                 be = run_until ("locals2");
1349
1350                 frame = be.Thread.GetFrames () [0];
1351
1352                 object val = frame.GetValue (frame.Method.GetLocal ("i"));
1353                 AssertValue (0, val);
1354
1355                 // Execute i = 42
1356                 var req = vm.CreateStepRequest (be.Thread);
1357                 req.Enable ();
1358
1359                 vm.Resume ();
1360                 var e = vm.GetNextEvent ();
1361                 Assert.IsTrue (e is StepEvent);
1362                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1363
1364                 // Execute s = "AB";
1365                 vm.Resume ();
1366                 e = vm.GetNextEvent ();
1367                 Assert.IsTrue (e is StepEvent);
1368                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1369
1370                 frame = e.Thread.GetFrames () [0];
1371
1372                 val = frame.GetValue (frame.Method.GetLocal ("i"));
1373                 AssertValue (42, val);
1374
1375                 LocalVariable[] locals = frame.Method.GetLocals ();
1376                 var vals = frame.GetValues (locals);
1377                 Assert.AreEqual (locals.Length, vals.Length);
1378                 for (int i = 0; i < locals.Length; ++i) {
1379                         if (locals [i].Name == "i")
1380                                 AssertValue (42, vals [i]);
1381                         if (locals [i].Name == "s")
1382                                 AssertValue ("AB", vals [i]);
1383                 }
1384
1385                 // Argument checking
1386
1387                 // GetValue () null
1388                 AssertThrows<ArgumentNullException> (delegate () {
1389                                 frame.GetValue ((LocalVariable)null);
1390                         });
1391                 // GetValue () local from another method
1392                 AssertThrows<ArgumentException> (delegate () {
1393                                 frame.GetValue (m1.GetLocal ("foo"));
1394                         });
1395
1396                 // GetValue () null
1397                 AssertThrows<ArgumentNullException> (delegate () {
1398                                 frame.GetValue ((ParameterInfoMirror)null);
1399                         });
1400                 // GetValue () local from another method
1401                 AssertThrows<ArgumentException> (delegate () {
1402                                 frame.GetValue (m1.GetParameters ()[0]);
1403                         });
1404
1405                 // GetValues () null
1406                 AssertThrows<ArgumentNullException> (delegate () {
1407                                 frame.GetValues (null);
1408                         });
1409                 // GetValues () embedded null
1410                 AssertThrows<ArgumentNullException> (delegate () {
1411                                 frame.GetValues (new LocalVariable [] { null });
1412                         });
1413                 // GetValues () local from another method
1414                 AssertThrows<ArgumentException> (delegate () {
1415                                 frame.GetValues (new LocalVariable [] { m1.GetLocal ("foo") });
1416                         });
1417                 // return value
1418                 AssertThrows<ArgumentException> (delegate () {
1419                                 val = frame.GetValue (frame.Method.ReturnParameter);
1420                         });
1421
1422                 // invalid stack frames
1423                 vm.Resume ();
1424                 e = vm.GetNextEvent ();
1425                 Assert.IsTrue (e is StepEvent);
1426                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1427
1428                 AssertThrows<InvalidStackFrameException> (delegate () {
1429                                 frame.GetValue (frame.Method.GetLocal ("i"));
1430                         });
1431
1432                 req.Disable ();
1433         }
1434
1435         [Test]
1436         public void Exit () {
1437                 run_until ("Main");
1438
1439                 vm.Exit (5);
1440
1441                 var e = vm.GetNextEvent ();
1442                 Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
1443
1444                 var p = vm.Process;
1445                 /* Could be a remote vm with no process */
1446                 if (p != null) {
1447                         p.WaitForExit ();
1448                         Assert.AreEqual (5, p.ExitCode);
1449
1450                         // error handling
1451                         AssertThrows<VMDisconnectedException> (delegate () {
1452                                         vm.Resume ();
1453                                 });
1454                 }
1455
1456                 vm = null;
1457         }
1458
1459         [Test]
1460         public void Dispose () {
1461                 run_until ("Main");
1462
1463                 vm.Dispose ();
1464
1465                 var e = vm.GetNextEvent ();
1466                 Assert.IsInstanceOfType (typeof (VMDisconnectEvent), e);
1467
1468                 var p = vm.Process;
1469                 /* Could be a remote vm with no process */
1470                 if (p != null) {
1471                         p.WaitForExit ();
1472                         Assert.AreEqual (3, p.ExitCode);
1473
1474                         // error handling
1475                         AssertThrows<VMDisconnectedException> (delegate () {
1476                                         vm.Resume ();
1477                                 });
1478                 }
1479
1480                 vm = null;
1481         }
1482
1483         [Test]
1484         public void LineNumbers () {
1485                 Event e = run_until ("line_numbers");
1486
1487                 step_req = vm.CreateStepRequest (e.Thread);
1488                 step_req.Depth = StepDepth.Into;
1489                 step_req.Enable ();
1490
1491                 Location l;
1492                 
1493                 vm.Resume ();
1494
1495                 e = vm.GetNextEvent ();
1496                 Assert.IsTrue (e is StepEvent);
1497
1498                 l = e.Thread.GetFrames ()[0].Location;
1499
1500                 Assert.IsTrue (l.SourceFile.IndexOf ("dtest-app.cs") != -1);
1501                 Assert.AreEqual ("ln1", l.Method.Name);
1502                 
1503                 int line_base = l.LineNumber;
1504
1505                 vm.Resume ();
1506                 e = vm.GetNextEvent ();
1507                 Assert.IsTrue (e is StepEvent);
1508                 l = e.Thread.GetFrames ()[0].Location;
1509                 Assert.AreEqual ("ln2", l.Method.Name);
1510                 Assert.AreEqual (line_base + 6, l.LineNumber);
1511
1512                 vm.Resume ();
1513                 e = vm.GetNextEvent ();
1514                 Assert.IsTrue (e is StepEvent);
1515                 l = e.Thread.GetFrames ()[0].Location;
1516                 Assert.AreEqual ("ln1", l.Method.Name);
1517                 Assert.AreEqual (line_base + 1, l.LineNumber);
1518
1519                 vm.Resume ();
1520                 e = vm.GetNextEvent ();
1521                 Assert.IsTrue (e is StepEvent);
1522                 l = e.Thread.GetFrames ()[0].Location;
1523                 Assert.AreEqual ("ln3", l.Method.Name);
1524                 Assert.AreEqual (line_base + 10, l.LineNumber);
1525
1526                 vm.Resume ();
1527                 e = vm.GetNextEvent ();
1528                 Assert.IsTrue (e is StepEvent);
1529                 l = e.Thread.GetFrames ()[0].Location;
1530                 Assert.AreEqual ("ln1", l.Method.Name);
1531                 Assert.AreEqual (line_base + 2, l.LineNumber);
1532
1533                 // GetSourceFiles ()
1534                 string[] sources = l.Method.DeclaringType.GetSourceFiles ();
1535                 Assert.AreEqual (1, sources.Length);
1536                 Assert.AreEqual ("dtest-app.cs", sources [0]);
1537         }
1538
1539         [Test]
1540         public void Suspend () {
1541                 vm.Dispose ();
1542
1543                 Start (new string [] { "dtest-app.exe", "suspend-test" });
1544
1545                 Event e = run_until ("suspend");
1546
1547                 ThreadMirror main = e.Thread;
1548
1549                 vm.Resume ();
1550
1551                 Thread.Sleep (100);
1552
1553                 vm.Suspend ();
1554
1555                 // The debuggee should be suspended while it is running the infinite loop
1556                 // in suspend ()
1557                 StackFrame frame = main.GetFrames ()[0];
1558                 Assert.AreEqual ("suspend", frame.Method.Name);
1559
1560                 vm.Resume ();
1561
1562                 // resuming when not suspended
1563                 AssertThrows<InvalidOperationException> (delegate () {
1564                                 vm.Resume ();
1565                         });
1566
1567                 vm.Exit (0);
1568
1569                 vm = null;
1570         }
1571
1572         [Test]
1573         public void AssemblyLoad () {
1574                 Event e = run_until ("assembly_load");
1575
1576                 vm.Resume ();
1577
1578                 e = vm.GetNextEvent ();
1579                 Assert.IsInstanceOfType (typeof (AssemblyLoadEvent), e);
1580                 Assert.IsTrue ((e as AssemblyLoadEvent).Assembly.Location.EndsWith ("System.dll"));
1581
1582                 var frames = e.Thread.GetFrames ();
1583                 Assert.IsTrue (frames.Length > 0);
1584                 Assert.AreEqual ("assembly_load", frames [0].Method.Name);
1585         }
1586
1587         [Test]
1588         public void CreateValue () {
1589                 PrimitiveValue v;
1590
1591                 v = vm.CreateValue (1);
1592                 Assert.AreEqual (vm, v.VirtualMachine);
1593                 Assert.AreEqual (1, v.Value);
1594
1595                 v = vm.CreateValue (null);
1596                 Assert.AreEqual (vm, v.VirtualMachine);
1597                 Assert.AreEqual (null, v.Value);
1598
1599                 // Argument checking
1600                 AssertThrows <ArgumentException> (delegate () {
1601                                 v = vm.CreateValue ("FOO");
1602                         });
1603         }
1604
1605         [Test]
1606         public void CreateString () {
1607                 StringMirror s = vm.RootDomain.CreateString ("ABC");
1608
1609                 Assert.AreEqual (vm, s.VirtualMachine);
1610                 Assert.AreEqual ("ABC", s.Value);
1611                 Assert.AreEqual (vm.RootDomain, s.Domain);
1612
1613                 // Argument checking
1614                 AssertThrows <ArgumentNullException> (delegate () {
1615                                 s = vm.RootDomain.CreateString (null);
1616                         });
1617         }
1618
1619         [Test]
1620         public void Invoke () {
1621                 Event e = run_until ("invoke1");
1622
1623                 StackFrame frame = e.Thread.GetFrames () [0];
1624
1625                 TypeMirror t = frame.Method.DeclaringType;
1626                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
1627
1628                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
1629
1630                 MethodMirror m;
1631                 Value v;
1632
1633                 // return void
1634                 m = t.GetMethod ("invoke_return_void");
1635                 v = this_obj.InvokeMethod (e.Thread, m, null);
1636                 Assert.IsNull (v);
1637
1638                 // return ref
1639                 m = t.GetMethod ("invoke_return_ref");
1640                 v = this_obj.InvokeMethod (e.Thread, m, null);
1641                 AssertValue ("ABC", v);
1642
1643                 // return null
1644                 m = t.GetMethod ("invoke_return_null");
1645                 v = this_obj.InvokeMethod (e.Thread, m, null);
1646                 AssertValue (null, v);
1647
1648                 // return primitive
1649                 m = t.GetMethod ("invoke_return_primitive");
1650                 v = this_obj.InvokeMethod (e.Thread, m, null);
1651                 AssertValue (42, v);
1652
1653                 // pass primitive
1654                 m = t.GetMethod ("invoke_pass_primitive");
1655                 Value[] args = new Value [] {
1656                         vm.CreateValue ((byte)Byte.MaxValue),
1657                         vm.CreateValue ((sbyte)SByte.MaxValue),
1658                         vm.CreateValue ((short)1),
1659                         vm.CreateValue ((ushort)1),
1660                         vm.CreateValue ((int)1),
1661                         vm.CreateValue ((uint)1),
1662                         vm.CreateValue ((long)1),
1663                         vm.CreateValue ((ulong)1),
1664                         vm.CreateValue ('A'),
1665                         vm.CreateValue (true),
1666                         vm.CreateValue (3.14f),
1667                         vm.CreateValue (3.14) };
1668
1669                 v = this_obj.InvokeMethod (e.Thread, m, args);
1670                 AssertValue ((int)Byte.MaxValue + (int)SByte.MaxValue + 1 + 1 + 1 + 1 + 1 + 1 + 'A' + 1 + 3 + 3, v);
1671
1672                 // pass ref
1673                 m = t.GetMethod ("invoke_pass_ref");
1674                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1675                 AssertValue ("ABC", v);
1676
1677                 // pass null
1678                 m = t.GetMethod ("invoke_pass_ref");
1679                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (null) });
1680                 AssertValue (null, v);
1681
1682                 // static
1683                 m = t.GetMethod ("invoke_static_pass_ref");
1684                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1685                 AssertValue ("ABC", v);
1686
1687                 // static invoked using ObjectMirror.InvokeMethod
1688                 m = t.GetMethod ("invoke_static_pass_ref");
1689                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1690                 AssertValue ("ABC", v);
1691
1692                 // method which throws an exception
1693                 try {
1694                         m = t.GetMethod ("invoke_throws");
1695                         v = this_obj.InvokeMethod (e.Thread, m, null);
1696                         Assert.Fail ();
1697                 } catch (InvocationException ex) {
1698                         Assert.AreEqual ("Exception", ex.Exception.Type.Name);
1699                 }
1700
1701                 // newobj
1702                 m = t.GetMethod (".ctor");
1703                 v = t.InvokeMethod (e.Thread, m, null);
1704                 Assert.IsInstanceOfType (typeof (ObjectMirror), v);
1705                 Assert.AreEqual ("Tests", (v as ObjectMirror).Type.Name);
1706
1707                 // Argument checking
1708                 
1709                 // null thread
1710                 AssertThrows<ArgumentNullException> (delegate {
1711                                 m = t.GetMethod ("invoke_pass_ref");
1712                                 v = this_obj.InvokeMethod (null, m, new Value [] { vm.CreateValue (null) });                            
1713                         });
1714
1715                 // null method
1716                 AssertThrows<ArgumentNullException> (delegate {
1717                                 v = this_obj.InvokeMethod (e.Thread, null, new Value [] { vm.CreateValue (null) });                             
1718                         });
1719
1720                 // invalid number of arguments
1721                 m = t.GetMethod ("invoke_pass_ref");
1722                 AssertThrows<ArgumentException> (delegate {
1723                                 v = this_obj.InvokeMethod (e.Thread, m, null);
1724                         });
1725
1726                 // invalid type of argument (ref != primitive)
1727                 m = t.GetMethod ("invoke_pass_ref");
1728                 AssertThrows<ArgumentException> (delegate {
1729                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
1730                         });
1731
1732                 // invalid type of argument (primitive != primitive)
1733                 m = t.GetMethod ("invoke_pass_primitive_2");
1734                 AssertThrows<ArgumentException> (delegate {
1735                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
1736                         });
1737
1738                 // invoking a non-static method as static
1739                 m = t.GetMethod ("invoke_pass_ref");
1740                 AssertThrows<ArgumentException> (delegate {
1741                                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
1742                         });
1743
1744                 // invoking a method defined in another class
1745                 m = t2.GetMethod ("invoke");
1746                 AssertThrows<ArgumentException> (delegate {
1747                                 v = this_obj.InvokeMethod (e.Thread, m, null);
1748                         });
1749         }
1750
1751         [Test]
1752         [Category ("only")]
1753         public void InvokeVType () {
1754                 Event e = run_until ("invoke1");
1755
1756                 StackFrame frame = e.Thread.GetFrames () [0];
1757
1758                 var s = frame.GetArgument (1) as StructMirror;
1759
1760                 TypeMirror t = s.Type;
1761
1762                 MethodMirror m;
1763                 Value v;
1764
1765                 // Pass struct as this, receive int
1766                 m = t.GetMethod ("invoke_return_int");
1767                 v = s.InvokeMethod (e.Thread, m, null);
1768                 AssertValue (42, v);
1769
1770                 // Pass struct as this, receive intptr
1771                 m = t.GetMethod ("invoke_return_intptr");
1772                 v = s.InvokeMethod (e.Thread, m, null);
1773                 AssertValue (43, v);
1774
1775                 // Static method
1776                 m = t.GetMethod ("invoke_static");
1777                 v = t.InvokeMethod (e.Thread, m, null);
1778                 AssertValue (5, v);
1779         }
1780
1781         [Test]
1782         public void BreakpointDuringInvoke () {
1783                 Event e = run_until ("invoke1");
1784
1785                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
1786                 Assert.IsNotNull (m);
1787                 vm.SetBreakpoint (m, 0);
1788
1789                 StackFrame frame = e.Thread.GetFrames () [0];
1790                 var o = frame.GetThis () as ObjectMirror;
1791
1792                 bool failed = false;
1793
1794                 bool finished = false;
1795                 object wait = new object ();
1796
1797                 // Have to invoke in a separate thread as the invoke is suspended until we
1798                 // resume after the breakpoint
1799                 Thread t = new Thread (delegate () {
1800                                 try {
1801                                         o.InvokeMethod (e.Thread, m, null);
1802                                 } catch {
1803                                         failed = true;
1804                                 }
1805                                 lock (wait) {
1806                                         finished = true;
1807                                         Monitor.Pulse (wait);
1808                                 }
1809                         });
1810
1811                 t.Start ();
1812
1813                 StackFrame invoke_frame = null;
1814
1815                 try {
1816                         e = vm.GetNextEvent ();
1817                         Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
1818                         // Check stack trace support and invokes
1819                         var frames = e.Thread.GetFrames ();
1820                         invoke_frame = frames [0];
1821                         Assert.AreEqual ("invoke2", frames [0].Method.Name);
1822                         Assert.IsTrue (frames [0].IsDebuggerInvoke);
1823                         Assert.AreEqual ("invoke1", frames [1].Method.Name);
1824                 } finally {
1825                         vm.Resume ();
1826                 }
1827
1828                 // Check that the invoke frames are no longer valid
1829                 AssertThrows<InvalidStackFrameException> (delegate {
1830                                 invoke_frame.GetThis ();
1831                         });
1832
1833                 lock (wait) {
1834                         if (!finished)
1835                                 Monitor.Wait (wait);
1836                 }
1837
1838                 // Check InvokeOptions.DisableBreakpoints flag
1839                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
1840         }
1841
1842         [Test]
1843         public void InvokeSingleThreaded () {
1844                 vm.Dispose ();
1845
1846                 Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
1847
1848                 Event e = run_until ("invoke_single_threaded_2");
1849
1850                 StackFrame f = e.Thread.GetFrames ()[0];
1851
1852                 var obj = f.GetThis () as ObjectMirror;
1853
1854                 // Check that the counter value incremented by the other thread does not increase
1855                 // during the invoke.
1856                 object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
1857
1858                 var m = obj.Type.GetMethod ("invoke_return_void");
1859                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
1860
1861             object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
1862
1863                 Assert.AreEqual ((int)counter1, (int)counter2);
1864
1865                 // Test multiple invokes done in succession
1866                 m = obj.Type.GetMethod ("invoke_return_void");
1867                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
1868
1869                 // Test events during single-threaded invokes
1870                 vm.EnableEvents (EventType.TypeLoad);
1871                 m = obj.Type.GetMethod ("invoke_type_load");
1872                 obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
1873                                 vm.Resume ();
1874                         }, null);
1875
1876                 e = vm.GetNextEvent ();
1877                 Assert.AreEqual (EventType.TypeLoad, e.EventType);
1878         }
1879
1880         [Test]
1881         public void GetThreads () {
1882                 vm.GetThreads ();
1883         }
1884
1885         [Test]
1886         public void Threads () {
1887                 Event e = run_until ("threads");
1888
1889                 Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
1890
1891                 vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
1892
1893                 vm.Resume ();
1894
1895                 e = vm.GetNextEvent ();
1896                 Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
1897                 var state = e.Thread.ThreadState;
1898                 Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
1899
1900                 vm.Resume ();
1901
1902                 e = vm.GetNextEvent ();
1903                 Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
1904                 Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
1905         }
1906
1907         [Test]
1908         public void Frame_SetValue () {
1909                 Event e = run_until ("locals2");
1910
1911                 StackFrame frame = e.Thread.GetFrames () [0];
1912
1913                 // primitive
1914                 var l = frame.Method.GetLocal ("i");
1915                 frame.SetValue (l, vm.CreateValue ((long)55));
1916                 AssertValue (55, frame.GetValue (l));
1917
1918                 // reference
1919                 l = frame.Method.GetLocal ("s");
1920                 frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
1921                 AssertValue ("DEF", frame.GetValue (l));
1922
1923                 // argument as local
1924                 l = frame.Method.GetLocal ("arg");
1925                 frame.SetValue (l, vm.CreateValue (6));
1926                 AssertValue (6, frame.GetValue (l));
1927
1928                 // argument
1929                 var p = frame.Method.GetParameters ()[1];
1930                 frame.SetValue (p, vm.CreateValue (7));
1931                 AssertValue (7, frame.GetValue (p));
1932
1933                 // argument checking
1934
1935                 // variable null
1936                 AssertThrows<ArgumentNullException> (delegate () {
1937                                 frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
1938                         });
1939
1940                 // value null
1941                 AssertThrows<ArgumentNullException> (delegate () {
1942                                 l = frame.Method.GetLocal ("i");
1943                                 frame.SetValue (l, null);
1944                         });
1945
1946                 // value of invalid type
1947                 AssertThrows<ArgumentException> (delegate () {
1948                                 l = frame.Method.GetLocal ("i");
1949                                 frame.SetValue (l, vm.CreateValue (55));
1950                         });
1951         }
1952
1953         [Test]
1954         public void InvokeRegress () {
1955                 Event e = run_until ("invoke1");
1956
1957                 StackFrame frame = e.Thread.GetFrames () [0];
1958
1959                 TypeMirror t = frame.Method.DeclaringType;
1960                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
1961
1962                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
1963
1964                 MethodMirror m;
1965                 Value v;
1966
1967                 // do an invoke
1968                 m = t.GetMethod ("invoke_return_void");
1969                 v = this_obj.InvokeMethod (e.Thread, m, null);
1970                 Assert.IsNull (v);
1971
1972                 // Check that the stack frames remain valid during the invoke
1973                 Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
1974
1975                 // do another invoke
1976                 m = t.GetMethod ("invoke_return_void");
1977                 v = this_obj.InvokeMethod (e.Thread, m, null);
1978                 Assert.IsNull (v);
1979
1980                 // Try a single step after the invoke
1981                 var req = vm.CreateStepRequest (e.Thread);
1982                 req.Depth = StepDepth.Into;
1983                 req.Size = StepSize.Line;
1984                 req.Enable ();
1985
1986                 step_req = req;
1987
1988                 // Step into invoke2
1989                 vm.Resume ();
1990                 e = vm.GetNextEvent ();
1991                 Assert.IsTrue (e is StepEvent);
1992                 Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
1993
1994                 req.Disable ();
1995
1996                 frame = e.Thread.GetFrames () [0];
1997         }
1998
1999         [Test]
2000         public void Exceptions () {
2001                 Event e = run_until ("exceptions");
2002                 var req = vm.CreateExceptionRequest (null);
2003                 req.Enable ();
2004
2005                 vm.Resume ();
2006
2007                 e = vm.GetNextEvent ();
2008                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2009                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2010
2011                 var frames = e.Thread.GetFrames ();
2012                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2013                 req.Disable ();
2014
2015                 // exception type filter
2016
2017                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
2018                 req.Enable ();
2019
2020                 // Skip the throwing of the second OverflowException       
2021                 vm.Resume ();
2022
2023                 e = vm.GetNextEvent ();
2024                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2025                 Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
2026                 req.Disable ();
2027
2028                 // exception type filter for subclasses
2029                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
2030                 req.Enable ();
2031
2032                 vm.Resume ();
2033
2034                 e = vm.GetNextEvent ();
2035                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2036                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2037                 req.Disable ();
2038
2039                 // Implicit exceptions
2040                 req = vm.CreateExceptionRequest (null);
2041                 req.Enable ();
2042
2043                 vm.Resume ();
2044
2045                 e = vm.GetNextEvent ();
2046                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2047                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2048                 req.Disable ();
2049
2050                 // Argument checking
2051                 AssertThrows<ArgumentException> (delegate {
2052                                 vm.CreateExceptionRequest (e.Thread.Type);
2053                         });
2054         }
2055
2056         [Test]
2057         public void Domains () {
2058                 vm.Dispose ();
2059
2060                 Start (new string [] { "dtest-app.exe", "domain-test" });
2061
2062                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
2063
2064                 Event e = run_until ("domains");
2065
2066                 vm.Resume ();
2067                 
2068                 e = vm.GetNextEvent ();
2069                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
2070
2071                 var domain = (e as AppDomainCreateEvent).Domain;
2072
2073                 // Run until the callback in the domain
2074                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
2075                 Assert.IsNotNull (m);
2076                 vm.SetBreakpoint (m, 0);
2077
2078                 while (true) {
2079                         vm.Resume ();
2080                         e = vm.GetNextEvent ();
2081                         if (e is BreakpointEvent)
2082                                 break;
2083                 }
2084
2085                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
2086
2087                 // d_method is from another domain
2088                 MethodMirror d_method = (e as BreakpointEvent).Method;
2089                 Assert.IsTrue (m != d_method);
2090
2091                 var frames = e.Thread.GetFrames ();
2092                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
2093                 Assert.AreEqual ("invoke", frames [1].Method.Name);
2094                 Assert.AreEqual ("domains", frames [2].Method.Name);
2095
2096                 // This is empty when receiving the AppDomainCreateEvent
2097                 Assert.AreEqual ("domain", domain.FriendlyName);
2098
2099                 // Run until the unload
2100                 while (true) {
2101                         vm.Resume ();
2102                         e = vm.GetNextEvent ();
2103                         if (e is AssemblyUnloadEvent) {
2104                                 continue;
2105                         } else {
2106                                 break;
2107                         }
2108                 }
2109                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
2110                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
2111
2112                 // Run past the unload
2113                 e = run_until ("domains_2");
2114
2115                 // Test access to unloaded types
2116                 // FIXME: Add an exception type for this
2117                 AssertThrows<Exception> (delegate {
2118                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
2119                         });
2120         }
2121
2122         [Test]
2123         public void DynamicMethods () {
2124                 Event e = run_until ("dyn_call");
2125
2126                 var m = e.Thread.GetFrames ()[1].Method;
2127                 Assert.AreEqual ("dyn_method", m.Name);
2128
2129                 // Test access to IL
2130                 var body = m.GetMethodBody ();
2131
2132                 ILInstruction ins = body.Instructions [0];
2133                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2134                 Assert.AreEqual ("FOO", ins.Operand);
2135         }
2136
2137         [Test]
2138         public void RefEmit () {
2139                 vm.Dispose ();
2140
2141                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
2142
2143                 Event e = run_until ("ref_emit_call");
2144
2145                 var m = e.Thread.GetFrames ()[1].Method;
2146                 Assert.AreEqual ("ref_emit_method", m.Name);
2147
2148                 // Test access to IL
2149                 var body = m.GetMethodBody ();
2150
2151                 ILInstruction ins;
2152
2153                 ins = body.Instructions [0];
2154                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2155                 Assert.AreEqual ("FOO", ins.Operand);
2156
2157                 ins = body.Instructions [1];
2158                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
2159                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
2160                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
2161         }
2162
2163         [Test]
2164         public void IsAttached () {
2165                 var f = entry_point.DeclaringType.GetField ("is_attached");
2166
2167                 Event e = run_until ("Main");
2168
2169                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
2170         }
2171
2172         [Test]
2173         public void StackTraceInNative () {
2174                 // Check that stack traces can be produced for threads in native code
2175                 vm.Dispose ();
2176
2177                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
2178
2179                 var e = run_until ("frames_in_native");
2180
2181                 // FIXME: This is racy
2182                 vm.Resume ();
2183
2184                 Thread.Sleep (100);
2185
2186                 vm.Suspend ();
2187
2188                 StackFrame[] frames = e.Thread.GetFrames ();
2189
2190                 int frame_index = -1;
2191                 for (int i = 0; i < frames.Length; ++i) {
2192                         if (frames [i].Method.Name == "Sleep") {
2193                                 frame_index = i;
2194                                 break;
2195                         }
2196                 }
2197
2198                 Assert.IsTrue (frame_index != -1);
2199                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
2200                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
2201                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
2202
2203                 // Check that invokes are disabled for such threads
2204                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
2205
2206                 // return void
2207                 var m = t.GetMethod ("invoke_static_return_void");
2208                 AssertThrows<InvalidOperationException> (delegate {
2209                                 t.InvokeMethod (e.Thread, m, null);
2210                         });
2211         }
2212
2213         [Test]
2214         public void VirtualMachine_CreateEnumMirror () {
2215                 var e = run_until ("o1");
2216                 var frame = e.Thread.GetFrames () [0];
2217
2218                 object val = frame.GetThis ();
2219                 Assert.IsTrue (val is ObjectMirror);
2220                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
2221                 ObjectMirror o = (val as ObjectMirror);
2222
2223                 FieldInfoMirror field = o.Type.GetField ("field_enum");
2224                 Value f = o.GetValue (field);
2225                 TypeMirror enumType = (f as EnumMirror).Type;
2226
2227                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
2228                 f = o.GetValue (field);
2229                 Assert.AreEqual (1, (f as EnumMirror).Value);
2230
2231                 // Argument checking
2232                 AssertThrows<ArgumentNullException> (delegate () {
2233                                 vm.CreateEnumMirror (enumType, null);
2234                         });
2235
2236                 AssertThrows<ArgumentNullException> (delegate () {
2237                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
2238                         });
2239
2240                 // null value
2241                 AssertThrows<ArgumentException> (delegate () {
2242                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
2243                         });
2244
2245                 // value of a wrong type
2246                 AssertThrows<ArgumentException> (delegate () {
2247                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
2248                         });
2249         }
2250 }