Merge pull request #980 from StephenMcConnel/bug-18638
[mono.git] / mcs / class / Mono.Debugger.Soft / Test / dtest.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Threading;
4 using System.Net;
5 using System.Reflection;
6 using System.Text;
7 using Mono.Cecil.Cil;
8 using Mono.Debugger.Soft;
9 using Diag = System.Diagnostics;
10 using System.Linq;
11 using System.IO;
12 using System.Security.Cryptography;
13
14 using NUnit.Framework;
15
16 #pragma warning disable 0219
17
18 namespace MonoTests
19 {
20
21 [TestFixture]
22 public class DebuggerTests
23 {
24         VirtualMachine vm;
25         MethodMirror entry_point;
26         StepEventRequest step_req;
27         bool forceExit;
28
29         void AssertThrows<ExType> (Action del) where ExType : Exception {
30                 bool thrown = false;
31
32                 try {
33                         del ();
34                 } catch (ExType) {
35                         thrown = true;
36                 }
37                 Assert.IsTrue (thrown);
38         }
39
40         // No other way to pass arguments to the tests ?
41         public static bool listening = Environment.GetEnvironmentVariable ("DBG_SUSPEND") != null;
42         public static string runtime = Environment.GetEnvironmentVariable ("DBG_RUNTIME");
43         public static string agent_args = Environment.GetEnvironmentVariable ("DBG_AGENT_ARGS");
44
45         Event GetNextEvent () {
46                 var es = vm.GetNextEventSet ();
47                 Assert.AreEqual (1, es.Events.Length);
48                 return es [0];
49         }
50
51         void Start (params string[] args) {
52                 Start (false, args);
53         }
54
55         void Start (bool forceExit, params string[] args) {
56                 this.forceExit = forceExit;
57
58                 if (!listening) {
59                         var pi = new Diag.ProcessStartInfo ();
60
61                         if (runtime != null)
62                                 pi.FileName = runtime;
63                         else
64                                 pi.FileName = "mono";
65                         pi.Arguments = String.Join (" ", args);
66                         vm = VirtualMachineManager.Launch (pi, new LaunchOptions { AgentArgs = agent_args });
67                 } else {
68                         var ep = new IPEndPoint (IPAddress.Any, 10000);
69                         Console.WriteLine ("Listening on " + ep + "...");
70                         vm = VirtualMachineManager.Listen (ep);
71                 }
72
73                 var load_req = vm.CreateAssemblyLoadRequest ();
74                 load_req.Enable ();
75
76                 Event vmstart = GetNextEvent ();
77                 Assert.AreEqual (EventType.VMStart, vmstart.EventType);
78
79                 vm.Resume ();
80
81                 entry_point = null;
82                 step_req = null;
83
84                 Event e;
85
86                 /* Find out the entry point */
87                 while (true) {
88                         e = GetNextEvent ();
89
90                         if (e is AssemblyLoadEvent) {
91                                 AssemblyLoadEvent ae = (AssemblyLoadEvent)e;
92                                 entry_point = ae.Assembly.EntryPoint;
93                                 if (entry_point != null)
94                                         break;
95                         }
96
97                         vm.Resume ();
98                 }
99
100                 load_req.Disable ();
101         }
102
103         BreakpointEvent run_until (string name) {
104                 // String
105                 MethodMirror m = entry_point.DeclaringType.GetMethod (name);
106                 Assert.IsNotNull (m);
107                 //Console.WriteLine ("X: " + name + " " + m.ILOffsets.Count + " " + m.Locations.Count);
108                 var req = vm.SetBreakpoint (m, m.ILOffsets [0]);
109
110                 Event e = null;
111
112                 while (true) {
113                         vm.Resume ();
114                         e = GetNextEvent ();
115                         if (e is BreakpointEvent)
116                                 break;
117                 }
118
119                 req.Disable ();
120
121                 Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
122                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
123
124                 return (e as BreakpointEvent);
125         }
126
127         Event single_step (ThreadMirror t) {
128                 var req = vm.CreateStepRequest (t);
129                 req.Enable ();
130
131                 vm.Resume ();
132                 Event e = GetNextEvent ();
133                 Assert.IsTrue (e is StepEvent);
134
135                 req.Disable ();
136
137                 return e;
138         }
139
140         Event step_until (ThreadMirror t, string method_name) {
141                 Event e;
142                 while (true) {
143                         e = single_step (t);
144                         if ((e as StepEvent).Method.Name == method_name)
145                                 break;
146                 }
147                 return e;
148         }
149
150         void check_arg_val (StackFrame frame, int pos, Type type, object eval) {
151                 object val = frame.GetArgument (pos);
152                 Assert.IsTrue (val is PrimitiveValue);
153                 object v = (val as PrimitiveValue).Value;
154                 Assert.AreEqual (type, v.GetType ());
155                 if (eval is float)
156                         Assert.IsTrue (Math.Abs ((float)eval - (float)v) < 0.0001);
157                 else if (eval is double)
158                         Assert.IsTrue (Math.Abs ((double)eval - (double)v) < 0.0001);
159                 else
160                         Assert.AreEqual (eval, v);
161         }
162
163         void AssertValue (object expected, object val) {
164                 if (expected is string) {
165                         Assert.IsTrue (val is StringMirror);
166                         Assert.AreEqual (expected, (val as StringMirror).Value);
167                 } else if (val is StructMirror && (val as StructMirror).Type.Name == "IntPtr") {
168                         AssertValue (expected, (val as StructMirror).Fields [0]);
169                 } else {
170                         Assert.IsTrue (val is PrimitiveValue);
171                         Assert.AreEqual (expected, (val as PrimitiveValue).Value);
172                 }
173         }
174
175         [SetUp]
176         public void SetUp () {
177                 ThreadMirror.NativeTransitions = false;
178                 Start (new string [] { "dtest-app.exe" });
179         }
180
181         [TearDown]
182         public void TearDown () {
183                 if (vm == null)
184                         return;
185
186                 if (step_req != null)
187                         step_req.Disable ();
188
189                 vm.Resume ();
190                 if (forceExit)
191                         vm.Exit (0);
192
193                 while (true) {
194                         Event e = GetNextEvent ();
195
196                         if (e is VMDeathEvent)
197                                 break;
198
199                         vm.Resume ();
200                 }
201                 vm = null;
202         }
203
204         [Test]
205         public void SimpleBreakpoint () {
206                 Event e;
207
208                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp1");
209                 Assert.IsNotNull (m);
210
211                 vm.SetBreakpoint (m, 0);
212
213                 vm.Resume ();
214
215                 e = GetNextEvent ();
216                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
217                 Assert.IsTrue (e is BreakpointEvent);
218                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
219
220                 // Argument checking
221                 AssertThrows<ArgumentException> (delegate {
222                                 // Invalid IL offset
223                                 vm.SetBreakpoint (m, 2);
224                         });
225         }
226
227         [Test]
228         public void BreakpointsSameLocation () {
229                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp2");
230                 Assert.IsNotNull (m);
231
232                 vm.SetBreakpoint (m, 0);
233                 vm.SetBreakpoint (m, 0);
234
235                 vm.Resume ();
236
237                 var es = vm.GetNextEventSet ();
238                 Assert.AreEqual (2, es.Events.Length);
239                 Assert.IsTrue (es [0] is BreakpointEvent);
240                 Assert.AreEqual (m, (es [0] as BreakpointEvent).Method);
241
242                 Assert.IsTrue (es [1] is BreakpointEvent);
243                 Assert.AreEqual (m.Name, (es [1] as BreakpointEvent).Method.Name);
244         }
245
246         [Test]
247         public void BreakpointAlreadyJITted () {
248                 Event e = run_until ("bp1");
249
250                 /* Place a breakpoint on bp3 */
251                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp3");
252                 Assert.IsNotNull (m);
253                 vm.SetBreakpoint (m, 0);
254
255                 /* Same with generic instances */
256                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp7");
257                 Assert.IsNotNull (m2);
258                 vm.SetBreakpoint (m2, 0);
259
260                 vm.Resume ();
261
262                 e = GetNextEvent ();
263                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
264                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
265
266                 vm.Resume ();
267
268                 /* Non-shared instance */
269                 e = GetNextEvent ();
270                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
271                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
272
273                 vm.Resume ();
274
275                 /* Shared instance */
276                 e = GetNextEvent ();
277                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
278                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
279         }
280
281         [Test]
282         public void ClearBreakpoint () {
283                 Event e;
284
285                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
286                 Assert.IsNotNull (m);
287                 EventRequest req1 = vm.SetBreakpoint (m, 0);
288                 EventRequest req2 = vm.SetBreakpoint (m, 0);
289
290                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
291                 Assert.IsNotNull (m2);
292                 vm.SetBreakpoint (m2, 0);
293
294                 /* Run until bp4 */
295                 vm.Resume ();
296
297                 var es = vm.GetNextEventSet ();
298                 Assert.AreEqual (2, es.Events.Length);
299                 Assert.AreEqual (EventType.Breakpoint, es [0].EventType);
300                 Assert.AreEqual (m.Name, (es [0] as BreakpointEvent).Method.Name);
301                 Assert.AreEqual (EventType.Breakpoint, es [1].EventType);
302                 Assert.AreEqual (m.Name, (es [1] as BreakpointEvent).Method.Name);
303
304                 /* Clear one of them */
305                 req1.Disable ();
306
307                 vm.Resume ();
308
309                 e = GetNextEvent ();
310                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
311                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
312
313                 /* Clear the other */
314                 req2.Disable ();
315
316                 vm.Resume ();
317
318                 e = GetNextEvent ();
319                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
320                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
321         }
322
323         [Test]
324         public void ClearAllBreakpoints () {
325                 Event e;
326
327                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp4");
328                 Assert.IsNotNull (m);
329                 vm.SetBreakpoint (m, 0);
330
331                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("bp5");
332                 Assert.IsNotNull (m2);
333                 vm.SetBreakpoint (m2, 0);
334
335                 vm.ClearAllBreakpoints ();
336
337                 vm.Resume ();
338
339                 e = GetNextEvent ();
340                 Assert.IsTrue (!(e is BreakpointEvent));
341                 if (e is VMDeathEvent)
342                         vm = null;
343         }
344
345         [Test]
346         public void BreakpointOnGShared () {
347                 Event e;
348
349                 MethodMirror m = entry_point.DeclaringType.GetMethod ("bp6");
350                 Assert.IsNotNull (m);
351
352                 vm.SetBreakpoint (m, 0);
353
354                 vm.Resume ();
355
356                 e = GetNextEvent ();
357                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
358                 Assert.IsTrue (e is BreakpointEvent);
359                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
360
361                 // Breakpoint on an open generic method of a closed generic class (#3422)
362                 var frame = e.Thread.GetFrames ()[0];
363                 var ginst = frame.GetValue (frame.Method.GetLocal ("gc"));
364                 var m2 = (ginst as ObjectMirror).Type.GetMethod ("bp");
365                 vm.SetBreakpoint (m2, 0);
366
367                 vm.Resume ();
368
369                 e = GetNextEvent ();
370                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
371                 Assert.IsTrue (e is BreakpointEvent);
372                 Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
373         }
374
375         void assert_location (Event e, string method) {
376                 Assert.IsTrue (e is StepEvent);
377                 Assert.AreEqual (method, (e as StepEvent).Method.Name);
378         }
379
380         StepEventRequest create_step (Event e) {
381                 var req = vm.CreateStepRequest (e.Thread);
382                 step_req = req;
383                 return req;
384         }
385
386         [Test]
387         public void SingleStepping () {
388                 Event e = run_until ("single_stepping");
389
390                 var req = create_step (e);
391                 req.Enable ();
392
393                 // Step over 'bool b = true'
394                 e = step_once ();
395                 assert_location (e, "single_stepping");
396
397                 // Skip nop
398                 step_once ();
399
400                 // Step into ss1
401                 e = step_once ();
402                 assert_location (e, "ss1");
403
404                 // Skip }
405                 e = step_once ();
406
407                 // Step out of ss1
408                 e = step_once ();
409                 assert_location (e, "single_stepping");
410
411                 // Step over ss2
412                 e = step_over ();
413                 assert_location (e, "single_stepping");
414
415                 // Step into ss3
416                 e = step_into ();
417                 assert_location (e, "ss3");
418
419                 // Step back into single_stepping
420                 e = step_out ();
421                 assert_location (e, "single_stepping");
422
423                 // Step into ss3_2 ()
424                 e = step_into ();
425                 assert_location (e, "ss3_2");
426
427                 // Step over ss3_2_2 ()
428                 e = step_over ();
429                 assert_location (e, "ss3_2");
430
431                 // Recreate the request
432                 req.Disable ();
433                 req.Enable ();
434
435                 // Skip }
436                 e = step_once ();
437
438                 // Step back into single_stepping () with the new request
439                 e = step_once ();
440                 assert_location (e, "single_stepping");
441
442                 // Step into ss4 ()
443                 e = step_into ();
444                 assert_location (e, "ss4");
445
446                 // Skip nop
447                 e = step_once ();
448
449                 // Change to StepSize.Line
450                 req.Disable ();
451                 req.Depth = StepDepth.Over;
452                 req.Size = StepSize.Line;
453                 req.Enable ();
454
455                 // Step over ss1 (); ss1 ();
456                 e = step_once ();
457
458                 // Step into ss2 ()
459                 req.Disable ();
460                 req.Depth = StepDepth.Into;
461                 req.Enable ();
462
463                 e = step_once ();
464                 assert_location (e, "ss2");
465
466                 req.Disable ();
467
468                 // Run until ss5
469                 e = run_until ("ss5");
470
471                 // Add an assembly filter
472                 req.AssemblyFilter = new AssemblyMirror [] { (e as BreakpointEvent).Method.DeclaringType.Assembly };
473                 req.Enable ();
474
475                 // Skip nop
476                 e = step_once ();
477
478                 // Step into is_even, skipping the linq stuff
479                 e = step_once ();
480                 assert_location (e, "is_even");
481
482                 // FIXME: Check that single stepping works with lock (obj)
483                 req.Disable ();
484
485                 // Run until ss6
486                 e = run_until ("ss6");
487
488                 req = create_step (e);
489                 req.Depth = StepDepth.Over;
490                 req.Enable ();
491
492                 // Check that single stepping works in out-of-line bblocks
493                 e = step_once ();
494                 e = step_once ();
495                 assert_location (e, "ss6");
496                 req.Disable ();
497
498                 // Check that a step over stops at an EH clause
499                 e = run_until ("ss7_2");
500                 req = create_step (e);
501                 req.Depth = StepDepth.Out;
502                 req.Enable ();
503                 e = step_once ();
504                 assert_location (e, "ss7");
505                 req.Disable ();
506                 req = create_step (e);
507                 req.Depth = StepDepth.Over;
508                 req.Enable ();
509                 e = step_once ();
510                 assert_location (e, "ss7");
511                 req.Disable ();
512
513                 // Check that stepping stops between nested calls
514                 e = run_until ("ss_nested_2");
515                 e = step_out ();
516                 assert_location (e, "ss_nested");
517                 e = step_into ();
518                 assert_location (e, "ss_nested_1");
519                 e = step_out ();
520                 assert_location (e, "ss_nested");
521                 // Check that step over steps over nested calls
522                 e = step_over ();
523                 assert_location (e, "ss_nested");
524                 e = step_into ();
525                 assert_location (e, "ss_nested_3");
526                 req.Disable ();
527
528                 // Check DebuggerStepThrough support
529                 e = run_until ("ss_step_through");
530                 req = create_step (e);
531                 req.Filter = StepFilter.DebuggerStepThrough;
532                 e = step_into ();
533                 // Step through step_through_1 ()
534                 e = step_into ();
535                 assert_location (e, "ss_step_through");
536                 // Step through StepThroughClass.step_through_2 ()
537                 e = step_into ();
538                 assert_location (e, "ss_step_through");
539                 req.Disable ();
540                 req.Filter = StepFilter.None;
541                 e = step_into ();
542                 assert_location (e, "step_through_3");
543                 req.Disable ();
544
545                 // Check DebuggerNonUserCode support
546                 e = run_until ("ss_non_user_code");
547                 req = create_step (e);
548                 req.Filter = StepFilter.DebuggerNonUserCode;
549                 e = step_into ();
550                 // Step through non_user_code_1 ()
551                 e = step_into ();
552                 assert_location (e, "ss_non_user_code");
553                 // Step through StepThroughClass.non_user_code_2 ()
554                 e = step_into ();
555                 assert_location (e, "ss_non_user_code");
556                 req.Disable ();
557                 req.Filter = StepFilter.None;
558                 e = step_into ();
559                 assert_location (e, "non_user_code_3");
560                 req.Disable ();
561
562                 // Check that step-over doesn't stop at inner frames with recursive functions
563                 e = run_until ("ss_recursive");
564                 req = create_step (e);
565                 e = step_over ();
566                 e = step_over ();
567                 e = step_over ();
568                 var f = e.Thread.GetFrames () [0];
569                 assert_location (e, "ss_recursive");
570                 AssertValue (1, f.GetValue (f.Method.GetLocal ("n")));
571                 req.Disable ();
572
573                 // Check that single stepping doesn't clobber fp values
574                 e = run_until ("ss_fp_clobber");
575                 req = create_step (e);
576                 while (true) {
577                         f = e.Thread.GetFrames ()[0];
578                         e = step_into ();
579                         if ((e as StepEvent).Method.Name == "ss_fp_clobber_2")
580                                 break;
581                         e = step_into ();
582                 }
583                 f = e.Thread.GetFrames ()[0];
584                 AssertValue (7.0, f.GetValue (f.Method.GetParameters ()[0]));
585                 req.Disable ();
586         }
587
588         [Test]
589         public void MethodEntryExit () {
590                 run_until ("single_stepping");
591
592                 var req1 = vm.CreateMethodEntryRequest ();
593                 var req2 = vm.CreateMethodExitRequest ();
594
595                 req1.Enable ();
596                 req2.Enable ();
597
598                 vm.Resume ();
599                 Event e = GetNextEvent ();
600                 Assert.IsTrue (e is MethodEntryEvent);
601                 Assert.AreEqual ("ss1", (e as MethodEntryEvent).Method.Name);
602
603                 vm.Resume ();
604                 e = GetNextEvent ();
605                 Assert.IsTrue (e is MethodExitEvent);
606                 Assert.AreEqual ("ss1", (e as MethodExitEvent).Method.Name);
607
608                 req1.Disable ();
609                 req2.Disable ();
610         }
611
612         [Test]
613         public void CountFilter () {
614                 run_until ("single_stepping");
615
616                 MethodMirror m2 = entry_point.DeclaringType.GetMethod ("ss3");
617                 Assert.IsNotNull (m2);
618                 vm.SetBreakpoint (m2, 0);
619
620                 var req1 = vm.CreateMethodEntryRequest ();
621                 req1.Count = 2;
622                 req1.Enable ();
623
624                 // Enter ss2, ss1 is skipped
625                 vm.Resume ();
626                 Event e = GetNextEvent ();
627                 Assert.IsTrue (e is MethodEntryEvent);
628                 Assert.AreEqual ("ss2", (e as MethodEntryEvent).Method.Name);
629
630                 // Breakpoint on ss3, the entry event is no longer reported
631                 vm.Resume ();
632                 e = GetNextEvent ();
633                 Assert.IsTrue (e is BreakpointEvent);
634
635                 req1.Disable ();
636         }
637
638         [Test]
639         public void Arguments () {
640                 object val;
641
642                 var e = run_until ("arg1");
643
644                 StackFrame frame = e.Thread.GetFrames () [0];
645
646                 check_arg_val (frame, 0, typeof (sbyte), SByte.MaxValue - 5);
647                 check_arg_val (frame, 1, typeof (byte), Byte.MaxValue - 5);
648                 check_arg_val (frame, 2, typeof (bool), true);
649                 check_arg_val (frame, 3, typeof (short), Int16.MaxValue - 5);
650                 check_arg_val (frame, 4, typeof (ushort), UInt16.MaxValue - 5);
651                 check_arg_val (frame, 5, typeof (char), 'F');
652                 check_arg_val (frame, 6, typeof (int), Int32.MaxValue - 5);
653                 check_arg_val (frame, 7, typeof (uint), UInt32.MaxValue - 5);
654                 check_arg_val (frame, 8, typeof (long), Int64.MaxValue - 5);
655                 check_arg_val (frame, 9, typeof (ulong), UInt64.MaxValue - 5);
656                 check_arg_val (frame, 10, typeof (float), 1.2345f);
657                 check_arg_val (frame, 11, typeof (double), 6.78910);
658
659                 e = run_until ("arg2");
660
661                 frame = e.Thread.GetFrames () [0];
662
663                 // String
664                 val = frame.GetArgument (0);
665                 AssertValue ("FOO", val);
666                 Assert.AreEqual ("String", (val as ObjectMirror).Type.Name);
667
668                 // null
669                 val = frame.GetArgument (1);
670                 AssertValue (null, val);
671
672                 // object
673                 val = frame.GetArgument (2);
674                 AssertValue ("BLA", val);
675
676                 // byref
677                 val = frame.GetArgument (3);
678                 AssertValue (42, val);
679
680                 // generic instance
681                 val = frame.GetArgument (4);
682                 Assert.IsTrue (val is ObjectMirror);
683                 Assert.AreEqual ("GClass`1", (val as ObjectMirror).Type.Name);
684
685                 // System.Object
686                 val = frame.GetArgument (5);
687                 Assert.IsTrue (val is ObjectMirror);
688                 Assert.AreEqual ("Object", (val as ObjectMirror).Type.Name);
689
690                 // this on static methods
691                 val = frame.GetThis ();
692                 AssertValue (null, val);
693
694                 e = run_until ("arg3");
695
696                 frame = e.Thread.GetFrames () [0];
697
698                 // this
699                 val = frame.GetThis ();
700                 Assert.IsTrue (val is ObjectMirror);
701                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
702
703                 // objref in register
704                 val = frame.GetArgument (0);
705                 AssertValue ("BLA", val);
706         }
707
708         [Test]
709         public void Arrays () {
710                 object val;
711
712                 var e = run_until ("o2");
713
714                 StackFrame frame = e.Thread.GetFrames () [0];
715
716                 // String[]
717                 val = frame.GetArgument (0);
718                 Assert.IsTrue (val is ArrayMirror);
719                 ArrayMirror arr = val as ArrayMirror;
720                 Assert.AreEqual (2, arr.Length);
721                 AssertValue ("BAR", arr [0]);
722                 AssertValue ("BAZ", arr [1]);
723
724                 var vals = arr.GetValues (0, 2);
725                 Assert.AreEqual (2, vals.Count);
726                 AssertValue ("BAR", vals [0]);
727                 AssertValue ("BAZ", vals [1]);
728
729                 arr [0] = vm.RootDomain.CreateString ("ABC");
730                 AssertValue ("ABC", arr [0]);
731
732                 arr [0] = vm.CreateValue (null);
733                 AssertValue (null, arr [0]);
734
735                 arr.SetValues (0, new Value [] { vm.RootDomain.CreateString ("D1"), vm.RootDomain.CreateString ("D2") });
736                 AssertValue ("D1", arr [0]);
737                 AssertValue ("D2", arr [1]);
738
739                 // int
740                 val = frame.GetArgument (1);
741                 Assert.IsTrue (val is ArrayMirror);
742                 arr = val as ArrayMirror;
743                 Assert.AreEqual (2, arr.Length);
744                 AssertValue (42, arr [0]);
745                 AssertValue (43, arr [1]);
746
747                 // Argument checking
748                 AssertThrows<IndexOutOfRangeException> (delegate () {
749                                 val = arr [2];
750                         });
751
752                 AssertThrows<IndexOutOfRangeException> (delegate () {
753                                 val = arr [Int32.MinValue];
754                         });
755
756                 AssertThrows<IndexOutOfRangeException> (delegate () {
757                                 vals = arr.GetValues (0, 3);
758                         });
759
760                 AssertThrows<IndexOutOfRangeException> (delegate () {
761                                 arr [2] = vm.CreateValue (null);
762                         });
763
764                 AssertThrows<IndexOutOfRangeException> (delegate () {
765                                 arr [Int32.MinValue] = vm.CreateValue (null);
766                         });
767
768                 AssertThrows<IndexOutOfRangeException> (delegate () {
769                                 arr.SetValues (0, new Value [] { null, null, null });
770                         });
771
772                 // Multidim arrays
773                 val = frame.GetArgument (2);
774                 Assert.IsTrue (val is ArrayMirror);
775                 arr = val as ArrayMirror;
776                 Assert.AreEqual (2, arr.Rank);
777                 Assert.AreEqual (4, arr.Length);
778                 Assert.AreEqual (2, arr.GetLength (0));
779                 Assert.AreEqual (2, arr.GetLength (1));
780                 Assert.AreEqual (0, arr.GetLowerBound (0));
781                 Assert.AreEqual (0, arr.GetLowerBound (1));
782                 vals = arr.GetValues (0, 4);
783                 AssertValue (1, vals [0]);
784                 AssertValue (2, vals [1]);
785                 AssertValue (3, vals [2]);
786                 AssertValue (4, vals [3]);
787
788                 val = frame.GetArgument (3);
789                 Assert.IsTrue (val is ArrayMirror);
790                 arr = val as ArrayMirror;
791                 Assert.AreEqual (2, arr.Rank);
792                 Assert.AreEqual (4, arr.Length);
793                 Assert.AreEqual (2, arr.GetLength (0));
794                 Assert.AreEqual (2, arr.GetLength (1));
795                 Assert.AreEqual (1, arr.GetLowerBound (0));
796                 Assert.AreEqual (3, arr.GetLowerBound (1));
797
798                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
799                                 arr.GetLength (-1);
800                         });
801                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
802                                 arr.GetLength (2);
803                         });
804
805                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
806                                 arr.GetLowerBound (-1);
807                         });
808                 AssertThrows<ArgumentOutOfRangeException> (delegate () {
809                                 arr.GetLowerBound (2);
810                         });
811
812                 // arrays treated as generic collections
813                 val = frame.GetArgument (4);
814                 Assert.IsTrue (val is ArrayMirror);
815                 arr = val as ArrayMirror;
816         }
817
818         [Test]
819         public void Object_GetValue () {
820                 var e = run_until ("o1");
821                 var frame = e.Thread.GetFrames () [0];
822
823                 object val = frame.GetThis ();
824                 Assert.IsTrue (val is ObjectMirror);
825                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
826                 ObjectMirror o = (val as ObjectMirror);
827
828                 TypeMirror t = o.Type;
829
830                 // object fields
831                 object f = o.GetValue (t.GetField ("field_i"));
832                 AssertValue (42, f);
833                 f = o.GetValue (t.GetField ("field_s"));
834                 AssertValue ("S", f);
835                 f = o.GetValue (t.GetField ("field_enum"));
836                 Assert.IsTrue (f is EnumMirror);
837                 Assert.AreEqual (1, (f as EnumMirror).Value);
838                 Assert.AreEqual ("B", (f as EnumMirror).StringValue);
839
840                 // Inherited object fields
841                 TypeMirror parent = t.BaseType;
842                 f = o.GetValue (parent.GetField ("base_field_i"));
843                 AssertValue (43, f);
844                 f = o.GetValue (parent.GetField ("base_field_s"));
845                 AssertValue ("T", f);
846
847                 // Static fields
848                 f = o.GetValue (o.Type.GetField ("static_i"));
849                 AssertValue (55, f);
850
851                 // generic instances
852                 ObjectMirror o2 = frame.GetValue (frame.Method.GetParameters ()[1]) as ObjectMirror;
853                 Assert.AreEqual ("GClass`1", o2.Type.Name);
854                 TypeMirror t2 = o2.Type;
855                 f = o2.GetValue (t2.GetField ("field"));
856                 AssertValue (42, f);
857
858                 ObjectMirror o3 = frame.GetValue (frame.Method.GetParameters ()[2]) as ObjectMirror;
859                 Assert.AreEqual ("GClass`1", o3.Type.Name);
860                 TypeMirror t3 = o3.Type;
861                 f = o3.GetValue (t3.GetField ("field"));
862                 AssertValue ("FOO", f);
863
864                 // Argument checking
865                 AssertThrows<ArgumentNullException> (delegate () {
866                         o.GetValue (null);
867                         });
868         }
869
870         [Test]
871         public void Object_GetValues () {
872                 var e = run_until ("o1");
873                 var frame = e.Thread.GetFrames () [0];
874
875                 object val = frame.GetThis ();
876                 Assert.IsTrue (val is ObjectMirror);
877                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
878                 ObjectMirror o = (val as ObjectMirror);
879
880                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
881
882                 TypeMirror t = o.Type;
883
884                 object[] vals = o.GetValues (new FieldInfoMirror [] { t.GetField ("field_i"), t.GetField ("field_s") });
885                 object f = vals [0];
886                 AssertValue (42, f);
887                 f = vals [1];
888                 AssertValue ("S", f);
889
890                 // Argument checking
891                 AssertThrows<ArgumentNullException> (delegate () {
892                         o.GetValues (null);
893                         });
894
895                 AssertThrows<ArgumentNullException> (delegate () {
896                         o.GetValues (new FieldInfoMirror [] { null });
897                         });
898
899                 // field of another class
900                 AssertThrows<ArgumentException> (delegate () {
901                                 o.GetValue (val2.Type.GetField ("field_j"));
902                         });
903         }
904
905         void TestSetValue (ObjectMirror o, string field_name, object val) {
906                 if (val is string)
907                         o.SetValue (o.Type.GetField (field_name), vm.RootDomain.CreateString ((string)val));
908                 else
909                         o.SetValue (o.Type.GetField (field_name), vm.CreateValue (val));
910                 Value f = o.GetValue (o.Type.GetField (field_name));
911                 AssertValue (val, f);
912         }
913
914         [Test]
915         public void Object_SetValues () {
916                 var e = run_until ("o1");
917                 var frame = e.Thread.GetFrames () [0];
918
919                 object val = frame.GetThis ();
920                 Assert.IsTrue (val is ObjectMirror);
921                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
922                 ObjectMirror o = (val as ObjectMirror);
923
924                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
925
926                 TestSetValue (o, "field_i", 22);
927                 TestSetValue (o, "field_bool1", false);
928                 TestSetValue (o, "field_bool2", true);
929                 TestSetValue (o, "field_char", 'B');
930                 TestSetValue (o, "field_byte", (byte)129);
931                 TestSetValue (o, "field_sbyte", (sbyte)-33);
932                 TestSetValue (o, "field_short", (short)(Int16.MaxValue - 5));
933                 TestSetValue (o, "field_ushort", (ushort)(UInt16.MaxValue - 5));
934                 TestSetValue (o, "field_long", Int64.MaxValue - 5);
935                 TestSetValue (o, "field_ulong", (ulong)(UInt64.MaxValue - 5));
936                 TestSetValue (o, "field_float", 6.28f);
937                 TestSetValue (o, "field_double", 6.28);
938                 TestSetValue (o, "static_i", 23);
939                 TestSetValue (o, "field_s", "CDEF");
940
941                 Value f;
942
943                 // intptrs
944                 f = o.GetValue (o.Type.GetField ("field_intptr"));
945                 Assert.IsInstanceOfType (typeof (StructMirror), f);
946                 AssertValue (Int32.MaxValue - 5, (f as StructMirror).Fields [0]);
947
948                 // enums
949                 FieldInfoMirror field = o.Type.GetField ("field_enum");
950                 f = o.GetValue (field);
951                 (f as EnumMirror).Value = 5;
952                 o.SetValue (field, f);
953                 f = o.GetValue (field);
954                 Assert.AreEqual (5, (f as EnumMirror).Value);
955
956                 // null
957                 o.SetValue (o.Type.GetField ("field_s"), vm.CreateValue (null));
958                 f = o.GetValue (o.Type.GetField ("field_s"));
959                 AssertValue (null, f);
960
961                 // vtype instances
962                 field = o.Type.GetField ("generic_field_struct");
963                 f = o.GetValue (field);
964                 o.SetValue (field, f);
965
966                 // nullables
967                 field = o.Type.GetField ("field_nullable");
968                 f = o.GetValue (field);
969                 AssertValue (0, (f as StructMirror).Fields [0]);
970                 AssertValue (false, (f as StructMirror).Fields [1]);
971                 o.SetValue (field, vm.CreateValue (6));
972                 f = o.GetValue (field);
973                 AssertValue (6, (f as StructMirror).Fields [0]);
974                 AssertValue (true, (f as StructMirror).Fields [1]);
975                 o.SetValue (field, vm.CreateValue (null));
976                 f = o.GetValue (field);
977                 AssertValue (0, (f as StructMirror).Fields [0]);
978                 AssertValue (false, (f as StructMirror).Fields [1]);
979
980                 // Argument checking
981                 AssertThrows<ArgumentNullException> (delegate () {
982                                 o.SetValues (null, new Value [0]);
983                         });
984
985                 AssertThrows<ArgumentNullException> (delegate () {
986                                 o.SetValues (new FieldInfoMirror [0], null);
987                         });
988
989                 AssertThrows<ArgumentNullException> (delegate () {
990                                 o.SetValues (new FieldInfoMirror [] { null }, new Value [1] { null });
991                         });
992
993                 // vtype with a wrong type
994                 AssertThrows<ArgumentException> (delegate () {
995                                 o.SetValue (o.Type.GetField ("field_struct"), o.GetValue (o.Type.GetField ("field_enum")));
996                         });
997
998                 // reference type not assignment compatible
999                 AssertThrows<ArgumentException> (delegate () {
1000                                 o.SetValue (o.Type.GetField ("field_class"), o);
1001                         });
1002
1003                 // field of another class
1004                 AssertThrows<ArgumentException> (delegate () {
1005                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
1006                         });
1007         }
1008
1009         [Test]
1010         public void Type_SetValue () {
1011                 var e = run_until ("o1");
1012                 var frame = e.Thread.GetFrames () [0];
1013                 Value f;
1014
1015                 object val = frame.GetThis ();
1016                 Assert.IsTrue (val is ObjectMirror);
1017                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
1018                 ObjectMirror o = (val as ObjectMirror);
1019
1020                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1021
1022                 o.Type.SetValue (o.Type.GetField ("static_i"), vm.CreateValue (55));
1023                 f = o.Type.GetValue (o.Type.GetField ("static_i"));
1024                 AssertValue (55, f);
1025
1026                 o.Type.SetValue (o.Type.GetField ("static_s"), vm.RootDomain.CreateString ("B"));
1027                 f = o.Type.GetValue (o.Type.GetField ("static_s"));
1028                 AssertValue ("B", f);
1029
1030                 // Argument checking
1031                 AssertThrows<ArgumentNullException> (delegate () {
1032                                 o.Type.SetValue (null, vm.CreateValue (0));
1033                         });
1034
1035                 AssertThrows<ArgumentNullException> (delegate () {
1036                                 o.Type.SetValue (o.Type.GetField ("static_i"), null);
1037                         });
1038
1039                 // field of another class
1040                 AssertThrows<ArgumentException> (delegate () {
1041                                 o.SetValue (val2.Type.GetField ("field_j"), vm.CreateValue (1));
1042                         });
1043         }
1044
1045         [Test]
1046         public void TypeInfo () {
1047                 Event e = run_until ("ti2");
1048                 StackFrame frame = e.Thread.GetFrames () [0];
1049
1050                 TypeMirror t;
1051
1052                 // Array types
1053                 t = frame.Method.GetParameters ()[0].ParameterType;
1054
1055                 Assert.AreEqual ("String[]", t.Name);
1056                 Assert.AreEqual ("string[]", t.CSharpName);
1057                 Assert.AreEqual ("Array", t.BaseType.Name);
1058                 Assert.AreEqual (true, t.HasElementType);
1059                 Assert.AreEqual (true, t.IsArray);
1060                 Assert.AreEqual (1, t.GetArrayRank ());
1061                 Assert.AreEqual ("String", t.GetElementType ().Name);
1062
1063                 t = frame.Method.GetParameters ()[2].ParameterType;
1064
1065                 Assert.AreEqual ("Int32[,]", t.Name);
1066                 // FIXME:
1067                 //Assert.AreEqual ("int[,]", t.CSharpName);
1068                 Assert.AreEqual ("Array", t.BaseType.Name);
1069                 Assert.AreEqual (true, t.HasElementType);
1070                 Assert.AreEqual (true, t.IsArray);
1071                 Assert.AreEqual (2, t.GetArrayRank ());
1072                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
1073
1074                 // Byref types
1075                 t = frame.Method.GetParameters ()[3].ParameterType;
1076                 // FIXME:
1077                 //Assert.AreEqual ("Int32&", t.Name);
1078                 //Assert.AreEqual (true, t.IsByRef);
1079                 //Assert.AreEqual (true, t.HasElementType);
1080
1081                 // Pointer types
1082                 t = frame.Method.GetParameters ()[4].ParameterType;
1083                 // FIXME:
1084                 //Assert.AreEqual ("Int32*", t.Name);
1085                 Assert.AreEqual (true, t.IsPointer);
1086                 Assert.AreEqual (true, t.HasElementType);
1087                 Assert.AreEqual ("Int32", t.GetElementType ().Name);
1088                 Assert.AreEqual (false, t.IsPrimitive);
1089
1090                 // primitive types 
1091                 t = frame.Method.GetParameters ()[5].ParameterType;
1092                 Assert.AreEqual (true, t.IsPrimitive);
1093
1094                 // value types
1095                 t = frame.Method.GetParameters ()[6].ParameterType;
1096                 Assert.AreEqual ("AStruct", t.Name);
1097                 Assert.AreEqual (false, t.IsPrimitive);
1098                 Assert.AreEqual (true, t.IsValueType);
1099                 Assert.AreEqual (false, t.IsClass);
1100
1101                 // reference types
1102                 t = frame.Method.GetParameters ()[7].ParameterType;
1103                 Assert.AreEqual ("Tests", t.Name);
1104                 var nested = (from nt in t.GetNestedTypes () where nt.IsNestedPublic select nt).ToArray ();
1105                 Assert.AreEqual (1, nested.Length);
1106                 Assert.AreEqual ("NestedClass", nested [0].Name);
1107                 Assert.IsTrue (t.BaseType.IsAssignableFrom (t));
1108                 Assert.IsTrue (!t.IsAssignableFrom (t.BaseType));
1109
1110                 // generic instances
1111                 t = frame.Method.GetParameters ()[9].ParameterType;
1112                 Assert.AreEqual ("GClass`1", t.Name);
1113                 Assert.IsTrue (t.IsGenericType);
1114                 Assert.IsFalse (t.IsGenericTypeDefinition);
1115
1116                 var args = t.GetGenericArguments ();
1117                 Assert.AreEqual (1, args.Length);
1118                 Assert.AreEqual ("Int32", args [0].Name);
1119
1120                 // generic type definitions
1121                 var gtd = t.GetGenericTypeDefinition ();
1122                 Assert.AreEqual ("GClass`1", gtd.Name);
1123                 Assert.IsTrue (gtd.IsGenericType);
1124                 Assert.IsTrue (gtd.IsGenericTypeDefinition);
1125                 Assert.AreEqual (gtd, gtd.GetGenericTypeDefinition ());
1126
1127                 args = gtd.GetGenericArguments ();
1128                 Assert.AreEqual (1, args.Length);
1129                 Assert.AreEqual ("T", args [0].Name);
1130
1131                 // enums
1132                 t = frame.Method.GetParameters ()[10].ParameterType;
1133                 Assert.AreEqual ("AnEnum", t.Name);
1134                 Assert.IsTrue (t.IsEnum);
1135                 Assert.AreEqual ("Int32", t.EnumUnderlyingType.Name);
1136
1137                 // properties
1138                 t = frame.Method.GetParameters ()[7].ParameterType;
1139
1140                 var props = t.GetProperties ();
1141                 Assert.AreEqual (3, props.Length);
1142                 foreach (PropertyInfoMirror prop in props) {
1143                         ParameterInfoMirror[] indexes = prop.GetIndexParameters ();
1144
1145                         if (prop.Name == "IntProperty") {
1146                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1147                                 Assert.AreEqual ("get_IntProperty", prop.GetGetMethod ().Name);
1148                                 Assert.AreEqual ("set_IntProperty", prop.GetSetMethod ().Name);
1149                                 Assert.AreEqual (0, indexes.Length);
1150                         } else if (prop.Name == "ReadOnlyProperty") {
1151                                 Assert.AreEqual ("Int32", prop.PropertyType.Name);
1152                                 Assert.AreEqual ("get_ReadOnlyProperty", prop.GetGetMethod ().Name);
1153                                 Assert.AreEqual (null, prop.GetSetMethod ());
1154                                 Assert.AreEqual (0, indexes.Length);
1155                         } else if (prop.Name == "IndexedProperty") {
1156                                 Assert.AreEqual (1, indexes.Length);
1157                                 Assert.AreEqual ("Int32", indexes [0].ParameterType.Name);
1158                         }
1159                 }
1160
1161                 // custom attributes
1162                 t = frame.Method.GetParameters ()[8].ParameterType;
1163                 Assert.AreEqual ("Tests2", t.Name);
1164                 var attrs = t.GetCustomAttributes (true);
1165                 Assert.AreEqual (5, attrs.Length);
1166                 foreach (var attr in attrs) {
1167                         if (attr.Constructor.DeclaringType.Name == "DebuggerDisplayAttribute") {
1168                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1169                                 Assert.AreEqual ("Tests", attr.ConstructorArguments [0].Value);
1170                                 Assert.AreEqual (2, attr.NamedArguments.Count);
1171                                 Assert.AreEqual ("Name", attr.NamedArguments [0].Property.Name);
1172                                 Assert.AreEqual ("FOO", attr.NamedArguments [0].TypedValue.Value);
1173                                 Assert.AreEqual ("Target", attr.NamedArguments [1].Property.Name);
1174                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.NamedArguments [1].TypedValue.Value);
1175                                 Assert.AreEqual ("Int32", (attr.NamedArguments [1].TypedValue.Value as TypeMirror).Name);
1176                         } else if (attr.Constructor.DeclaringType.Name == "DebuggerTypeProxyAttribute") {
1177                                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1178                                 Assert.IsInstanceOfType (typeof (TypeMirror), attr.ConstructorArguments [0].Value);
1179                                 Assert.AreEqual ("Tests", (attr.ConstructorArguments [0].Value as TypeMirror).Name);
1180                         } else if (attr.Constructor.DeclaringType.Name == "BAttribute") {
1181                                 Assert.AreEqual (2, attr.NamedArguments.Count);
1182                                 Assert.AreEqual ("afield", attr.NamedArguments [0].Field.Name);
1183                                 Assert.AreEqual ("bfield", attr.NamedArguments [1].Field.Name);
1184                         } else if (attr.Constructor.DeclaringType.Name == "ClassInterfaceAttribute") {
1185                                 // inherited from System.Object
1186                                 //} else if (attr.Constructor.DeclaringType.Name == "Serializable") {
1187                                 // inherited from System.Object
1188                         } else if (attr.Constructor.DeclaringType.Name == "ComVisibleAttribute") {
1189                                 // inherited from System.Object
1190                         } else {
1191                                 Assert.Fail (attr.Constructor.DeclaringType.Name);
1192                         }
1193                 }
1194
1195                 var assembly = entry_point.DeclaringType.Assembly;
1196                 var type = assembly.GetType ("Tests4");
1197                 Assert.IsFalse (type.IsInitialized);
1198         }
1199
1200         [Test]
1201         public void FieldInfo () {
1202                 Event e = run_until ("ti2");
1203                 StackFrame frame = e.Thread.GetFrames () [0];
1204
1205                 TypeMirror t;
1206
1207                 t = frame.Method.GetParameters ()[8].ParameterType;
1208                 Assert.AreEqual ("Tests2", t.Name);
1209
1210                 var fi = t.GetField ("field_j");
1211                 var attrs = fi.GetCustomAttributes (true);
1212                 Assert.AreEqual (1, attrs.Length);
1213                 var attr = attrs [0];
1214                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1215                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1216                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1217                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1218         }
1219
1220         [Test]
1221         public void PropertyInfo () {
1222                 Event e = run_until ("ti2");
1223                 StackFrame frame = e.Thread.GetFrames () [0];
1224
1225                 TypeMirror t;
1226
1227                 t = frame.Method.GetParameters ()[8].ParameterType;
1228                 Assert.AreEqual ("Tests2", t.Name);
1229
1230                 var pi = t.GetProperty ("AProperty");
1231                 var attrs = pi.GetCustomAttributes (true);
1232                 Assert.AreEqual (1, attrs.Length);
1233                 var attr = attrs [0];
1234                 Assert.AreEqual ("DebuggerBrowsableAttribute", attr.Constructor.DeclaringType.Name);
1235                 Assert.AreEqual (1, attr.ConstructorArguments.Count);
1236                 Assert.IsInstanceOfType (typeof (EnumMirror), attr.ConstructorArguments [0].Value);
1237                 Assert.AreEqual ((int)System.Diagnostics.DebuggerBrowsableState.Collapsed, (attr.ConstructorArguments [0].Value as EnumMirror).Value);
1238         }
1239
1240         [Test]
1241         [Category ("only5")]
1242         public void Type_GetValue () {
1243                 Event e = run_until ("o1");
1244                 StackFrame frame = e.Thread.GetFrames () [0];
1245
1246                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1247
1248                 TypeMirror t = o.Type;
1249
1250                 ObjectMirror val2 = frame.GetValue (frame.Method.GetParameters ()[0]) as ObjectMirror;
1251
1252                 // static fields
1253                 object f = t.GetValue (o.Type.GetField ("static_i"));
1254                 AssertValue (55, f);
1255
1256                 f = t.GetValue (o.Type.GetField ("static_s"));
1257                 AssertValue ("A", f);
1258
1259                 // literal static fields
1260                 f = t.GetValue (o.Type.GetField ("literal_i"));
1261                 AssertValue (56, f);
1262
1263                 f = t.GetValue (o.Type.GetField ("literal_s"));
1264                 AssertValue ("B", f);
1265
1266                 // Inherited static fields
1267                 TypeMirror parent = t.BaseType;
1268                 f = t.GetValue (parent.GetField ("base_static_i"));
1269                 AssertValue (57, f);
1270
1271                 f = t.GetValue (parent.GetField ("base_static_s"));
1272                 AssertValue ("C", f);
1273
1274                 // thread static field
1275                 f = t.GetValue (t.GetField ("tls_i"), e.Thread);
1276                 AssertValue (42, f);
1277
1278                 // Argument checking
1279                 AssertThrows<ArgumentNullException> (delegate () {
1280                         t.GetValue (null);
1281                         });
1282
1283                 // instance fields
1284                 AssertThrows<ArgumentException> (delegate () {
1285                         t.GetValue (o.Type.GetField ("field_i"));
1286                         });
1287
1288                 // field on another type
1289                 AssertThrows<ArgumentException> (delegate () {
1290                                 t.GetValue (val2.Type.GetField ("static_field_j"));
1291                         });
1292
1293                 // special static field
1294                 AssertThrows<ArgumentException> (delegate () {
1295                                 t.GetValue (t.GetField ("tls_i"));
1296                         });
1297         }
1298
1299         [Test]
1300         public void Type_GetValues () {
1301                 Event e = run_until ("o1");
1302                 StackFrame frame = e.Thread.GetFrames () [0];
1303
1304                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1305
1306                 TypeMirror t = o.Type;
1307
1308                 // static fields
1309                 object[] vals = t.GetValues (new FieldInfoMirror [] { t.GetField ("static_i"), t.GetField ("static_s") });
1310                 object f = vals [0];
1311                 AssertValue (55, f);
1312
1313                 f = vals [1];
1314                 AssertValue ("A", f);
1315
1316                 // Argument checking
1317                 AssertThrows<ArgumentNullException> (delegate () {
1318                         t.GetValues (null);
1319                         });
1320
1321                 AssertThrows<ArgumentNullException> (delegate () {
1322                         t.GetValues (new FieldInfoMirror [] { null });
1323                         });
1324         }
1325
1326         [Test]
1327         public void ObjRefs () {
1328                 Event e = run_until ("objrefs1");
1329                 StackFrame frame = e.Thread.GetFrames () [0];
1330
1331                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1332                 ObjectMirror child = o.GetValue (o.Type.GetField ("child")) as ObjectMirror;
1333
1334                 Assert.IsTrue (child.Address != 0);
1335
1336                 // Check that object references are internalized correctly
1337                 Assert.AreEqual (o, frame.GetThis ());
1338
1339                 run_until ("objrefs2");
1340
1341                 // child should be gc'd now
1342                 // This is not deterministic
1343                 //Assert.IsTrue (child.IsCollected);
1344
1345                 /*
1346                  * No longer works since Type is read eagerly
1347                  */
1348                 /*
1349                 AssertThrows<ObjectCollectedException> (delegate () {
1350                         TypeMirror t = child.Type;
1351                         });
1352                 */
1353                 /*
1354                 AssertThrows<ObjectCollectedException> (delegate () {
1355                                 long addr = child.Address;
1356                         });
1357                 */
1358         }
1359
1360         [Test]
1361         public void Type_GetObject () {
1362                 Event e = run_until ("o1");
1363                 StackFrame frame = e.Thread.GetFrames () [0];
1364
1365                 ObjectMirror o = (frame.GetThis () as ObjectMirror);
1366
1367                 TypeMirror t = o.Type;
1368
1369                 Assert.AreEqual ("MonoType", t.GetTypeObject ().Type.Name);
1370         }
1371
1372         [Test]
1373         public void VTypes () {
1374                 Event e = run_until ("vtypes1");
1375                 StackFrame frame = e.Thread.GetFrames () [0];
1376
1377                 // vtypes as fields
1378                 ObjectMirror o = frame.GetThis () as ObjectMirror;
1379                 var obj = o.GetValue (o.Type.GetField ("field_struct"));
1380                 Assert.IsTrue (obj is StructMirror);
1381                 var s = obj as StructMirror;
1382                 Assert.AreEqual ("AStruct", s.Type.Name);
1383                 AssertValue (42, s ["i"]);
1384                 obj = s ["s"];
1385                 AssertValue ("S", obj);
1386                 AssertValue (43, s ["k"]);
1387                 obj = o.GetValue (o.Type.GetField ("field_boxed_struct"));
1388                 Assert.IsTrue (obj is StructMirror);
1389                 s = obj as StructMirror;
1390                 Assert.AreEqual ("AStruct", s.Type.Name);
1391                 AssertValue (42, s ["i"]);
1392
1393                 // Check decoding of nested structs (#14942)
1394                 obj = o.GetValue (o.Type.GetField ("nested_struct"));
1395                 o.SetValue (o.Type.GetField ("nested_struct"), obj);
1396
1397                 // Check round tripping of boxed struct fields (#12354)
1398                 obj = o.GetValue (o.Type.GetField ("boxed_struct_field"));
1399                 o.SetValue (o.Type.GetField ("boxed_struct_field"), obj);
1400                 obj = o.GetValue (o.Type.GetField ("boxed_struct_field"));
1401                 s = obj as StructMirror;
1402                 AssertValue (1, s ["key"]);
1403                 obj = s ["value"];
1404                 Assert.IsTrue (obj is StructMirror);
1405                 s = obj as StructMirror;
1406                 AssertValue (42, s ["m_value"]);
1407
1408                 // vtypes as arguments
1409                 s = frame.GetArgument (0) as StructMirror;
1410                 AssertValue (44, s ["i"]);
1411                 obj = s ["s"];
1412                 AssertValue ("T", obj);
1413                 AssertValue (45, s ["k"]);
1414
1415                 // vtypes as array entries
1416                 var arr = frame.GetArgument (1) as ArrayMirror;
1417                 obj = arr [0];
1418                 Assert.IsTrue (obj is StructMirror);
1419                 s = obj as StructMirror;
1420                 AssertValue (1, s ["i"]);
1421                 AssertValue ("S1", s ["s"]);
1422                 obj = arr [1];
1423                 Assert.IsTrue (obj is StructMirror);
1424                 s = obj as StructMirror;
1425                 AssertValue (2, s ["i"]);
1426                 AssertValue ("S2", s ["s"]);
1427
1428                 // Argument checking
1429                 s = frame.GetArgument (0) as StructMirror;
1430                 AssertThrows<ArgumentException> (delegate () {
1431                                 obj = s ["FOO"];
1432                         });
1433
1434                 // generic vtype instances
1435                 o = frame.GetThis () as ObjectMirror;
1436                 obj = o.GetValue (o.Type.GetField ("generic_field_struct"));
1437                 Assert.IsTrue (obj is StructMirror);
1438                 s = obj as StructMirror;
1439                 Assert.AreEqual ("GStruct`1", s.Type.Name);
1440                 AssertValue (42, s ["i"]);
1441
1442                 // this on vtype methods
1443                 e = run_until ("vtypes2");
1444                 e = step_until (e.Thread, "foo");
1445
1446                 frame = e.Thread.GetFrames () [0];
1447
1448                 Assert.AreEqual ("foo", (e as StepEvent).Method.Name);
1449                 obj = frame.GetThis ();
1450
1451                 Assert.IsTrue (obj is StructMirror);
1452                 s = obj as StructMirror;
1453                 AssertValue (44, s ["i"]);
1454                 AssertValue ("T", s ["s"]);
1455                 AssertValue (45, s ["k"]);
1456
1457                 // this on static vtype methods
1458                 e = run_until ("vtypes3");
1459                 e = step_until (e.Thread, "static_foo");
1460
1461                 frame = e.Thread.GetFrames () [0];
1462
1463                 Assert.AreEqual ("static_foo", (e as StepEvent).Method.Name);
1464                 obj = frame.GetThis ();
1465                 AssertValue (null, obj);
1466
1467                 // vtypes which reference themselves recursively
1468                 e = run_until ("vtypes4_2");
1469                 frame = e.Thread.GetFrames () [0];
1470
1471                 Assert.IsTrue (frame.GetArgument (0) is StructMirror);
1472         }
1473
1474         [Test]
1475         public void AssemblyInfo () {
1476                 Event e = run_until ("single_stepping");
1477
1478                 StackFrame frame = e.Thread.GetFrames () [0];
1479
1480                 var aname = frame.Method.DeclaringType.Assembly.GetName ();
1481                 Assert.AreEqual ("dtest-app, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", aname.ToString ());
1482
1483                 ModuleMirror m = frame.Method.DeclaringType.Module;
1484
1485                 Assert.AreEqual ("dtest-app.exe", m.Name);
1486                 Assert.AreEqual ("dtest-app.exe", m.ScopeName);
1487                 Assert.IsTrue (m.FullyQualifiedName.IndexOf ("dtest-app.exe") != -1);
1488                 Guid guid = m.ModuleVersionId;
1489                 Assert.AreEqual (frame.Method.DeclaringType.Assembly, m.Assembly);
1490                 Assert.AreEqual (frame.Method.DeclaringType.Assembly.ManifestModule, m);
1491
1492                 // This is no longer true on 4.0
1493                 //Assert.AreEqual ("Assembly", frame.Method.DeclaringType.Assembly.GetAssemblyObject ().Type.Name);
1494
1495                 TypeMirror t = vm.RootDomain.Corlib.GetType ("System.Diagnostics.DebuggerDisplayAttribute");
1496                 Assert.AreEqual ("DebuggerDisplayAttribute", t.Name);
1497         }
1498
1499         [Test]
1500         public void LocalsInfo () {
1501                 Event e = run_until ("locals2");
1502
1503                 StackFrame frame = e.Thread.GetFrames () [0];
1504
1505                 var locals = frame.Method.GetLocals ();
1506                 Assert.AreEqual (8, locals.Length);
1507                 for (int i = 0; i < 8; ++i) {
1508                         if (locals [i].Name == "args") {
1509                                 Assert.IsTrue (locals [i].IsArg);
1510                                 Assert.AreEqual ("String[]", locals [i].Type.Name);
1511                         } else if (locals [i].Name == "arg") {
1512                                 Assert.IsTrue (locals [i].IsArg);
1513                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1514                         } else if (locals [i].Name == "i") {
1515                                 Assert.IsFalse (locals [i].IsArg);
1516                                 Assert.AreEqual ("Int64", locals [i].Type.Name);
1517                         } else if (locals [i].Name == "j") {
1518                                 Assert.IsFalse (locals [i].IsArg);
1519                                 Assert.AreEqual ("Int32", locals [i].Type.Name);
1520                         } else if (locals [i].Name == "s") {
1521                                 Assert.IsFalse (locals [i].IsArg);
1522                                 Assert.AreEqual ("String", locals [i].Type.Name);
1523                         } else if (locals [i].Name == "t") {
1524                                 // gshared
1525                                 Assert.IsTrue (locals [i].IsArg);
1526                                 Assert.AreEqual ("String", locals [i].Type.Name);
1527                         } else if (locals [i].Name == "rs") {
1528                                 Assert.IsTrue (locals [i].IsArg);
1529                                 Assert.AreEqual ("String", locals [i].Type.Name);
1530                         } else if (locals [i].Name == "astruct") {
1531                         } else {
1532                                 Assert.Fail ();
1533                         }
1534                 }
1535         }
1536
1537         Event step_once () {
1538                 vm.Resume ();
1539                 var e = GetNextEvent ();
1540                 Assert.IsTrue (e is StepEvent);
1541                 return e;
1542         }
1543
1544         Event step_into () {
1545                 step_req.Disable ();
1546                 step_req.Depth = StepDepth.Into;
1547                 step_req.Enable ();
1548                 return step_once ();
1549         }
1550
1551         Event step_over () {
1552                 step_req.Disable ();
1553                 step_req.Depth = StepDepth.Over;
1554                 step_req.Enable ();
1555                 return step_once ();
1556         }
1557
1558         Event step_out () {
1559                 step_req.Disable ();
1560                 step_req.Depth = StepDepth.Out;
1561                 step_req.Enable ();
1562                 return step_once ();
1563         }
1564
1565         [Test]
1566         public void Locals () {
1567                 var be = run_until ("locals1");
1568
1569                 StackFrame frame = be.Thread.GetFrames () [0];
1570                 MethodMirror m1 = frame.Method;
1571
1572                 // Compiler generated byref local
1573                 foreach (var l in m1.GetLocals ()) {
1574                         // The byval flag is hidden from the type
1575                         if (l.Name != "ri" && l.Type.Name == "Double")
1576                                 AssertValue (null, frame.GetValue (l));
1577                 }
1578
1579                 be = run_until ("locals2");
1580
1581                 frame = be.Thread.GetFrames () [0];
1582
1583                 object val = frame.GetValue (frame.Method.GetLocal ("i"));
1584                 AssertValue (0, val);
1585
1586                 var req = create_step (be);
1587                 req.Enable ();
1588
1589                 // Skip nop
1590                 step_once ();
1591
1592                 // Execute i = 42
1593                 var e = step_once ();
1594                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1595
1596                 // Execute s = "AB";
1597                 e = step_once ();
1598                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1599
1600                 frame = e.Thread.GetFrames () [0];
1601
1602                 val = frame.GetValue (frame.Method.GetLocal ("i"));
1603                 AssertValue (42, val);
1604
1605                 LocalVariable[] locals = frame.Method.GetLocals ();
1606                 var vals = frame.GetValues (locals);
1607                 Assert.AreEqual (locals.Length, vals.Length);
1608                 for (int i = 0; i < locals.Length; ++i) {
1609                         if (locals [i].Name == "i")
1610                                 AssertValue (42, vals [i]);
1611                         if (locals [i].Name == "s")
1612                                 AssertValue ("AB", vals [i]);
1613                         if (locals [i].Name == "t")
1614                                 AssertValue ("ABC", vals [i]);
1615                 }
1616
1617                 // Argument checking
1618
1619                 // GetValue () null
1620                 AssertThrows<ArgumentNullException> (delegate () {
1621                                 frame.GetValue ((LocalVariable)null);
1622                         });
1623                 // GetValue () local from another method
1624                 AssertThrows<ArgumentException> (delegate () {
1625                                 frame.GetValue (m1.GetLocal ("foo"));
1626                         });
1627
1628                 // GetValue () null
1629                 AssertThrows<ArgumentNullException> (delegate () {
1630                                 frame.GetValue ((ParameterInfoMirror)null);
1631                         });
1632                 // GetValue () local from another method
1633                 AssertThrows<ArgumentException> (delegate () {
1634                                 frame.GetValue (m1.GetParameters ()[0]);
1635                         });
1636
1637                 // GetValues () null
1638                 AssertThrows<ArgumentNullException> (delegate () {
1639                                 frame.GetValues (null);
1640                         });
1641                 // GetValues () embedded null
1642                 AssertThrows<ArgumentNullException> (delegate () {
1643                                 frame.GetValues (new LocalVariable [] { null });
1644                         });
1645                 // GetValues () local from another method
1646                 AssertThrows<ArgumentException> (delegate () {
1647                                 frame.GetValues (new LocalVariable [] { m1.GetLocal ("foo") });
1648                         });
1649                 // return value
1650                 AssertThrows<ArgumentException> (delegate () {
1651                                 val = frame.GetValue (frame.Method.ReturnParameter);
1652                         });
1653
1654                 // invalid stack frames
1655                 vm.Resume ();
1656                 e = GetNextEvent ();
1657                 Assert.IsTrue (e is StepEvent);
1658                 Assert.AreEqual ("locals2", (e as StepEvent).Method.Name);
1659
1660                 AssertThrows<InvalidStackFrameException> (delegate () {
1661                                 frame.GetValue (frame.Method.GetLocal ("i"));
1662                         });
1663
1664                 req.Disable ();
1665
1666                 // gsharedvt
1667                 be = run_until ("locals7");
1668
1669                 req = create_step (be);
1670                 req.Enable ();
1671
1672                 // Skip nop
1673                 e = step_once ();
1674
1675                 // Test that locals are initialized
1676                 frame = e.Thread.GetFrames () [0];
1677                 val = frame.GetValue (frame.Method.GetLocal ("t"));
1678                 AssertValue (0, val);
1679
1680                 // Execute t = arg
1681                 e = step_once ();
1682                 Assert.AreEqual ("locals7", (e as StepEvent).Method.Name);
1683
1684                 // Execute t2 = t
1685                 e = step_once ();
1686                 Assert.AreEqual ("locals7", (e as StepEvent).Method.Name);
1687
1688                 frame = e.Thread.GetFrames () [0];
1689                 val = frame.GetValue (frame.Method.GetParameters ()[0]);
1690                 AssertValue (22, val);
1691                 val = frame.GetValue (frame.Method.GetLocal ("t"));
1692                 AssertValue (22, val);
1693                 val = frame.GetValue (frame.Method.GetLocal ("t2"));
1694                 AssertValue (22, val);
1695         }
1696
1697         [Test]
1698         public void GetVisibleVariables () {
1699                 Event e = run_until ("locals4");
1700
1701                 // First scope
1702                 var locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1703                 Assert.AreEqual (2, locals.Count);
1704                 var loc = locals.First (l => l.Name == "i");
1705                 Assert.AreEqual ("Int64", loc.Type.Name);
1706                 loc = locals.First (l => l.Name == "s");
1707                 Assert.AreEqual ("String", loc.Type.Name);
1708
1709                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1710                 Assert.AreEqual ("i", loc.Name);
1711                 Assert.AreEqual ("Int64", loc.Type.Name);
1712
1713                 e = run_until ("locals5");
1714
1715                 // Second scope
1716                 locals = e.Thread.GetFrames ()[1].GetVisibleVariables ();
1717                 Assert.AreEqual (2, locals.Count);
1718                 loc = locals.First (l => l.Name == "i");
1719                 Assert.AreEqual ("String", loc.Type.Name);
1720                 loc = locals.First (l => l.Name == "s");
1721                 Assert.AreEqual ("String", loc.Type.Name);
1722
1723                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("i");
1724                 Assert.AreEqual ("i", loc.Name);
1725                 Assert.AreEqual ("String", loc.Type.Name);
1726
1727                 // Variable in another scope
1728                 loc = e.Thread.GetFrames ()[1].GetVisibleVariableByName ("j");
1729                 Assert.IsNull (loc);
1730         }
1731
1732         [Test]
1733         public void Exit () {
1734                 run_until ("Main");
1735
1736                 vm.Exit (5);
1737
1738                 var e = GetNextEvent ();
1739                 Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
1740
1741                 Assert.AreEqual (5, (e as VMDeathEvent).ExitCode);
1742
1743                 var p = vm.Process;
1744                 /* Could be a remote vm with no process */
1745                 if (p != null) {
1746                         p.WaitForExit ();
1747                         Assert.AreEqual (5, p.ExitCode);
1748
1749                         // error handling
1750                         AssertThrows<VMDisconnectedException> (delegate () {
1751                                         vm.Resume ();
1752                                 });
1753                 }
1754
1755                 vm = null;
1756         }
1757
1758         [Test]
1759         public void Dispose () {
1760                 run_until ("Main");
1761
1762                 vm.Detach ();
1763
1764                 var e = GetNextEvent ();
1765                 Assert.IsInstanceOfType (typeof (VMDisconnectEvent), e);
1766
1767                 var p = vm.Process;
1768                 /* Could be a remote vm with no process */
1769                 if (p != null) {
1770                         p.WaitForExit ();
1771                         Assert.AreEqual (3, p.ExitCode);
1772
1773                         // error handling
1774                         AssertThrows<VMDisconnectedException> (delegate () {
1775                                         vm.Resume ();
1776                                 });
1777                 }
1778
1779                 vm = null;
1780         }
1781
1782         [Test]
1783         public void ColumnNumbers () {
1784                 Event e = run_until ("line_numbers");
1785
1786                 // FIXME: Merge this with LineNumbers () when its fixed
1787
1788                 step_req = create_step (e);
1789                 step_req.Depth = StepDepth.Into;
1790                 step_req.Enable ();
1791
1792                 Location l;
1793                 
1794                 while (true) {
1795                         vm.Resume ();
1796
1797                         e = GetNextEvent ();
1798                         Assert.IsTrue (e is StepEvent);
1799                         if (e.Thread.GetFrames ()[0].Method.Name == "ln1")
1800                                 break;
1801                 }
1802
1803                 // Do an additional step over so we are not on the beginning line of the method
1804                 step_req.Disable ();
1805                 step_req.Depth = StepDepth.Over;
1806                 step_req.Enable ();
1807                 vm.Resume ();
1808                 e = GetNextEvent ();
1809                 Assert.IsTrue (e is StepEvent);         
1810
1811                 l = e.Thread.GetFrames ()[0].Location;
1812
1813                 Assert.AreEqual (3, l.ColumnNumber);
1814
1815                 step_req.Disable ();
1816         }
1817
1818         [Test]
1819         // Broken by mcs+runtime changes (#5438)
1820         [Category("NotWorking")]
1821         public void LineNumbers () {
1822                 Event e = run_until ("line_numbers");
1823
1824                 step_req = create_step (e);
1825                 step_req.Depth = StepDepth.Into;
1826                 step_req.Enable ();
1827
1828                 Location l;
1829                 
1830                 vm.Resume ();
1831
1832                 e = GetNextEvent ();
1833                 Assert.IsTrue (e is StepEvent);
1834
1835                 l = e.Thread.GetFrames ()[0].Location;
1836
1837                 Assert.IsTrue (l.SourceFile.IndexOf ("dtest-app.cs") != -1);
1838                 Assert.AreEqual ("ln1", l.Method.Name);
1839
1840                 // Check hash
1841                 using (FileStream fs = new FileStream (l.SourceFile, FileMode.Open, FileAccess.Read)) {
1842                         MD5 md5 = MD5.Create ();
1843                         var hash = md5.ComputeHash (fs);
1844
1845                         for (int i = 0; i < 16; ++i)
1846                                 Assert.AreEqual (hash [i], l.SourceFileHash [i]);
1847                 }
1848                 
1849                 int line_base = l.LineNumber;
1850
1851                 vm.Resume ();
1852                 e = GetNextEvent ();
1853                 Assert.IsTrue (e is StepEvent);
1854                 l = e.Thread.GetFrames ()[0].Location;
1855                 Assert.AreEqual ("ln2", l.Method.Name);
1856                 Assert.AreEqual (line_base + 6, l.LineNumber);
1857
1858                 vm.Resume ();
1859                 e = GetNextEvent ();
1860                 Assert.IsTrue (e is StepEvent);
1861                 l = e.Thread.GetFrames ()[0].Location;
1862                 Assert.AreEqual ("ln1", l.Method.Name);
1863                 Assert.AreEqual (line_base + 1, l.LineNumber);
1864
1865                 vm.Resume ();
1866                 e = GetNextEvent ();
1867                 Assert.IsTrue (e is StepEvent);
1868                 l = e.Thread.GetFrames ()[0].Location;
1869                 Assert.AreEqual ("ln3", l.Method.Name);
1870                 Assert.AreEqual (line_base + 11, l.LineNumber);
1871
1872                 vm.Resume ();
1873                 e = GetNextEvent ();
1874                 Assert.IsTrue (e is StepEvent);
1875                 l = e.Thread.GetFrames ()[0].Location;
1876                 Assert.AreEqual ("ln3", l.Method.Name);
1877                 Assert.IsTrue (l.SourceFile.EndsWith ("FOO"));
1878                 Assert.AreEqual (55, l.LineNumber);
1879
1880                 vm.Resume ();
1881                 e = GetNextEvent ();
1882                 Assert.IsTrue (e is StepEvent);
1883                 l = e.Thread.GetFrames ()[0].Location;
1884                 Assert.AreEqual ("ln1", l.Method.Name);
1885                 Assert.AreEqual (line_base + 2, l.LineNumber);
1886
1887                 // GetSourceFiles ()
1888                 string[] sources = l.Method.DeclaringType.GetSourceFiles ();
1889                 Assert.AreEqual (2, sources.Length);
1890                 Assert.AreEqual ("dtest-app.cs", sources [0]);
1891                 Assert.AreEqual ("FOO", sources [1]);
1892
1893                 sources = l.Method.DeclaringType.GetSourceFiles (true);
1894                 Assert.AreEqual (2, sources.Length);
1895                 Assert.IsTrue (sources [0].EndsWith ("dtest-app.cs"));
1896                 Assert.IsTrue (sources [1].EndsWith ("FOO"));
1897         }
1898
1899         [Test]
1900         public void Suspend () {
1901                 vm.Detach ();
1902
1903                 Start (new string [] { "dtest-app.exe", "suspend-test" });
1904
1905                 Event e = run_until ("suspend");
1906
1907                 ThreadMirror main = e.Thread;
1908
1909                 vm.Resume ();
1910
1911                 Thread.Sleep (100);
1912
1913                 vm.Suspend ();
1914
1915                 // The debuggee should be suspended while it is running the infinite loop
1916                 // in suspend ()
1917                 StackFrame frame = main.GetFrames ()[0];
1918                 Assert.AreEqual ("suspend", frame.Method.Name);
1919
1920                 vm.Resume ();
1921
1922                 // resuming when not suspended
1923                 AssertThrows<InvalidOperationException> (delegate () {
1924                                 vm.Resume ();
1925                         });
1926
1927                 vm.Exit (0);
1928
1929                 vm = null;
1930         }
1931
1932         [Test]
1933         public void AssemblyLoad () {
1934                 Event e = run_until ("assembly_load");
1935
1936                 var load_req = vm.CreateAssemblyLoadRequest ();
1937                 load_req.Enable ();
1938
1939                 vm.Resume ();
1940
1941                 e = GetNextEvent ();
1942                 Assert.IsInstanceOfType (typeof (AssemblyLoadEvent), e);
1943                 Assert.IsTrue ((e as AssemblyLoadEvent).Assembly.Location.EndsWith ("System.dll"));
1944
1945                 var frames = e.Thread.GetFrames ();
1946                 Assert.IsTrue (frames.Length > 0);
1947                 Assert.AreEqual ("assembly_load", frames [0].Method.Name);
1948         }
1949
1950         [Test]
1951         public void CreateValue () {
1952                 PrimitiveValue v;
1953
1954                 v = vm.CreateValue (1);
1955                 Assert.AreEqual (vm, v.VirtualMachine);
1956                 Assert.AreEqual (1, v.Value);
1957
1958                 v = vm.CreateValue (null);
1959                 Assert.AreEqual (vm, v.VirtualMachine);
1960                 Assert.AreEqual (null, v.Value);
1961
1962                 // Argument checking
1963                 AssertThrows <ArgumentException> (delegate () {
1964                                 v = vm.CreateValue ("FOO");
1965                         });
1966         }
1967
1968         [Test]
1969         public void CreateString () {
1970                 StringMirror s = vm.RootDomain.CreateString ("ABC");
1971
1972                 Assert.AreEqual (vm, s.VirtualMachine);
1973                 Assert.AreEqual ("ABC", s.Value);
1974                 Assert.AreEqual (vm.RootDomain, s.Domain);
1975
1976                 // Long strings
1977                 StringBuilder sb = new StringBuilder ();
1978                 for (int i = 0; i < 1024; ++i)
1979                         sb.Append ('A');
1980                 s = vm.RootDomain.CreateString (sb.ToString ());
1981
1982                 // Argument checking
1983                 AssertThrows <ArgumentNullException> (delegate () {
1984                                 s = vm.RootDomain.CreateString (null);
1985                         });
1986         }
1987
1988         [Test]
1989         public void CreateBoxedValue () {
1990                 ObjectMirror o = vm.RootDomain.CreateBoxedValue (new PrimitiveValue (vm, 42));
1991
1992                 Assert.AreEqual ("Int32", o.Type.Name);
1993                 //AssertValue (42, m.GetValue (o.Type.GetField ("m_value")));
1994
1995                 // Argument checking
1996                 AssertThrows <ArgumentNullException> (delegate () {
1997                                 vm.RootDomain.CreateBoxedValue (null);
1998                         });
1999
2000                 AssertThrows <ArgumentException> (delegate () {
2001                                 vm.RootDomain.CreateBoxedValue (o);
2002                         });
2003         }
2004
2005         [Test]
2006         public void Invoke () {
2007                 Event e = run_until ("invoke1");
2008
2009                 StackFrame frame = e.Thread.GetFrames () [0];
2010
2011                 TypeMirror t = frame.Method.DeclaringType;
2012                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2013
2014                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2015
2016                 MethodMirror m;
2017                 Value v;
2018
2019                 // return void
2020                 m = t.GetMethod ("invoke_return_void");
2021                 v = this_obj.InvokeMethod (e.Thread, m, null);
2022                 Assert.IsNull (v);
2023
2024                 // return ref
2025                 m = t.GetMethod ("invoke_return_ref");
2026                 v = this_obj.InvokeMethod (e.Thread, m, null);
2027                 AssertValue ("ABC", v);
2028
2029                 // return null
2030                 m = t.GetMethod ("invoke_return_null");
2031                 v = this_obj.InvokeMethod (e.Thread, m, null);
2032                 AssertValue (null, v);
2033
2034                 // return primitive
2035                 m = t.GetMethod ("invoke_return_primitive");
2036                 v = this_obj.InvokeMethod (e.Thread, m, null);
2037                 AssertValue (42, v);
2038
2039                 // return nullable
2040                 m = t.GetMethod ("invoke_return_nullable");
2041                 v = this_obj.InvokeMethod (e.Thread, m, null);
2042                 Assert.IsInstanceOfType (typeof (StructMirror), v);
2043                 var s = v as StructMirror;
2044                 AssertValue (42, s.Fields [0]);
2045                 AssertValue (true, s.Fields [1]);
2046
2047                 // pass nullable as this
2048                 //m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2049                 m = s.Type.GetMethod ("ToString");
2050                 v = s.InvokeMethod (e.Thread, m, null);
2051
2052                 // return nullable null
2053                 m = t.GetMethod ("invoke_return_nullable_null");
2054                 v = this_obj.InvokeMethod (e.Thread, m, null);
2055                 Assert.IsInstanceOfType (typeof (StructMirror), v);
2056                 s = v as StructMirror;
2057                 AssertValue (0, s.Fields [0]);
2058                 AssertValue (false, s.Fields [1]);
2059
2060                 // pass nullable as this
2061                 //m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2062                 m = s.Type.GetMethod ("ToString");
2063                 v = s.InvokeMethod (e.Thread, m, null);
2064
2065                 // pass primitive
2066                 m = t.GetMethod ("invoke_pass_primitive");
2067                 Value[] args = new Value [] {
2068                         vm.CreateValue ((byte)Byte.MaxValue),
2069                         vm.CreateValue ((sbyte)SByte.MaxValue),
2070                         vm.CreateValue ((short)1),
2071                         vm.CreateValue ((ushort)1),
2072                         vm.CreateValue ((int)1),
2073                         vm.CreateValue ((uint)1),
2074                         vm.CreateValue ((long)1),
2075                         vm.CreateValue ((ulong)1),
2076                         vm.CreateValue ('A'),
2077                         vm.CreateValue (true),
2078                         vm.CreateValue (3.14f),
2079                         vm.CreateValue (3.14) };
2080
2081                 v = this_obj.InvokeMethod (e.Thread, m, args);
2082                 AssertValue ((int)Byte.MaxValue + (int)SByte.MaxValue + 1 + 1 + 1 + 1 + 1 + 1 + 'A' + 1 + 3 + 3, v);
2083
2084                 // pass ref
2085                 m = t.GetMethod ("invoke_pass_ref");
2086                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2087                 AssertValue ("ABC", v);
2088
2089                 // pass null
2090                 m = t.GetMethod ("invoke_pass_ref");
2091                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (null) });
2092                 AssertValue (null, v);
2093
2094                 // static
2095                 m = t.GetMethod ("invoke_static_pass_ref");
2096                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2097                 AssertValue ("ABC", v);
2098
2099                 // static invoked using ObjectMirror.InvokeMethod
2100                 m = t.GetMethod ("invoke_static_pass_ref");
2101                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2102                 AssertValue ("ABC", v);
2103
2104                 // method which throws an exception
2105                 try {
2106                         m = t.GetMethod ("invoke_throws");
2107                         v = this_obj.InvokeMethod (e.Thread, m, null);
2108                         Assert.Fail ();
2109                 } catch (InvocationException ex) {
2110                         Assert.AreEqual ("Exception", ex.Exception.Type.Name);
2111                 }
2112
2113 #if NET_4_5
2114                 // out argument
2115                 m = t.GetMethod ("invoke_out");
2116                 var out_task = this_obj.InvokeMethodAsyncWithResult (e.Thread, m, new Value [] { vm.CreateValue (1), vm.CreateValue (null) }, InvokeOptions.ReturnOutArgs);
2117                 var out_args = out_task.Result.OutArgs;
2118                 AssertValue (5, out_args [0]);
2119                 Assert.IsTrue (out_args [1] is ArrayMirror);
2120                 Assert.AreEqual (10, (out_args [1] as ArrayMirror).Length);
2121
2122                 // without ReturnOutArgs flag
2123                 out_task = this_obj.InvokeMethodAsyncWithResult (e.Thread, m, new Value [] { vm.CreateValue (1), vm.CreateValue (null) });
2124                 out_args = out_task.Result.OutArgs;
2125                 Assert.IsNull (out_args);
2126 #endif
2127
2128                 // newobj
2129                 m = t.GetMethod (".ctor");
2130                 v = t.InvokeMethod (e.Thread, m, null);
2131                 Assert.IsInstanceOfType (typeof (ObjectMirror), v);
2132                 Assert.AreEqual ("Tests", (v as ObjectMirror).Type.Name);
2133
2134                 // interface method
2135                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("ITest2");
2136                 m = cl1.GetMethod ("invoke_iface");
2137                 v = this_obj.InvokeMethod (e.Thread, m, null);
2138                 AssertValue (42, v);
2139
2140                 // virtual call
2141                 m = t.BaseType.GetMethod ("virtual_method");
2142                 v = this_obj.InvokeMethod (e.Thread, m, null, InvokeOptions.Virtual);
2143                 AssertValue ("V2", v);
2144
2145 #if NET_4_5
2146                 // instance
2147                 m = t.GetMethod ("invoke_pass_ref");
2148                 var task = this_obj.InvokeMethodAsync (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2149                 AssertValue ("ABC", task.Result);
2150
2151                 // static
2152                 m = t.GetMethod ("invoke_static_pass_ref");
2153                 task = t.InvokeMethodAsync (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2154                 AssertValue ("ABC", task.Result);
2155 #endif
2156
2157                 // Argument checking
2158                 
2159                 // null thread
2160                 AssertThrows<ArgumentNullException> (delegate {
2161                                 m = t.GetMethod ("invoke_pass_ref");
2162                                 v = this_obj.InvokeMethod (null, m, new Value [] { vm.CreateValue (null) });                            
2163                         });
2164
2165                 // null method
2166                 AssertThrows<ArgumentNullException> (delegate {
2167                                 v = this_obj.InvokeMethod (e.Thread, null, new Value [] { vm.CreateValue (null) });                             
2168                         });
2169
2170                 // invalid number of arguments
2171                 m = t.GetMethod ("invoke_pass_ref");
2172                 AssertThrows<ArgumentException> (delegate {
2173                                 v = this_obj.InvokeMethod (e.Thread, m, null);
2174                         });
2175
2176                 // invalid type of argument (ref != primitive)
2177                 m = t.GetMethod ("invoke_pass_ref");
2178                 AssertThrows<ArgumentException> (delegate {
2179                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2180                         });
2181
2182                 // invalid type of argument (primitive != primitive)
2183                 m = t.GetMethod ("invoke_pass_primitive_2");
2184                 AssertThrows<ArgumentException> (delegate {
2185                                 v = this_obj.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
2186                         });
2187
2188                 // invoking a non-static method as static
2189                 m = t.GetMethod ("invoke_pass_ref");
2190                 AssertThrows<ArgumentException> (delegate {
2191                                 v = t.InvokeMethod (e.Thread, m, new Value [] { vm.RootDomain.CreateString ("ABC") });
2192                         });
2193
2194                 // invoking a method defined in another class
2195                 m = t2.GetMethod ("invoke");
2196                 AssertThrows<ArgumentException> (delegate {
2197                                 v = this_obj.InvokeMethod (e.Thread, m, null);
2198                         });
2199         }
2200
2201         [Test]
2202         public void InvokeVType () {
2203                 Event e = run_until ("invoke1");
2204
2205                 StackFrame frame = e.Thread.GetFrames () [0];
2206
2207                 var s = frame.GetArgument (1) as StructMirror;
2208
2209                 TypeMirror t = s.Type;
2210
2211                 MethodMirror m;
2212                 Value v;
2213
2214                 // Pass struct as this, receive int
2215                 m = t.GetMethod ("invoke_return_int");
2216                 v = s.InvokeMethod (e.Thread, m, null);
2217                 AssertValue (42, v);
2218
2219                 // Pass struct as this, receive intptr
2220                 m = t.GetMethod ("invoke_return_intptr");
2221                 v = s.InvokeMethod (e.Thread, m, null);
2222                 AssertValue (43, v);
2223
2224                 // Static method
2225                 m = t.GetMethod ("invoke_static");
2226                 v = t.InvokeMethod (e.Thread, m, null);
2227                 AssertValue (5, v);
2228
2229                 // Pass generic struct as this
2230                 s = frame.GetArgument (2) as StructMirror;
2231                 t = s.Type;
2232                 m = t.GetMethod ("invoke_return_int");
2233                 v = s.InvokeMethod (e.Thread, m, null);
2234                 AssertValue (42, v);
2235
2236 #if NET_4_5
2237                 // Invoke a method which changes state
2238                 s = frame.GetArgument (1) as StructMirror;
2239                 t = s.Type;
2240                 m = t.GetMethod ("invoke_mutate");
2241                 var task = s.InvokeMethodAsyncWithResult (e.Thread, m, null, InvokeOptions.ReturnOutThis);
2242                 var out_this = task.Result.OutThis as StructMirror;
2243                 AssertValue (5, out_this ["l"]);
2244
2245                 // Without the ReturnOutThis flag
2246                 s = frame.GetArgument (1) as StructMirror;
2247                 t = s.Type;
2248                 m = t.GetMethod ("invoke_mutate");
2249                 task = s.InvokeMethodAsyncWithResult (e.Thread, m, null);
2250                 out_this = task.Result.OutThis as StructMirror;
2251                 Assert.AreEqual (null, out_this);
2252 #endif
2253         }
2254
2255         [Test]
2256         public void BreakpointDuringInvoke () {
2257                 Event e = run_until ("invoke1");
2258
2259                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
2260                 Assert.IsNotNull (m);
2261                 vm.SetBreakpoint (m, 0);
2262
2263                 StackFrame frame = e.Thread.GetFrames () [0];
2264                 var o = frame.GetThis () as ObjectMirror;
2265
2266                 bool failed = false;
2267
2268                 bool finished = false;
2269                 object wait = new object ();
2270
2271                 // Have to invoke in a separate thread as the invoke is suspended until we
2272                 // resume after the breakpoint
2273                 Thread t = new Thread (delegate () {
2274                                 try {
2275                                         o.InvokeMethod (e.Thread, m, null);
2276                                 } catch {
2277                                         failed = true;
2278                                 }
2279                                 lock (wait) {
2280                                         finished = true;
2281                                         Monitor.Pulse (wait);
2282                                 }
2283                         });
2284
2285                 t.Start ();
2286
2287                 StackFrame invoke_frame = null;
2288
2289                 try {
2290                         e = GetNextEvent ();
2291                         Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
2292                         // Check stack trace support and invokes
2293                         var frames = e.Thread.GetFrames ();
2294                         invoke_frame = frames [0];
2295                         Assert.AreEqual ("invoke2", frames [0].Method.Name);
2296                         Assert.IsTrue (frames [0].IsDebuggerInvoke);
2297                         Assert.AreEqual ("invoke1", frames [1].Method.Name);
2298                 } finally {
2299                         vm.Resume ();
2300                 }
2301
2302                 lock (wait) {
2303                         if (!finished)
2304                                 Monitor.Wait (wait);
2305                 }
2306
2307                 // Check that the invoke frames are no longer valid
2308                 AssertThrows<InvalidStackFrameException> (delegate {
2309                                 invoke_frame.GetThis ();
2310                         });
2311
2312                 // Check InvokeOptions.DisableBreakpoints flag
2313                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2314         }
2315
2316         [Test]
2317         public void DisabledExceptionDuringInvoke () {
2318                 Event e = run_until ("invoke_ex");
2319
2320                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_ex_inner");
2321
2322                 StackFrame frame = e.Thread.GetFrames () [0];
2323                 var o = frame.GetThis () as ObjectMirror;
2324
2325                 var req = vm.CreateExceptionRequest (null);
2326                 req.Enable ();
2327
2328                 // Check InvokeOptions.DisableBreakpoints flag
2329                 o.InvokeMethod (e.Thread, m, null, InvokeOptions.DisableBreakpoints);
2330
2331                 req.Disable ();
2332         }
2333
2334         [Test]
2335         public void InvokeSingleThreaded () {
2336                 vm.Detach ();
2337
2338                 Start (new string [] { "dtest-app.exe", "invoke-single-threaded" });
2339
2340                 Event e = run_until ("invoke_single_threaded_2");
2341
2342                 StackFrame f = e.Thread.GetFrames ()[0];
2343
2344                 var obj = f.GetThis () as ObjectMirror;
2345
2346                 // Check that the counter value incremented by the other thread does not increase
2347                 // during the invoke.
2348                 object counter1 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2349
2350                 var m = obj.Type.GetMethod ("invoke_return_void");
2351                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2352
2353             object counter2 = (obj.GetValue (obj.Type.GetField ("counter")) as PrimitiveValue).Value;
2354
2355                 Assert.AreEqual ((int)counter1, (int)counter2);
2356
2357                 // Test multiple invokes done in succession
2358                 m = obj.Type.GetMethod ("invoke_return_void");
2359                 obj.InvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded);
2360
2361                 // Test events during single-threaded invokes
2362                 vm.EnableEvents (EventType.TypeLoad);
2363                 m = obj.Type.GetMethod ("invoke_type_load");
2364                 obj.BeginInvokeMethod (e.Thread, m, null, InvokeOptions.SingleThreaded, delegate {
2365                                 vm.Resume ();
2366                         }, null);
2367
2368                 e = GetNextEvent ();
2369                 Assert.AreEqual (EventType.TypeLoad, e.EventType);
2370         }
2371
2372         List<Value> invoke_results;
2373
2374         [Test]
2375         public void InvokeMultiple () {
2376                 Event e = run_until ("invoke1");
2377
2378                 StackFrame frame = e.Thread.GetFrames () [0];
2379
2380                 TypeMirror t = frame.Method.DeclaringType;
2381                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2382
2383                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2384
2385                 var methods = new MethodMirror [2];
2386                 methods [0] = t.GetMethod ("invoke_return_ref");
2387                 methods [1] = t.GetMethod ("invoke_return_primitive");
2388
2389                 invoke_results = new List<Value> ();
2390
2391                 var r = this_obj.BeginInvokeMultiple (e.Thread, methods, null, InvokeOptions.SingleThreaded, invoke_multiple_cb, this_obj);
2392                 WaitHandle.WaitAll (new WaitHandle[] { r.AsyncWaitHandle });
2393                 this_obj.EndInvokeMultiple (r);
2394                 // The callback might still be running
2395                 while (invoke_results.Count < 2) {
2396                         Thread.Sleep (100);
2397                 }
2398                 if (invoke_results [0] is PrimitiveValue) {
2399                         AssertValue ("ABC", invoke_results [1]);
2400                         AssertValue (42, invoke_results [0]);
2401                 } else {
2402                         AssertValue ("ABC", invoke_results [0]);
2403                         AssertValue (42, invoke_results [1]);
2404                 }
2405         }
2406
2407         void invoke_multiple_cb (IAsyncResult ar) {
2408                 ObjectMirror this_obj = (ObjectMirror)ar.AsyncState;
2409
2410                 var res = this_obj.EndInvokeMethod (ar);
2411                 lock (invoke_results)
2412                         invoke_results.Add (res);
2413         }
2414
2415         [Test]
2416         public void GetThreads () {
2417                 vm.GetThreads ();
2418         }
2419
2420         [Test]
2421         public void Threads () {
2422                 Event e = run_until ("threads");
2423
2424                 Assert.AreEqual (ThreadState.Running, e.Thread.ThreadState);
2425
2426                 Assert.IsTrue (e.Thread.ThreadId > 0);
2427
2428                 Assert.AreEqual (e.Thread.TID, e.Thread.TID);
2429
2430                 vm.EnableEvents (EventType.ThreadStart, EventType.ThreadDeath);
2431
2432                 vm.Resume ();
2433
2434                 e = GetNextEvent ();
2435                 Assert.IsInstanceOfType (typeof (ThreadStartEvent), e);
2436                 var state = e.Thread.ThreadState;
2437                 Assert.IsTrue (state == ThreadState.Running || state == ThreadState.Unstarted);
2438
2439                 vm.Resume ();
2440
2441                 e = GetNextEvent ();
2442                 Assert.IsInstanceOfType (typeof (ThreadDeathEvent), e);
2443                 Assert.AreEqual (ThreadState.Stopped, e.Thread.ThreadState);
2444         }
2445
2446         [Test]
2447         public void Frame_SetValue () {
2448                 Event e = run_until ("locals2");
2449
2450                 StackFrame frame = e.Thread.GetFrames () [0];
2451
2452                 // primitive
2453                 var l = frame.Method.GetLocal ("i");
2454                 frame.SetValue (l, vm.CreateValue ((long)55));
2455                 AssertValue (55, frame.GetValue (l));
2456
2457                 // reference
2458                 l = frame.Method.GetLocal ("s");
2459                 frame.SetValue (l, vm.RootDomain.CreateString ("DEF"));
2460                 AssertValue ("DEF", frame.GetValue (l));
2461
2462                 // argument as local
2463                 l = frame.Method.GetLocal ("arg");
2464                 frame.SetValue (l, vm.CreateValue (6));
2465                 AssertValue (6, frame.GetValue (l));
2466
2467                 // argument
2468                 var p = frame.Method.GetParameters ()[1];
2469                 frame.SetValue (p, vm.CreateValue (7));
2470                 AssertValue (7, frame.GetValue (p));
2471
2472                 // gshared
2473                 p = frame.Method.GetParameters ()[2];
2474                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF"));
2475                 AssertValue ("DEF", frame.GetValue (p));
2476
2477                 // byref
2478                 p = frame.Method.GetParameters ()[3];
2479                 frame.SetValue (p, vm.RootDomain.CreateString ("DEF2"));
2480                 AssertValue ("DEF2", frame.GetValue (p));
2481
2482                 // byref struct
2483                 p = frame.Method.GetParameters ()[4];
2484                 var v = frame.GetValue (p) as StructMirror;
2485                 v ["i"] = vm.CreateValue (43);
2486                 frame.SetValue (p, v);
2487                 v = frame.GetValue (p) as StructMirror;
2488                 AssertValue (43, v ["i"]);
2489
2490                 // argument checking
2491
2492                 // variable null
2493                 AssertThrows<ArgumentNullException> (delegate () {
2494                                 frame.SetValue ((LocalVariable)null, vm.CreateValue (55));
2495                         });
2496
2497                 // value null
2498                 AssertThrows<ArgumentNullException> (delegate () {
2499                                 l = frame.Method.GetLocal ("i");
2500                                 frame.SetValue (l, null);
2501                         });
2502
2503                 // value of invalid type
2504                 AssertThrows<ArgumentException> (delegate () {
2505                                 l = frame.Method.GetLocal ("i");
2506                                 frame.SetValue (l, vm.CreateValue (55));
2507                         });
2508         }
2509
2510         [Test]
2511         [Category ("only")]
2512         public void Frame_SetValue_Registers () {
2513                 Event e = run_until ("locals6_1");
2514
2515                 StackFrame frame = e.Thread.GetFrames () [1];
2516
2517                 // Set 'j' to 99
2518                 var l = frame.Method.GetLocal ("j");
2519                 frame.SetValue (l, vm.CreateValue (99));
2520                 AssertValue (99, frame.GetValue (l));
2521
2522                 // Check it during execution
2523                 e = run_until ("locals6_2");
2524                 frame = e.Thread.GetFrames () [0];
2525                 AssertValue (99, frame.GetValue (frame.Method.GetParameters ()[0]));
2526
2527                 // Set it while in a frame which clobbers its register
2528                 e = run_until ("locals6_3");
2529                 frame = e.Thread.GetFrames () [1];
2530                 frame.SetValue (l, vm.CreateValue (100));
2531                 AssertValue (100, frame.GetValue (l));
2532
2533                 // Check it during execution
2534                 e = run_until ("locals6_4");
2535                 frame = e.Thread.GetFrames () [0];
2536                 AssertValue (100, frame.GetValue (frame.Method.GetParameters ()[0]));
2537
2538                 // Signed byte value
2539                 e = run_until ("locals6_5");
2540                 frame = e.Thread.GetFrames () [1];
2541                 var l2 = frame.Method.GetLocal ("sb");
2542                 frame.SetValue (l2, vm.CreateValue ((sbyte)-99));
2543                 AssertValue (-99, frame.GetValue (l2));
2544
2545                 // Check it during execution
2546                 e = run_until ("locals6_6");
2547                 frame = e.Thread.GetFrames () [0];
2548                 AssertValue (-99, frame.GetValue (frame.Method.GetParameters ()[0]));
2549         }
2550
2551         [Test]
2552         public void InvokeRegress () {
2553                 Event e = run_until ("invoke1");
2554
2555                 StackFrame frame = e.Thread.GetFrames () [0];
2556
2557                 TypeMirror t = frame.Method.DeclaringType;
2558                 ObjectMirror this_obj = (ObjectMirror)frame.GetThis ();
2559
2560                 TypeMirror t2 = frame.Method.GetParameters ()[0].ParameterType;
2561
2562                 MethodMirror m;
2563                 Value v;
2564
2565                 // do an invoke
2566                 m = t.GetMethod ("invoke_return_void");
2567                 v = this_obj.InvokeMethod (e.Thread, m, null);
2568                 Assert.IsNull (v);
2569
2570                 // Check that the stack frames remain valid during the invoke
2571                 Assert.AreEqual ("Tests", (frame.GetThis () as ObjectMirror).Type.Name);
2572
2573                 // do another invoke
2574                 m = t.GetMethod ("invoke_return_void");
2575                 v = this_obj.InvokeMethod (e.Thread, m, null);
2576                 Assert.IsNull (v);
2577
2578                 // Try a single step after the invoke
2579                 var req = create_step (e);
2580                 req.Depth = StepDepth.Into;
2581                 req.Size = StepSize.Line;
2582                 req.Enable ();
2583
2584                 // Skip nop
2585                 step_once ();
2586
2587                 // Step into invoke2
2588                 vm.Resume ();
2589                 e = GetNextEvent ();
2590                 Assert.IsTrue (e is StepEvent);
2591                 Assert.AreEqual ("invoke2", (e as StepEvent).Method.Name);
2592
2593                 req.Disable ();
2594
2595                 frame = e.Thread.GetFrames () [0];
2596         }
2597
2598         [Test]
2599         public void Exceptions () {
2600                 Event e = run_until ("exceptions");
2601                 var req = vm.CreateExceptionRequest (null);
2602                 req.Enable ();
2603
2604                 vm.Resume ();
2605
2606                 e = GetNextEvent ();
2607                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2608                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2609
2610                 var frames = e.Thread.GetFrames ();
2611                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2612                 req.Disable ();
2613
2614                 // exception type filter
2615
2616                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.ArgumentException"));
2617                 req.Enable ();
2618
2619                 // Skip the throwing of the second OverflowException       
2620                 vm.Resume ();
2621
2622                 e = GetNextEvent ();
2623                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2624                 Assert.AreEqual ("ArgumentException", (e as ExceptionEvent).Exception.Type.Name);
2625                 req.Disable ();
2626
2627                 // exception type filter for subclasses
2628                 req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.Exception"));
2629                 req.Enable ();
2630
2631                 vm.Resume ();
2632
2633                 e = GetNextEvent ();
2634                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2635                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2636                 req.Disable ();
2637
2638                 // no subclasses
2639                 req.IncludeSubclasses = false;
2640                 req.Enable ();
2641
2642                 vm.Resume ();
2643
2644                 e = GetNextEvent ();
2645                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2646                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
2647                 req.Disable ();
2648
2649                 // Implicit exceptions
2650                 req = vm.CreateExceptionRequest (null);
2651                 req.Enable ();
2652
2653                 vm.Resume ();
2654
2655                 e = GetNextEvent ();
2656                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2657                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2658                 req.Disable ();
2659
2660                 // Single stepping after an exception
2661                 req = vm.CreateExceptionRequest (null);
2662                 req.Enable ();
2663
2664                 vm.Resume ();
2665
2666                 e = GetNextEvent ();
2667                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2668                 Assert.AreEqual ("Exception", (e as ExceptionEvent).Exception.Type.Name);
2669                 frames = e.Thread.GetFrames ();
2670                 Assert.AreEqual ("exceptions2", frames [0].Method.Name);
2671                 req.Disable ();
2672
2673                 var sreq = create_step (e);
2674                 sreq.Depth = StepDepth.Over;
2675                 sreq.Size = StepSize.Line;
2676                 sreq.Enable ();
2677
2678                 vm.Resume ();
2679                 e = GetNextEvent ();
2680                 Assert.IsInstanceOfType (typeof (StepEvent), e);
2681                 frames = e.Thread.GetFrames ();
2682                 Assert.AreEqual ("exceptions", frames [0].Method.Name);
2683                 sreq.Disable ();
2684
2685                 // Argument checking
2686                 AssertThrows<ArgumentException> (delegate {
2687                                 vm.CreateExceptionRequest (e.Thread.Type);
2688                         });
2689         }
2690
2691         [Test]
2692         public void ExceptionFilter () {
2693                 Event e = run_until ("exception_filter");
2694
2695                 MethodMirror m = entry_point.DeclaringType.GetMethod ("exception_filter_filter");
2696                 Assert.IsNotNull (m);
2697
2698                 vm.SetBreakpoint (m, 0);
2699
2700                 vm.Resume ();
2701
2702                 e = GetNextEvent ();
2703                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
2704                 Assert.IsTrue (e is BreakpointEvent);
2705                 Assert.AreEqual (m.Name, (e as BreakpointEvent).Method.Name);
2706
2707                 var frames = e.Thread.GetFrames ();
2708
2709                 Assert.IsTrue (frames [0].Location.SourceFile.IndexOf ("dtest-app.cs") != -1);
2710                 Assert.AreEqual ("exception_filter_filter", frames [0].Location.Method.Name);
2711
2712                 Assert.AreEqual (0, frames [1].Location.Method.MetadataToken);
2713                 Assert.AreEqual (0x0f, frames [1].Location.ILOffset);
2714
2715                 Assert.AreEqual ("exception_filter_method", frames [2].Location.Method.Name);
2716                 Assert.AreEqual (0x06, frames [2].Location.ILOffset);
2717
2718                 Assert.AreEqual (0, frames [3].Location.Method.MetadataToken, 0);
2719                 Assert.AreEqual (0, frames [3].Location.ILOffset);
2720
2721                 Assert.AreEqual ("exception_filter", frames [4].Location.Method.Name);
2722         }
2723
2724         [Test]
2725         public void ExceptionFilter2 () {
2726                 vm.Detach ();
2727
2728                 Start (new string [] { "dtest-excfilter.exe" });
2729
2730                 MethodMirror filter_method = entry_point.DeclaringType.GetMethod ("Filter");
2731                 Assert.IsNotNull (filter_method);
2732
2733                 MethodMirror test_method = entry_point.DeclaringType.GetMethod ("Test");
2734                 Assert.IsNotNull (test_method);
2735
2736                 vm.SetBreakpoint (filter_method, 0);
2737
2738                 vm.Resume ();
2739
2740                 var e = GetNextEvent ();
2741                 Assert.AreEqual (EventType.Breakpoint, e.EventType);
2742                 Assert.IsTrue (e is BreakpointEvent);
2743                 Assert.AreEqual (filter_method.Name, (e as BreakpointEvent).Method.Name);
2744
2745                 var frames = e.Thread.GetFrames ();
2746
2747                 Assert.AreEqual (4, frames.Count ());
2748
2749                 Assert.AreEqual (filter_method.Name, frames [0].Location.Method.Name);
2750                 Assert.AreEqual (20, frames [0].Location.LineNumber);
2751                 Assert.AreEqual (0, frames [0].Location.ILOffset);
2752
2753                 Assert.AreEqual (test_method.Name, frames [1].Location.Method.Name);
2754                 Assert.AreEqual (37, frames [1].Location.LineNumber);
2755                 Assert.AreEqual (0x0b, frames [1].Location.ILOffset);
2756
2757                 Assert.AreEqual (test_method.Name, frames [2].Location.Method.Name);
2758                 Assert.AreEqual (33, frames [2].Location.LineNumber);
2759                 Assert.AreEqual (0x05, frames [2].Location.ILOffset);
2760
2761                 Assert.AreEqual (entry_point.Name, frames [3].Location.Method.Name);
2762                 Assert.AreEqual (14, frames [3].Location.LineNumber);
2763                 Assert.AreEqual (0x00, frames [3].Location.ILOffset);
2764
2765                 vm.Exit (0);
2766
2767                 vm = null;
2768         }
2769
2770         [Test]
2771         public void EventSets () {
2772                 //
2773                 // Create two filter which both match the same exception
2774                 //
2775                 Event e = run_until ("exceptions");
2776
2777                 var req = vm.CreateExceptionRequest (null);
2778                 req.Enable ();
2779
2780                 var req2 = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.OverflowException"));
2781                 req2.Enable ();
2782
2783                 vm.Resume ();
2784
2785                 var es = vm.GetNextEventSet ();
2786                 Assert.AreEqual (2, es.Events.Length);
2787
2788                 e = es [0];
2789                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2790                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2791
2792                 e = es [1];
2793                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2794                 Assert.AreEqual ("OverflowException", (e as ExceptionEvent).Exception.Type.Name);
2795
2796                 req.Disable ();
2797                 req2.Disable ();
2798         }
2799
2800         //
2801         // Test single threaded invokes during processing of nullref exceptions.
2802         // These won't work if the exception handling is done from the sigsegv signal
2803         // handler, since the sigsegv signal is disabled until control returns from the
2804         // signal handler.
2805         //
2806         [Test]
2807         [Category ("only3")]
2808         public void NullRefExceptionAndSingleThreadedInvoke () {
2809                 Event e = run_until ("exceptions");
2810                 var req = vm.CreateExceptionRequest (vm.RootDomain.Corlib.GetType ("System.NullReferenceException"));
2811                 req.Enable ();
2812
2813                 vm.Resume ();
2814
2815                 e = GetNextEvent ();
2816                 Assert.IsInstanceOfType (typeof (ExceptionEvent), e);
2817                 Assert.AreEqual ("NullReferenceException", (e as ExceptionEvent).Exception.Type.Name);
2818
2819                 var ex = (e as ExceptionEvent).Exception;
2820                 var tostring_method = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
2821                 ex.InvokeMethod (e.Thread, tostring_method, null, InvokeOptions.SingleThreaded);
2822         }
2823
2824         [Test]
2825         public void Domains () {
2826                 vm.Detach ();
2827
2828                 Start (new string [] { "dtest-app.exe", "domain-test" });
2829
2830                 vm.EnableEvents (EventType.AppDomainCreate, EventType.AppDomainUnload, EventType.AssemblyUnload);
2831
2832                 Event e = run_until ("domains");
2833
2834                 vm.Resume ();
2835                 
2836                 e = GetNextEvent ();
2837                 Assert.IsInstanceOfType (typeof (AppDomainCreateEvent), e);
2838
2839                 var domain = (e as AppDomainCreateEvent).Domain;
2840
2841                 // Check the object type
2842                 e = run_until ("domains_2");
2843                 var frame = e.Thread.GetFrames ()[0];
2844                 var o = frame.GetArgument (0) as ObjectMirror;
2845                 Assert.AreEqual ("CrossDomain", o.Type.Name);
2846
2847                 // Do a remoting invoke
2848                 var cross_domain_type = o.Type;
2849                 var v = o.InvokeMethod (e.Thread, cross_domain_type.GetMethod ("invoke_3"), null);
2850                 AssertValue (42, v);
2851
2852                 // Run until the callback in the domain
2853                 MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke_in_domain");
2854                 Assert.IsNotNull (m);
2855                 vm.SetBreakpoint (m, 0);
2856
2857                 while (true) {
2858                         vm.Resume ();
2859                         e = GetNextEvent ();
2860                         if (e is BreakpointEvent)
2861                                 break;
2862                 }
2863
2864                 Assert.AreEqual ("invoke_in_domain", (e as BreakpointEvent).Method.Name);
2865
2866                 // d_method is from another domain
2867                 MethodMirror d_method = (e as BreakpointEvent).Method;
2868                 Assert.IsTrue (m != d_method);
2869
2870                 var frames = e.Thread.GetFrames ();
2871                 Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name);
2872                 Assert.AreEqual (domain, frames [0].Domain);
2873                 Assert.AreEqual ("invoke", frames [1].Method.Name);
2874                 Assert.AreEqual ("domains", frames [2].Method.Name);
2875                 Assert.AreEqual (vm.RootDomain, frames [2].Domain);
2876
2877                 // Test breakpoints on already JITted methods in other domains
2878                 m = entry_point.DeclaringType.GetMethod ("invoke_in_domain_2");
2879                 Assert.IsNotNull (m);
2880                 vm.SetBreakpoint (m, 0);
2881
2882                 while (true) {
2883                         vm.Resume ();
2884                         e = GetNextEvent ();
2885                         if (e is BreakpointEvent)
2886                                 break;
2887                 }
2888
2889                 Assert.AreEqual ("invoke_in_domain_2", (e as BreakpointEvent).Method.Name);
2890
2891                 // This is empty when receiving the AppDomainCreateEvent
2892                 Assert.AreEqual ("domain", domain.FriendlyName);
2893
2894                 // Run until the unload
2895                 while (true) {
2896                         vm.Resume ();
2897                         e = GetNextEvent ();
2898                         if (e is AssemblyUnloadEvent) {
2899                                 continue;
2900                         } else {
2901                                 break;
2902                         }
2903                 }
2904                 Assert.IsInstanceOfType (typeof (AppDomainUnloadEvent), e);
2905                 Assert.AreEqual (domain, (e as AppDomainUnloadEvent).Domain);
2906
2907                 // Run past the unload
2908                 e = run_until ("domains_3");
2909
2910                 // Test access to unloaded types
2911                 // FIXME: Add an exception type for this
2912                 AssertThrows<Exception> (delegate {
2913                                 d_method.DeclaringType.GetValue (d_method.DeclaringType.GetField ("static_i"));
2914                         });
2915         }
2916
2917         [Test]
2918         public void DynamicMethods () {
2919                 Event e = run_until ("dyn_call");
2920
2921                 var m = e.Thread.GetFrames ()[1].Method;
2922                 Assert.AreEqual ("dyn_method", m.Name);
2923
2924                 // Test access to IL
2925                 var body = m.GetMethodBody ();
2926
2927                 ILInstruction ins = body.Instructions [0];
2928                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2929                 Assert.AreEqual ("FOO", ins.Operand);
2930         }
2931
2932         [Test]
2933         public void RefEmit () {
2934                 vm.Detach ();
2935
2936                 Start (new string [] { "dtest-app.exe", "ref-emit-test" });
2937
2938                 Event e = run_until ("ref_emit_call");
2939
2940                 var m = e.Thread.GetFrames ()[1].Method;
2941                 Assert.AreEqual ("ref_emit_method", m.Name);
2942
2943                 // Test access to IL
2944                 var body = m.GetMethodBody ();
2945
2946                 ILInstruction ins;
2947
2948                 ins = body.Instructions [0];
2949                 Assert.AreEqual (OpCodes.Ldstr, ins.OpCode);
2950                 Assert.AreEqual ("FOO", ins.Operand);
2951
2952                 ins = body.Instructions [1];
2953                 Assert.AreEqual (OpCodes.Call, ins.OpCode);
2954                 Assert.IsInstanceOfType (typeof (MethodMirror), ins.Operand);
2955                 Assert.AreEqual ("ref_emit_call", (ins.Operand as MethodMirror).Name);
2956         }
2957
2958         [Test]
2959         public void IsAttached () {
2960                 var f = entry_point.DeclaringType.GetField ("is_attached");
2961
2962                 Event e = run_until ("Main");
2963
2964                 AssertValue (true, entry_point.DeclaringType.GetValue (f));
2965         }
2966
2967         [Test]
2968         public void StackTraceInNative () {
2969                 // Check that stack traces can be produced for threads in native code
2970                 vm.Detach ();
2971
2972                 Start (new string [] { "dtest-app.exe", "frames-in-native" });
2973
2974                 var e = run_until ("frames_in_native");
2975
2976                 // FIXME: This is racy
2977                 vm.Resume ();
2978
2979                 Thread.Sleep (100);
2980
2981                 vm.Suspend ();
2982
2983                 StackFrame[] frames = e.Thread.GetFrames ();
2984
2985                 int frame_index = -1;
2986                 for (int i = 0; i < frames.Length; ++i) {
2987                         if (frames [i].Method.Name == "Sleep") {
2988                                 frame_index = i;
2989                                 break;
2990                         }
2991                 }
2992
2993                 Assert.IsTrue (frame_index != -1);
2994                 Assert.AreEqual ("Sleep", frames [frame_index].Method.Name);
2995                 Assert.AreEqual ("frames_in_native", frames [frame_index + 1].Method.Name);
2996                 Assert.AreEqual ("Main", frames [frame_index + 2].Method.Name);
2997
2998                 // Check that invokes are disabled for such threads
2999                 TypeMirror t = frames [frame_index + 1].Method.DeclaringType;
3000
3001                 var m = t.GetMethod ("invoke_static_return_void");
3002                 AssertThrows<InvalidOperationException> (delegate {
3003                                 t.InvokeMethod (e.Thread, m, null);
3004                         });
3005
3006                 // Check that the frame info is invalidated
3007                 run_until ("frames_in_native_2");
3008
3009                 AssertThrows<InvalidStackFrameException> (delegate {
3010                                 Console.WriteLine (frames [frame_index].GetThis ());
3011                         });
3012         }
3013
3014         [Test]
3015         public void VirtualMachine_CreateEnumMirror () {
3016                 var e = run_until ("o1");
3017                 var frame = e.Thread.GetFrames () [0];
3018
3019                 object val = frame.GetThis ();
3020                 Assert.IsTrue (val is ObjectMirror);
3021                 Assert.AreEqual ("Tests", (val as ObjectMirror).Type.Name);
3022                 ObjectMirror o = (val as ObjectMirror);
3023
3024                 FieldInfoMirror field = o.Type.GetField ("field_enum");
3025                 Value f = o.GetValue (field);
3026                 TypeMirror enumType = (f as EnumMirror).Type;
3027
3028                 o.SetValue (field, vm.CreateEnumMirror (enumType, vm.CreateValue (1)));
3029                 f = o.GetValue (field);
3030                 Assert.AreEqual (1, (f as EnumMirror).Value);
3031
3032                 // Argument checking
3033                 AssertThrows<ArgumentNullException> (delegate () {
3034                                 vm.CreateEnumMirror (enumType, null);
3035                         });
3036
3037                 AssertThrows<ArgumentNullException> (delegate () {
3038                                 vm.CreateEnumMirror (null, vm.CreateValue (1));
3039                         });
3040
3041                 // null value
3042                 AssertThrows<ArgumentException> (delegate () {
3043                                 vm.CreateEnumMirror (enumType, vm.CreateValue (null));
3044                         });
3045
3046                 // value of a wrong type
3047                 AssertThrows<ArgumentException> (delegate () {
3048                                 vm.CreateEnumMirror (enumType, vm.CreateValue ((long)1));
3049                         });
3050         }
3051
3052         [Test]
3053         public void VirtualMachine_EnableEvents_Breakpoint () {
3054                 AssertThrows<ArgumentException> (delegate () {
3055                                 vm.EnableEvents (EventType.Breakpoint);
3056                         });
3057         }
3058
3059         [Test]
3060         public void SingleStepRegress654694 () {
3061                 int il_offset = -1;
3062
3063                 MethodMirror m = entry_point.DeclaringType.GetMethod ("ss_regress_654694");
3064                 foreach (Location l in m.Locations) {
3065                         if (l.ILOffset > 0 && il_offset == -1)
3066                                 il_offset = l.ILOffset;
3067                 }
3068
3069                 Event e = run_until ("ss_regress_654694");
3070
3071                 Assert.IsNotNull (m);
3072                 vm.SetBreakpoint (m, il_offset);
3073
3074                 vm.Resume ();
3075
3076                 e = GetNextEvent ();
3077                 Assert.IsTrue (e is BreakpointEvent);
3078
3079                 var req = create_step (e);
3080                 req.Depth = StepDepth.Over;
3081                 req.Size = StepSize.Line;
3082                 req.Enable ();
3083
3084                 vm.Resume ();
3085
3086                 e = GetNextEvent ();
3087                 Assert.IsTrue (e is StepEvent);
3088
3089                 req.Disable ();
3090         }
3091
3092         [Test]
3093         public void DebugBreak () {
3094                 vm.EnableEvents (EventType.UserBreak);
3095
3096                 run_until ("user");
3097
3098                 vm.Resume ();
3099                 var e = GetNextEvent ();
3100                 Assert.IsTrue (e is UserBreakEvent);
3101         }
3102
3103         [Test]
3104         public void DebugLog () {
3105                 vm.EnableEvents (EventType.UserLog);
3106
3107                 run_until ("user");
3108
3109                 vm.Resume ();
3110                 var e = GetNextEvent ();
3111                 Assert.IsTrue (e is UserLogEvent);
3112                 var le = e as UserLogEvent;
3113
3114                 Assert.AreEqual (5, le.Level);
3115                 Assert.AreEqual ("A", le.Category);
3116                 Assert.AreEqual ("B", le.Message);
3117         }
3118
3119         [Test]
3120         public void TypeGetMethodsByNameFlags () {
3121                 MethodMirror[] mm;
3122                 var assembly = entry_point.DeclaringType.Assembly;
3123                 var type = assembly.GetType ("Tests3");
3124
3125                 Assert.IsNotNull (type);
3126
3127                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Public, false);
3128                 Assert.AreEqual (1, mm.Length, "#1");
3129                 Assert.AreEqual ("M1", mm[0].Name, "#2");
3130
3131                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.NonPublic, false);
3132                 Assert.AreEqual (1, mm.Length, "#3");
3133                 Assert.AreEqual ("M2", mm[0].Name, "#4");
3134
3135                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public, false);
3136                 Assert.AreEqual (7, mm.Length, "#5"); //M3 plus Equals, GetHashCode, GetType, ToString, .ctor
3137
3138                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, false);
3139                 Assert.AreEqual (2, mm.Length, "#7");
3140
3141                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
3142                 Assert.AreEqual (1, mm.Length, "#9");
3143
3144                 mm = type.GetMethodsByNameFlags (null, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly, false);
3145                 Assert.AreEqual (5, mm.Length, "#11");
3146
3147                 //Now with name
3148                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static | BindingFlags.Public, false);
3149                 Assert.AreEqual (1, mm.Length, "#12");
3150                 Assert.AreEqual ("M1", mm[0].Name, "#13");
3151
3152                 mm = type.GetMethodsByNameFlags ("m1", BindingFlags.Static | BindingFlags.Public, true);
3153                 Assert.AreEqual (1, mm.Length, "#14");
3154                 Assert.AreEqual ("M1", mm[0].Name, "#15");
3155
3156                 mm = type.GetMethodsByNameFlags ("M1", BindingFlags.Static  | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, false);
3157                 Assert.AreEqual (1, mm.Length, "#16");
3158                 Assert.AreEqual ("M1", mm[0].Name, "#17");
3159         }
3160
3161         [Test]
3162         [Category ("only88")]
3163         public void TypeLoadSourceFileFilter () {
3164                 Event e = run_until ("type_load");
3165
3166                 if (!vm.Version.AtLeast (2, 7))
3167                         return;
3168
3169                 string srcfile = (e as BreakpointEvent).Method.DeclaringType.GetSourceFiles (true)[0];
3170
3171                 var req = vm.CreateTypeLoadRequest ();
3172                 req.SourceFileFilter = new string [] { srcfile.ToUpper () };
3173                 req.Enable ();
3174
3175                 vm.Resume ();
3176                 e = GetNextEvent ();
3177                 Assert.IsTrue (e is TypeLoadEvent);
3178                 Assert.AreEqual ("TypeLoadClass", (e as TypeLoadEvent).Type.FullName);
3179         }
3180
3181         [Test]
3182         public void TypeLoadTypeNameFilter () {
3183                 Event e = run_until ("type_load");
3184
3185                 var req = vm.CreateTypeLoadRequest ();
3186                 req.TypeNameFilter = new string [] { "TypeLoadClass2" };
3187                 req.Enable ();
3188
3189                 vm.Resume ();
3190                 e = GetNextEvent ();
3191                 Assert.IsTrue (e is TypeLoadEvent);
3192                 Assert.AreEqual ("TypeLoadClass2", (e as TypeLoadEvent).Type.FullName);
3193         }
3194
3195         [Test]
3196         public void GetTypesForSourceFile () {
3197                 run_until ("user");
3198
3199                 var types = vm.GetTypesForSourceFile ("dtest-app.cs", false);
3200                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3201                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3202
3203                 types = vm.GetTypesForSourceFile ("DTEST-app.cs", true);
3204                 Assert.IsTrue (types.Any (t => t.FullName == "Tests"));
3205                 Assert.IsFalse (types.Any (t => t.FullName == "System.Int32"));
3206         }
3207
3208         [Test]
3209         public void GetTypesNamed () {
3210                 run_until ("user");
3211
3212                 var types = vm.GetTypes ("Tests", false);
3213                 Assert.AreEqual (1, types.Count);
3214                 Assert.AreEqual ("Tests", types [0].FullName);
3215
3216                 types = vm.GetTypes ("System.Exception", false);
3217                 Assert.AreEqual (1, types.Count);
3218                 Assert.AreEqual ("System.Exception", types [0].FullName);
3219         }
3220
3221         [Test]
3222         public void String_GetChars () {
3223                 object val;
3224
3225                 // Reuse this test
3226                 var e = run_until ("arg2");
3227
3228                 var frame = e.Thread.GetFrames () [0];
3229
3230                 val = frame.GetArgument (0);
3231                 Assert.IsTrue (val is StringMirror);
3232                 AssertValue ("FOO", val);
3233                 var s = (val as StringMirror);
3234                 Assert.AreEqual (3, s.Length);
3235
3236                 var c = s.GetChars (0, 2);
3237                 Assert.AreEqual (2, c.Length);
3238                 Assert.AreEqual ('F', c [0]);
3239                 Assert.AreEqual ('O', c [1]);
3240
3241                 AssertThrows<ArgumentException> (delegate () {          
3242                                 s.GetChars (2, 2);
3243                         });
3244         }
3245
3246         [Test]
3247         public void GetInterfaces () {
3248                 var e = run_until ("arg2");
3249
3250                 var frame = e.Thread.GetFrames () [0];
3251
3252                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3253                 var ifaces = cl1.GetInterfaces ();
3254                 Assert.AreEqual (1, ifaces.Length);
3255                 Assert.AreEqual ("ITest", ifaces [0].Name);
3256
3257                 var cl2 = cl1.GetMethod ("Baz").ReturnType;
3258                 var ifaces2 = cl2.GetInterfaces ();
3259                 Assert.AreEqual (1, ifaces2.Length);
3260                 Assert.AreEqual ("ITest`1", ifaces2 [0].Name);
3261         }
3262
3263         [Test]
3264         public void GetInterfaceMap () {
3265                 var e = run_until ("arg2");
3266
3267                 var frame = e.Thread.GetFrames () [0];
3268
3269                 var cl1 = frame.Method.DeclaringType.Assembly.GetType ("TestIfaces");
3270                 var iface = cl1.Assembly.GetType ("ITest");
3271                 var map = cl1.GetInterfaceMap (iface);
3272                 Assert.AreEqual (cl1, map.TargetType);
3273                 Assert.AreEqual (iface, map.InterfaceType);
3274                 Assert.AreEqual (2, map.InterfaceMethods.Length);
3275                 Assert.AreEqual (2, map.TargetMethods.Length);
3276         }
3277
3278         [Test]
3279         public void StackAlloc_Breakpoints_Regress2775 () {
3280                 // Check that breakpoints on arm don't overwrite stackalloc-ed memory
3281                 var e = run_until ("regress_2755");
3282
3283                 var frame = e.Thread.GetFrames () [0];
3284                 var m = e.Method;
3285                 // This breaks at the call site
3286                 vm.SetBreakpoint (m, m.Locations [2].ILOffset);
3287
3288                 vm.Resume ();
3289                 var e2 = GetNextEvent ();
3290                 Assert.IsTrue (e2 is BreakpointEvent);
3291
3292                 e = run_until ("regress_2755_3");
3293                 frame = e.Thread.GetFrames () [1];
3294                 var res = frame.GetValue (m.GetLocal ("sum"));
3295                 AssertValue (0, res);
3296         }
3297
3298         [Test]
3299         public void MethodInfo () {
3300                 Event e = run_until ("locals2");
3301
3302                 StackFrame frame = e.Thread.GetFrames () [0];
3303                 var m = frame.Method;
3304
3305                 Assert.IsTrue (m.IsGenericMethod);
3306                 Assert.IsFalse (m.IsGenericMethodDefinition);
3307
3308                 var args = m.GetGenericArguments ();
3309                 Assert.AreEqual (1, args.Length);
3310                 Assert.AreEqual ("String", args [0].Name);
3311
3312                 var gmd = m.GetGenericMethodDefinition ();
3313                 Assert.IsTrue (gmd.IsGenericMethod);
3314                 Assert.IsTrue (gmd.IsGenericMethodDefinition);
3315                 Assert.AreEqual (gmd, gmd.GetGenericMethodDefinition ());
3316
3317                 args = gmd.GetGenericArguments ();
3318                 Assert.AreEqual (1, args.Length);
3319                 Assert.AreEqual ("T", args [0].Name);
3320
3321                 var attrs = m.GetCustomAttributes (true);
3322                 Assert.AreEqual (1, attrs.Length);
3323                 Assert.AreEqual ("StateMachineAttribute", attrs [0].Constructor.DeclaringType.Name);
3324         }
3325
3326         [Test]
3327         public void UnhandledException () {
3328                 vm.Exit (0);
3329
3330                 Start (new string [] { "dtest-app.exe", "unhandled-exception" });
3331
3332                 var req = vm.CreateExceptionRequest (null, false, true);
3333                 req.Enable ();
3334
3335                 var e = run_until ("unhandled_exception");
3336                 vm.Resume ();
3337
3338                 var e2 = GetNextEvent ();
3339                 Assert.IsTrue (e2 is ExceptionEvent);
3340
3341                 vm.Exit (0);
3342                 vm = null;
3343         }
3344
3345         [Test]
3346         public void UnhandledException_2 () {
3347                 vm.Exit (0);
3348
3349                 Start (new string [] { "dtest-app.exe", "unhandled-exception-endinvoke" });
3350
3351                 var req = vm.CreateExceptionRequest (null, false, true);
3352                 req.Enable ();
3353
3354                 MethodMirror m = entry_point.DeclaringType.GetMethod ("unhandled_exception_endinvoke_2");
3355                 Assert.IsNotNull (m);
3356                 vm.SetBreakpoint (m, m.ILOffsets [0]);
3357
3358                 var e = run_until ("unhandled_exception_endinvoke");
3359                 vm.Resume ();
3360
3361                 var e2 = GetNextEvent ();
3362                 Assert.IsFalse (e2 is ExceptionEvent);
3363
3364                 vm.Exit (0);
3365                 vm = null;
3366         }
3367
3368 #if NET_4_5
3369         [Test]
3370         public void UnhandledExceptionUserCode () {
3371                 vm.Detach ();
3372
3373                 // Exceptions caught in non-user code are treated as unhandled
3374                 Start (new string [] { "dtest-app.exe", "unhandled-exception-user" });
3375
3376                 var req = vm.CreateExceptionRequest (null, false, true);
3377                 req.AssemblyFilter = new List<AssemblyMirror> () { entry_point.DeclaringType.Assembly };
3378                 req.Enable ();
3379
3380                 var e = run_until ("unhandled_exception_user");
3381                 vm.Resume ();
3382
3383                 var e2 = GetNextEvent ();
3384                 Assert.IsTrue (e2 is ExceptionEvent);
3385
3386                 vm.Exit (0);
3387                 vm = null;
3388         }
3389 #endif
3390
3391         [Test]
3392         public void GCWhileSuspended () {
3393                 // Check that objects are kept alive during suspensions
3394                 Event e = run_until ("gc_suspend_1");
3395
3396                 MethodMirror m = entry_point.DeclaringType.GetMethod ("gc_suspend_invoke");
3397
3398                 var o = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3399                 //Console.WriteLine (o);
3400
3401                 StackFrame frame = e.Thread.GetFrames () [0];
3402                 TypeMirror t = frame.Method.DeclaringType;
3403                 for (int i = 0; i < 10; ++i)
3404                         t.InvokeMethod (e.Thread, m, new Value [] { });
3405
3406                 // This throws an exception if the object is collected
3407                 long addr = o.Address;
3408
3409                 var o2 = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
3410                 Assert.IsNull (o2);
3411         }
3412
3413         [Test]
3414         public void MakeGenericMethod () {
3415                 Event e = run_until ("bp1");
3416
3417                 var intm = vm.RootDomain.GetCorrespondingType (typeof (int));
3418                 var stringm = vm.RootDomain.GetCorrespondingType (typeof (string));
3419                 var gm = entry_point.DeclaringType.GetMethod ("generic_method");
3420                 var res = gm.MakeGenericMethod (new TypeMirror [] { stringm });
3421                 var args = res.GetGenericArguments ();
3422                 Assert.AreEqual (1, args.Length);
3423                 Assert.AreEqual (stringm, args [0]);
3424
3425                 // Error checking
3426                 AssertThrows<ArgumentNullException> (delegate {
3427                                 gm.MakeGenericMethod (null);
3428                         });
3429                 AssertThrows<ArgumentNullException> (delegate {
3430                                 gm.MakeGenericMethod (new TypeMirror [] { null });
3431                         });
3432                 AssertThrows<ArgumentException> (delegate {
3433                                 gm.MakeGenericMethod (new TypeMirror [] { stringm, stringm });
3434                         });
3435                 AssertThrows<InvalidOperationException> (delegate {
3436                                 gm.MakeGenericMethod (new TypeMirror [] { intm });
3437                         });
3438                 AssertThrows<InvalidOperationException> (delegate {
3439                                 entry_point.DeclaringType.GetMethod ("Main").MakeGenericMethod (new TypeMirror [] { intm });
3440                         });
3441         }
3442
3443         [Test]
3444         public void InspectThreadSuspenedOnWaitOne () {
3445                 TearDown ();
3446                 Start (true, "dtest-app.exe", "wait-one" );
3447
3448                 ThreadMirror.NativeTransitions = true;
3449
3450                 var evt = run_until ("wait_one");
3451                 Assert.IsNotNull (evt, "#1");
3452
3453                 var thread = evt.Thread;
3454                 Assert.AreEqual (ThreadState.Running, thread.ThreadState, "#1.1");
3455
3456                 var frames = thread.GetFrames ();
3457                 Assert.IsNotNull (frames, "#2");
3458                 Assert.AreEqual (2, frames.Length, "#3");
3459                 Assert.AreEqual ("wait_one", frames [0].Method.Name, "#4");
3460                 Assert.AreEqual ("Main", frames [1].Method.Name, "#5");
3461
3462                 vm.Resume ();
3463
3464                 Thread.Sleep (500); //FIXME this is racy, maybe single step? or something?
3465
3466                 vm.Suspend ();
3467                 Assert.AreEqual (ThreadState.WaitSleepJoin, thread.ThreadState, "#6");
3468
3469                 frames = thread.GetFrames ();
3470                 Assert.AreEqual (4, frames.Length, "#7");
3471                 Assert.AreEqual ("WaitOne_internal", frames [0].Method.Name, "#8");
3472                 Assert.AreEqual ("WaitOne", frames [1].Method.Name, "#8.1");
3473                 Assert.AreEqual ("wait_one", frames [2].Method.Name, "#9");
3474                 Assert.AreEqual ("Main", frames [3].Method.Name, "#10");
3475
3476
3477                 var frame = frames [0];
3478                 Assert.IsTrue (frame.IsNativeTransition, "#11.1");
3479                 try {
3480                         frame.GetThis ();
3481                         Assert.Fail ("Known limitation - can't get info from m2n frames");
3482                 } catch (AbsentInformationException) {}
3483
3484                 frame = frames [1];
3485                 Assert.IsFalse (frame.IsNativeTransition, "#12.1");
3486                 var wait_one_this = frame.GetThis ();
3487                 Assert.IsNotNull (wait_one_this, "#12.2");
3488
3489                 frame = frames [2];
3490                 var locals = frame.GetVisibleVariables ();
3491                 Assert.AreEqual (1, locals.Count, "#13.1");
3492
3493                 var local_0 = frame.GetValue (locals [0]);
3494                 Assert.IsNotNull (local_0, "#13.2");
3495
3496                 Assert.AreEqual (wait_one_this, local_0, "#14.2");
3497         }
3498
3499         [Test]
3500         public void GetMethodBody () {
3501                 var bevent = run_until ("Main");
3502
3503                 var m = bevent.Method.DeclaringType.GetMethod ("get_IntProperty");
3504                 var body = m.GetMethodBody ();
3505                 foreach (var ins in body.Instructions) {
3506                         if (ins.OpCode == OpCodes.Ldfld) {
3507                                 var field = (FieldInfoMirror)ins.Operand;
3508                                 Assert.AreEqual ("field_i", field.Name);
3509                         }
3510                 }
3511         }
3512
3513         [Test]
3514         public void EvaluateMethod () {
3515                 var bevent = run_until ("evaluate_method_2");
3516
3517                 var m = bevent.Method.DeclaringType.GetMethod ("get_IntProperty");
3518
3519                 var this_obj = bevent.Thread.GetFrames ()[0].GetThis ();
3520                 var v = m.Evaluate (this_obj, null);
3521                 AssertValue (42, v);
3522         }
3523
3524         [Test]
3525         public void SetIP () {
3526                 var bevent = run_until ("set_ip_1");
3527
3528                 var invalid_loc = bevent.Thread.GetFrames ()[0].Location;
3529
3530                 var req = create_step (bevent);
3531                 var e = step_out ();
3532                 req.Disable ();
3533                 var frames = e.Thread.GetFrames ();
3534                 var locs = frames [0].Method.Locations;
3535                 var next_loc = locs.First (l => (l.LineNumber == frames [0].Location.LineNumber + 2));
3536
3537                 e.Thread.SetIP (next_loc);
3538
3539                 /* Check that i = 5; j = 5; was skipped */
3540                 bevent = run_until ("set_ip_2");
3541                 var f = bevent.Thread.GetFrames ()[1];
3542                 AssertValue (1, f.GetValue (f.Method.GetLocal ("i")));
3543                 AssertValue (0, f.GetValue (f.Method.GetLocal ("j")));
3544
3545                 // Error handling
3546                 AssertThrows<ArgumentNullException> (delegate {
3547                                 e.Thread.SetIP (null);
3548                         });
3549
3550                 AssertThrows<ArgumentException> (delegate {
3551                                 e.Thread.SetIP (invalid_loc);
3552                         });
3553         }
3554
3555         [Test]
3556         public void NewInstanceNoCtor () {
3557                 var bevent = run_until ("Main");
3558
3559                 var stype = bevent.Method.DeclaringType.Assembly.GetType ("AStruct");
3560                 var obj = stype.NewInstance ();
3561                 Assert.IsTrue (obj is ObjectMirror);
3562                 Assert.AreEqual ("AStruct", (obj as ObjectMirror).Type.Name);
3563         }
3564 }
3565
3566 }