From 779a566ee08249de7fa1a3a0e283cb222c4e8dc7 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Mon, 7 Oct 2019 08:22:06 -0400 Subject: [PATCH] [debugger][exception] Debugger breaks on handled exceptions (mono/mono#17106) * If there is a perform_wait_callback in the stack there will be another catch generated by the owner thread, so we don't need to throw, we can continue and find the next catch. Fixes mono/mono#17083 * Reverting unit test changed on commit 405d521. * Fixing assert when calling mono_jit_info_get_method if it was a trampoline. Commit migrated from https://github.com/mono/mono/commit/18fac0a24190cb3f90057d86232e773758bb1284 --- src/mono/mono/mini/mini-exceptions.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/mini/mini-exceptions.c b/src/mono/mono/mini/mini-exceptions.c index 6c4c768..b12322f 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) +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) { ERROR_DECL (error); MonoDomain *domain = mono_domain_get (); @@ -2471,6 +2471,17 @@ handle_exception_first_pass (MonoContext *ctx, MonoObject *obj, gint32 *out_filt frame.native_offset = (char*)ei->handler_start - (char*)ji->code_start; *catch_frame = frame; result = MONO_FIRST_PASS_HANDLED; + if (method->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE) { + //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; + break; + } + unwind_res = unwinder_unwind_frame (&unwinder, domain, jit_tls, NULL, &new_ctx, &new_ctx, NULL, &lmf, NULL, &frame); + } + } return result; } mono_error_cleanup (isinst_error); @@ -2675,7 +2686,8 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu StackFrameInfo catch_frame; MonoFirstPassResult res; - res = handle_exception_first_pass (&ctx_cp, obj, &first_filter_idx, &ji, &prev_ji, non_exception, &catch_frame); + 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); if (res == MONO_FIRST_PASS_UNHANDLED) { if (mono_aot_mode == MONO_AOT_MODE_LLVMONLY_INTERP) { @@ -2715,7 +2727,8 @@ 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)) { - mini_get_dbg_callbacks ()->handle_exception ((MonoException *)obj, ctx, NULL, NULL); + if (!has_perform_wait_callback_method) + 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 if (res != MONO_FIRST_PASS_CALLBACK_TO_NATIVE) -- 2.7.4