From: Thays Grazia Date: Wed, 23 Oct 2019 20:56:58 +0000 (-0300) Subject: [debugger] Changing how debugger handles exception when hybrid suspend is enabled... X-Git-Tag: submit/tizen/20210909.063632~10331^2~5^2~299 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ace84342024f4729b33a8c2517b75b3fd83d1048;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [debugger] Changing how debugger handles exception when hybrid suspend is enabled (mono/mono#17478) * Removing all fixes to fix mono/mono#15203 and mono/mono#17083, and trying a new approach to fix this mono/mono#17084, together. The thing is when we are executing on hybrid suspend the caller is executed inside try catch in the runtime_invoke_ method that is generated. And this try catch should be ignored for the debugger exception, otherwise it's the last try catch in main thread, but should always be considered to generate the stack trace. Fixes mono/mono#17084 * This test check the case that we were missing. On preemptive this test always runs perfectly, on Hybrid, never run well until this PR. * Changing how call unit test. Changing variable name. Commit migrated from https://github.com/mono/mono/commit/8fda1738f728dec900e7a53b78fefdbbbc9e0924 --- diff --git a/src/mono/mono/mini/exceptions-amd64.c b/src/mono/mono/mini/exceptions-amd64.c index c301b90..d5ff063 100644 --- a/src/mono/mono/mini/exceptions-amd64.c +++ b/src/mono/mono/mini/exceptions-amd64.c @@ -394,7 +394,7 @@ mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guin if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) { MonoException *mono_ex = (MonoException*)exc; - if (!rethrow) { + if (!rethrow && !mono_ex->caught_in_unmanaged) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } else if (preserve_ips) { diff --git a/src/mono/mono/mini/exceptions-arm.c b/src/mono/mono/mini/exceptions-arm.c index 75af2d9..7edb22d 100644 --- a/src/mono/mono/mini/exceptions-arm.c +++ b/src/mono/mono/mini/exceptions-arm.c @@ -168,7 +168,7 @@ mono_arm_throw_exception (MonoObject *exc, host_mgreg_t pc, host_mgreg_t sp, hos if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) { MonoException *mono_ex = (MonoException*)exc; - if (!rethrow) { + if (!rethrow && !mono_ex->caught_in_unmanaged) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } else if (preserve_ips) { diff --git a/src/mono/mono/mini/exceptions-arm64.c b/src/mono/mono/mini/exceptions-arm64.c index 0c1778a..3cc5dc7 100644 --- a/src/mono/mono/mini/exceptions-arm64.c +++ b/src/mono/mono/mini/exceptions-arm64.c @@ -386,7 +386,7 @@ mono_arm_throw_exception (gpointer arg, host_mgreg_t pc, host_mgreg_t *int_regs, if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) { MonoException *mono_ex = (MonoException*)exc; - if (!rethrow) { + if (!rethrow && !mono_ex->caught_in_unmanaged) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } else if (preserve_ips) { diff --git a/src/mono/mono/mini/exceptions-mips.c b/src/mono/mono/mini/exceptions-mips.c index d0a325d..6d635d3 100644 --- a/src/mono/mono/mini/exceptions-mips.c +++ b/src/mono/mono/mini/exceptions-mips.c @@ -200,7 +200,7 @@ throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, gboolean if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) { MonoException *mono_ex = (MonoException*)exc; - if (!rethrow) { + if (!rethrow && !mono_ex->caught_in_unmanaged) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } if (preserve_ips) { diff --git a/src/mono/mono/mini/exceptions-ppc.c b/src/mono/mono/mini/exceptions-ppc.c index acdf700..fc55044 100644 --- a/src/mono/mono/mini/exceptions-ppc.c +++ b/src/mono/mono/mini/exceptions-ppc.c @@ -340,7 +340,7 @@ mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) { MonoException *mono_ex = (MonoException*)exc; - if (!rethrow) { + if (!rethrow && !mono_ex->caught_in_unmanaged) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } else if (preserve_ips) { diff --git a/src/mono/mono/mini/exceptions-s390x.c b/src/mono/mono/mini/exceptions-s390x.c index 4dc41f2..fe5ca32 100644 --- a/src/mono/mono/mini/exceptions-s390x.c +++ b/src/mono/mono/mini/exceptions-s390x.c @@ -268,7 +268,7 @@ throw_exception (MonoObject *exc, unsigned long ip, unsigned long sp, if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) { MonoException *mono_ex = (MonoException*)exc; - if (!rethrow) { + if (!rethrow && !mono_ex->caught_in_unmanaged) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } else if (preserve_ips) { diff --git a/src/mono/mono/mini/exceptions-sparc.c b/src/mono/mono/mini/exceptions-sparc.c index c84d0fc..bb84090 100644 --- a/src/mono/mono/mini/exceptions-sparc.c +++ b/src/mono/mono/mini/exceptions-sparc.c @@ -184,7 +184,7 @@ throw_exception (MonoObject *exc, gpointer sp, gpointer ip, gboolean rethrow, gb if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) { MonoException *mono_ex = (MonoException*)exc; - if (!rethrow) { + if (!rethrow && !mono_ex->caught_in_unmanaged) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } else (preserve_ips) { diff --git a/src/mono/mono/mini/exceptions-x86.c b/src/mono/mono/mini/exceptions-x86.c index f43c1d0..ac84f63 100644 --- a/src/mono/mono/mini/exceptions-x86.c +++ b/src/mono/mono/mini/exceptions-x86.c @@ -477,7 +477,7 @@ mono_x86_throw_exception (host_mgreg_t *regs, MonoObject *exc, if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) { MonoException *mono_ex = (MonoException*)exc; - if (!rethrow) { + if (!rethrow && !mono_ex->caught_in_unmanaged) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; } else if (preserve_ips) { diff --git a/src/mono/mono/mini/mini-exceptions.c b/src/mono/mono/mini/mini-exceptions.c index 1854a3c..5d99310 100644 --- a/src/mono/mono/mini/mini-exceptions.c +++ b/src/mono/mono/mini/mini-exceptions.c @@ -2218,7 +2218,7 @@ typedef enum { * return \c MONO_FIRST_PASS_CALLBACK_TO_NATIVE). */ static MonoFirstPassResult -handle_exception_first_pass (MonoContext *ctx, MonoObject *obj, gint32 *out_filter_idx, MonoJitInfo **out_ji, MonoJitInfo **out_prev_ji, MonoObject *non_exception, StackFrameInfo *catch_frame, gboolean *has_perform_wait_callback_method) +handle_exception_first_pass (MonoContext *ctx, MonoObject *obj, gint32 *out_filter_idx, MonoJitInfo **out_ji, MonoJitInfo **out_prev_ji, MonoObject *non_exception, StackFrameInfo *catch_frame, gboolean *last_mono_wrapper_runtime_invoke) { ERROR_DECL (error); MonoDomain *domain = mono_domain_get (); @@ -2242,7 +2242,7 @@ handle_exception_first_pass (MonoContext *ctx, MonoObject *obj, gint32 *out_filt MonoFirstPassResult result = MONO_FIRST_PASS_UNHANDLED; g_assert (ctx != NULL); - + *last_mono_wrapper_runtime_invoke = TRUE; if (obj == (MonoObject *)domain->stack_overflow_ex) stack_overflow = TRUE; @@ -2475,8 +2475,8 @@ handle_exception_first_pass (MonoContext *ctx, MonoObject *obj, gint32 *out_filt //try to find threadpool_perform_wait_callback_method unwind_res = unwinder_unwind_frame (&unwinder, domain, jit_tls, NULL, &new_ctx, &new_ctx, NULL, &lmf, NULL, &frame); while (unwind_res) { - if (frame.ji && !frame.ji->is_trampoline && jinfo_get_method (frame.ji) == mono_defaults.threadpool_perform_wait_callback_method) { - *has_perform_wait_callback_method = TRUE; + if (frame.ji && !frame.ji->is_trampoline && jinfo_get_method (frame.ji)->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE) { + *last_mono_wrapper_runtime_invoke = FALSE; break; } unwind_res = unwinder_unwind_frame (&unwinder, domain, jit_tls, NULL, &new_ctx, &new_ctx, NULL, &lmf, NULL, &frame); @@ -2555,6 +2555,8 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu MonoObject *non_exception = NULL; Unwinder unwinder; gboolean in_interp; + gboolean is_caught_unmanaged = FALSE; + gboolean last_mono_wrapper_runtime_invoke = TRUE; g_assert (ctx != NULL); if (!obj) { @@ -2594,6 +2596,10 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu ; } + if (mono_ex->caught_in_unmanaged) + is_caught_unmanaged = TRUE; + + if (mono_object_isinst_checked (obj, mono_defaults.exception_class, error)) { mono_ex = (MonoException*)obj; } else { @@ -2686,8 +2692,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu StackFrameInfo catch_frame; MonoFirstPassResult res; - gboolean has_perform_wait_callback_method = FALSE; - res = handle_exception_first_pass (&ctx_cp, obj, &first_filter_idx, &ji, &prev_ji, non_exception, &catch_frame, &has_perform_wait_callback_method); + res = handle_exception_first_pass (&ctx_cp, obj, &first_filter_idx, &ji, &prev_ji, non_exception, &catch_frame, &last_mono_wrapper_runtime_invoke); if (res == MONO_FIRST_PASS_UNHANDLED) { if (mono_aot_mode == MONO_AOT_MODE_LLVMONLY_INTERP) { @@ -2727,12 +2732,14 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu if (unhandled) mini_get_dbg_callbacks ()->handle_exception ((MonoException *)obj, ctx, NULL, NULL); else if (!ji || (jinfo_get_method (ji)->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE)) { - if (!has_perform_wait_callback_method) + if (last_mono_wrapper_runtime_invoke && mono_thread_get_main () && (mono_thread_internal_current () == mono_thread_get_main ()->internal_thread)) mini_get_dbg_callbacks ()->handle_exception ((MonoException *)obj, ctx, NULL, NULL); - mini_get_dbg_callbacks ()->handle_exception ((MonoException *)obj, ctx, &ctx_cp, &catch_frame); + else + mini_get_dbg_callbacks ()->handle_exception ((MonoException *)obj, ctx, &ctx_cp, &catch_frame); } else if (res != MONO_FIRST_PASS_CALLBACK_TO_NATIVE) - mini_get_dbg_callbacks ()->handle_exception ((MonoException *)obj, ctx, &ctx_cp, &catch_frame); + if (!is_caught_unmanaged) + mini_get_dbg_callbacks ()->handle_exception ((MonoException *)obj, ctx, &ctx_cp, &catch_frame); } }