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