diff options
author | Alexander Kyte <alkyte@microsoft.com> | 2018-09-24 23:55:37 +0300 |
---|---|---|
committer | Alexander Kyte <alkyte@microsoft.com> | 2018-10-01 21:23:48 +0300 |
commit | 52a9b776eae9908e2a1f797b335122157914bca4 (patch) | |
tree | 69e6637dfe9ef7c97aa22577587848124df388c4 | |
parent | 2e15fa255facafd35cf67da2234271035bb89347 (diff) |
[runtime] Fix off by one with stacktrace rethrow
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | mcs/class/referencesource/mscorlib/system/exception.cs | 2 | ||||
-rw-r--r-- | mono/metadata/marshal-ilgen.c | 5 | ||||
-rw-r--r-- | mono/metadata/object-internals.h | 1 | ||||
-rw-r--r-- | mono/mini/mini-exceptions.c | 10 | ||||
-rw-r--r-- | mono/mini/mini-runtime.c | 4 |
6 files changed, 21 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac index e861846b907..00032981c7f 100644 --- a/configure.ac +++ b/configure.ac @@ -46,7 +46,7 @@ MONO_VERSION_BUILD=`echo $VERSION | cut -d . -f 3` # There is no ordering of corlib versions, no old or new, # the runtime expects an exact match. # -MONO_CORLIB_VERSION=BEAF66F4-BA36-44C5-974E-83C6F627DF8C +MONO_CORLIB_VERSION=E06DCE2D-7852-4BBA-AD9F-54D67EEF1FF9 # # Put a quoted #define in config.h. diff --git a/mcs/class/referencesource/mscorlib/system/exception.cs b/mcs/class/referencesource/mscorlib/system/exception.cs index ba3e49e67b2..ac0d1fc6ba1 100644 --- a/mcs/class/referencesource/mscorlib/system/exception.cs +++ b/mcs/class/referencesource/mscorlib/system/exception.cs @@ -978,6 +978,8 @@ namespace System { // Mono addition: Used on iPhone IntPtr[] native_trace_ips; + + int caught_in_unmanaged; #endif // See clr\src\vm\excep.h's EXCEPTION_COMPLUS definition: diff --git a/mono/metadata/marshal-ilgen.c b/mono/metadata/marshal-ilgen.c index 02687517584..7f475e26fd0 100644 --- a/mono/metadata/marshal-ilgen.c +++ b/mono/metadata/marshal-ilgen.c @@ -1173,6 +1173,11 @@ emit_thread_interrupt_checkpoint_call (MonoMethodBuilder *mb, gpointer checkpoin mono_mb_emit_byte (mb, CEE_DUP); pos_noex = mono_mb_emit_branch (mb, CEE_BRFALSE); + mono_mb_emit_byte (mb, CEE_DUP); + mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoException, caught_in_unmanaged)); + mono_mb_emit_byte (mb, CEE_LDC_I4_1); + mono_mb_emit_byte (mb, CEE_STIND_I4); + mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX); mono_mb_emit_byte (mb, CEE_MONO_RETHROW); diff --git a/mono/metadata/object-internals.h b/mono/metadata/object-internals.h index c260a123eaf..13c7cf1d832 100644 --- a/mono/metadata/object-internals.h +++ b/mono/metadata/object-internals.h @@ -268,6 +268,7 @@ struct _MonoException { MonoObject *serialization_manager; MonoObject *captured_traces; MonoArray *native_trace_ips; + gint32 caught_in_unmanaged; }; typedef struct { diff --git a/mono/mini/mini-exceptions.c b/mono/mini/mini-exceptions.c index f32b69b3d96..da8044c62d5 100644 --- a/mono/mini/mini-exceptions.c +++ b/mono/mini/mini-exceptions.c @@ -1923,7 +1923,11 @@ handle_exception_first_pass (MonoContext *ctx, MonoObject *obj, gint32 *out_filt if (initial_trace_ips) { int len = mono_array_length (initial_trace_ips) / TRACE_IP_ENTRY_SIZE; - for (i = 0; i < (len - 1); i++) { + // If we catch in managed/non-wrapper, we don't save the catching frame + if (!mono_ex->caught_in_unmanaged) + len -= 1; + + for (i = 0; i < len; i++) { for (int j = 0; j < TRACE_IP_ENTRY_SIZE; ++j) { gpointer p = mono_array_get (initial_trace_ips, gpointer, (i * TRACE_IP_ENTRY_SIZE) + j); trace_ips = g_list_prepend (trace_ips, p); @@ -1931,6 +1935,10 @@ handle_exception_first_pass (MonoContext *ctx, MonoObject *obj, gint32 *out_filt } } + // Reset the state because we're making it be caught somewhere + if (mono_ex->caught_in_unmanaged) + MONO_OBJECT_SETREF (mono_ex, caught_in_unmanaged, 0); + if (!mono_object_isinst_checked (obj, mono_defaults.exception_class, error)) { mono_error_assert_ok (error); mono_ex = NULL; diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index f3f0f4b93fb..0d5f471cdc8 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -3135,8 +3135,10 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec result = runtime_invoke ((MonoObject *)obj, params, exc, info->compiled_method); } - if (catchExcInMonoError && *exc != NULL) + if (catchExcInMonoError && *exc != NULL) { + ((MonoException *)(*exc))->caught_in_unmanaged = TRUE; mono_error_set_exception_instance (error, (MonoException*) *exc); + } return result; } |