[runtime] Synthesize IList and IReadOnlyList for the element type of enum errays...
[mono.git] / mono / tests / finalizer-exception.cs
index ef0b4f6e13ab59afe350cfa48c38c77763bd92c2..71f4b4cc20933647e7fcc1df7d36407ec6261ae7 100644 (file)
@@ -1,38 +1,45 @@
-
-using System; 
-using System.Collections; 
+using System;
 using System.Threading;
 
-public class foo  { 
-       public static LocalDataStoreSlot dataslot = Thread.AllocateDataSlot();
-       public static int final_count=0;
+public class FinalizerException {
 
-       ~foo() { 
-               // Demonstrate that this is still the same thread
-               string ID=(string)Thread.GetData(dataslot);
-               if(ID==null) {
-                       Console.WriteLine("Set ID: foo");
-                       Thread.SetData(dataslot, "foo");
-               }
+       ~FinalizerException () {
+               throw new Exception ();
+       }
 
-               // Don't run forever
-               if(final_count++>10) {
-                       Environment.Exit(0);
-               }
+       static IntPtr aptr;
 
-               Console.WriteLine("finalizer thread ID: {0}", (string)Thread.GetData(dataslot));
-               throw new SystemException("wibble");
-       } 
-
-       public static int Main() { 
-               ArrayList list = new ArrayList (); 
-               Thread.SetData(dataslot, "ID is wibble");
-               Environment.ExitCode = 2;
-               while(true) { 
-                       foo instance = new foo(); 
-                       list.Add (new WeakReference(instance)); 
+       /*
+        * We allocate the exception object deep down the stack so
+        * that it doesn't get pinned.
+        */
+       public static unsafe void MakeException (int depth) {
+               // Avoid tail calls
+               int* values = stackalloc int [20];
+               aptr = new IntPtr (values);
+               if (depth <= 0) {
+                       for (int i = 0; i < 10; i++)
+                               new FinalizerException ();
+                       return;
                }
-               return 1;
-       } 
-} 
+               MakeException (depth - 1);
+       }
+
+       public static int Main () { 
+               AppDomain.CurrentDomain.UnhandledException += (sender, args) => {
+                       Console.WriteLine ("caught");
+                       Environment.Exit (0);
+               };
+
+               var t = new Thread (delegate () { MakeException (1024); });
+               t.Start ();
+               t.Join ();
+
+               GC.Collect ();
+               GC.WaitForPendingFinalizers ();
+
+               Thread.Sleep (Timeout.Infinite); // infinite wait so we don't race against the unhandled exception callback
 
+               return 2;
+       }
+}