[interp] Retain trace during exception checkpoint (#56825)
authorVlad Brezae <brezaevlad@gmail.com>
Wed, 4 Aug 2021 15:29:22 +0000 (18:29 +0300)
committerGitHub <noreply@github.com>
Wed, 4 Aug 2021 15:29:22 +0000 (10:29 -0500)
When an exception needs to cross a native boundary, it can be caught by the runtime invoke wrapper and this exception will end up as a pending exception. With JIT, the initial managed to native wrapper will check for a pending exception and will use a CEE_MONO_RETHROW opcode in order to preserve the stacktrace. With the interp we do the exception checkpoint outside of the native wrapper, and we need to do it in rethrow fashion (without clearing the original trace).

src/mono/mono/mini/interp/interp.c

index d43b388..8005a99 100644 (file)
@@ -1024,7 +1024,7 @@ interp_throw (ThreadContext *context, MonoException *ex, InterpFrame *frame, con
                if (mono_thread_interruption_request_flag && !mono_threads_is_critical_method (frame->imethod->method)) { \
                        MonoException *exc = mono_thread_interruption_checkpoint ();    \
                        if (exc)                                                        \
-                               THROW_EX (exc, ip);                                     \
+                               THROW_EX_GENERAL (exc, ip, TRUE);                                       \
                }                                                                       \
        } while (0)
 
@@ -1034,7 +1034,7 @@ interp_throw (ThreadContext *context, MonoException *ex, InterpFrame *frame, con
                if (mono_thread_interruption_request_flag && !mono_threads_is_critical_method (frame->imethod->method) && mono_thread_is_gc_unsafe_mode ()) { \
                        MonoException *exc = mono_thread_interruption_checkpoint ();    \
                        if (exc)                                                        \
-                               THROW_EX (exc, ip);                                     \
+                               THROW_EX_GENERAL (exc, ip, TRUE);                                       \
                }                                                                       \
        } while (0)