Merge pull request #1668 from alexanderkyte/bug1856
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 12 May 2015 21:11:18 +0000 (17:11 -0400)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 12 May 2015 21:11:18 +0000 (17:11 -0400)
[runtime] Overwrite stacktrace for exception on re-throw. Fixes #1856.

mono/mini/exceptions-amd64.c
mono/mini/exceptions-arm.c
mono/mini/exceptions-ia64.c
mono/mini/exceptions-mips.c
mono/mini/exceptions-ppc.c
mono/mini/exceptions-s390x.c
mono/mini/exceptions-sparc.c
mono/mini/exceptions-x86.c
mono/tests/Makefile.am
mono/tests/exception18.cs [new file with mode: 0644]

index 502015268f6e3d654b88257a8f7db67b585a6a56..72342361fdc87d69d95007e294f5ac0953335534 100644 (file)
@@ -332,8 +332,10 @@ mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guin
 
        if (mono_object_isinst (exc, mono_defaults.exception_class)) {
                MonoException *mono_ex = (MonoException*)exc;
-               if (!rethrow)
+               if (!rethrow) {
                        mono_ex->stack_trace = NULL;
+                       mono_ex->trace_ips = NULL;
+               }
        }
 
        /* adjust eip so that it point into the call instruction */
index 1ca59fcba4433bce6b7308eab66acbc72851e24d..7f57eea44ecc7b2d2e469e996297d4aa32e9f87f 100644 (file)
@@ -154,8 +154,10 @@ mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_
 
        if (mono_object_isinst (exc, mono_defaults.exception_class)) {
                MonoException *mono_ex = (MonoException*)exc;
-               if (!rethrow)
+               if (!rethrow) {
                        mono_ex->stack_trace = NULL;
+                       mono_ex->trace_ips = NULL;
+               }
        }
        mono_handle_exception (&ctx, exc);
        mono_restore_context (&ctx);
index b8212c684bd3d47b5c3d5b32ca361319def675ad..b8e1929e8cb951cb6b35672edc1729e9eeb8b224 100644 (file)
@@ -243,8 +243,10 @@ throw_exception (MonoObject *exc, guint64 rethrow)
 
        if (mono_object_isinst (exc, mono_defaults.exception_class)) {
                MonoException *mono_ex = (MonoException*)exc;
-               if (!rethrow)
+               if (!rethrow) {
                        mono_ex->stack_trace = NULL;
+                       mono_ex->trace_ips = NULL;
+               }
        }
 
        res = unw_getcontext (&unw_ctx);
index f0158e5b7a9f2657d1665227a8930b52d8a133c6..dfb4a57d3b9a3ff5418b7cb005b8f283ffbbd387 100644 (file)
@@ -196,8 +196,10 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean
 
        if (mono_object_isinst (exc, mono_defaults.exception_class)) {
                MonoException *mono_ex = (MonoException*)exc;
-               if (!rethrow)
+               if (!rethrow) {
                        mono_ex->stack_trace = NULL;
+                       mono_ex->trace_ips = NULL;
+               }
        }
        mono_handle_exception (&ctx, exc);
 #ifdef DEBUG_EXCEPTIONS
index 4b8d1642c166986decc197df563fe673ba0bcb1d..b7c2e8d3a174503e4831a989da37122d80c1c79d 100644 (file)
@@ -333,8 +333,10 @@ mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp,
 
        if (mono_object_isinst (exc, mono_defaults.exception_class)) {
                MonoException *mono_ex = (MonoException*)exc;
-               if (!rethrow)
+               if (!rethrow) {
                        mono_ex->stack_trace = NULL;
+                       mono_ex->trace_ips = NULL;
+               }
        }
        mono_handle_exception (&ctx, exc);
        mono_restore_context (&ctx);
index 78fd645c7859aebac069ccb3616e3ab256880b55..ac1d0f2c921c6c8003529246f76a8a271ba77795 100644 (file)
@@ -259,8 +259,10 @@ throw_exception (MonoObject *exc, unsigned long ip, unsigned long sp,
        
        if (mono_object_isinst (exc, mono_defaults.exception_class)) {
                MonoException *mono_ex = (MonoException*)exc;
-               if (!rethrow)
+               if (!rethrow) {
                        mono_ex->stack_trace = NULL;
+                       mono_ex->trace_ips = NULL;
+               }
        }
 //     mono_arch_handle_exception (&ctx, exc, FALSE);
        mono_handle_exception (&ctx, exc);
index 3ebe2e7a29c422b5bc72c2a65e1002cd8a1ad235..52a93ac1f13f925b20c3bb1961fe255c2e8071b3 100644 (file)
@@ -180,8 +180,10 @@ throw_exception (MonoObject *exc, gpointer sp, gpointer ip, gboolean rethrow)
 
        if (mono_object_isinst (exc, mono_defaults.exception_class)) {
                MonoException *mono_ex = (MonoException*)exc;
-               if (!rethrow)
+               if (!rethrow) {
                        mono_ex->stack_trace = NULL;
+                       mono_ex->trace_ips = NULL;
+               }
        }
        mono_handle_exception (&ctx, exc);
        restore_context (&ctx);
index 2e862f43f18921ead6b4073c8506c73c04e71689..d7d4f72d299091b426195e49712a4002b98c0eda 100644 (file)
@@ -472,8 +472,10 @@ mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc,
 
        if (mono_object_isinst (exc, mono_defaults.exception_class)) {
                MonoException *mono_ex = (MonoException*)exc;
-               if (!rethrow)
+               if (!rethrow) {
                        mono_ex->stack_trace = NULL;
+                       mono_ex->trace_ips = NULL;
+               }
        }
 
        /* adjust eip so that it point into the call instruction */
index 82177d65d015ea5ffb08471bf05c1f876d0051c7..7d2e1acde3927d18df8577cd5817208a22cd9e02 100644 (file)
@@ -90,6 +90,7 @@ BASE_TEST_CS_SRC=             \
        exception15.cs          \
        exception16.cs          \
        exception17.cs          \
+       exception18.cs          \
        typeload-unaligned.cs   \
        struct.cs               \
        valuetype-gettype.cs    \
diff --git a/mono/tests/exception18.cs b/mono/tests/exception18.cs
new file mode 100644 (file)
index 0000000..8f1e492
--- /dev/null
@@ -0,0 +1,48 @@
+using System;
+
+class C
+{
+       static Exception e;
+
+       static void Throw ()
+       {
+               try {
+                       int.Parse (null);
+               } catch (Exception ex) {
+                       e = ex;
+               }
+       }
+
+       static int FrameCount (Exception ex)
+       {
+                       string fullTrace = ex.StackTrace;
+                       string[] frames = fullTrace.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
+                       return frames.Length;
+       }
+
+       public static void Main ()
+       {
+               Throw ();
+
+               try {
+                       throw e;
+               } catch (Exception ex) {
+                       int frames = FrameCount (ex);
+                       if (frames != 1)
+                               throw new Exception (String.Format("Exception carried {0} frames along with it when it should have reported one.", frames));
+               }
+
+               try {
+                       try {
+                               int.Parse (null);
+                       } catch (Exception) {
+                               throw;
+                       }
+               } catch (Exception ex) {
+                       int frames = FrameCount (ex);
+                       if (frames != 4)
+                               throw new Exception (String.Format("Exception carried {0} frames along with it when it should have reported four.", frames));
+               }
+
+       }
+}