Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions src/mono/mono/mini/mini-wasm-debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ G_END_DECLS
static void describe_object_properties_for_klass (void *obj, MonoClass *klass, gboolean isAsyncLocalThis, int gpflags);
static void handle_exception (MonoException *exc, MonoContext *throw_ctx, MonoContext *catch_ctx, StackFrameInfo *catch_frame);
static void assembly_loaded (MonoProfiler *prof, MonoAssembly *assembly);
static MonoObject* mono_runtime_try_invoke_internal (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError* error);

//FIXME move all of those fields to the profiler object
static gboolean debugger_enabled;
Expand All @@ -83,6 +84,7 @@ static GHashTable *objrefs;
static GHashTable *obj_to_objref;
static int objref_id = 0;
static int pause_on_exc = EXCEPTION_MODE_NONE;
static MonoObject* exception_on_runtime_invoke = NULL;

static const char*
all_getters_allowed_class_names[] = {
Expand Down Expand Up @@ -314,7 +316,7 @@ get_this_async_id (DbgEngineStackFrame *frame)
return 0;
}

obj = mono_runtime_try_invoke (method, builder, NULL, &ex, error);
obj = mono_runtime_try_invoke_internal (method, builder, NULL, &ex, error);
mono_error_assert_ok (error);

return get_object_id (obj);
Expand Down Expand Up @@ -552,6 +554,9 @@ handle_exception (MonoException *exc, MonoContext *throw_ctx, MonoContext *catch
{
ERROR_DECL (error);
PRINT_DEBUG_MSG (1, "handle exception - %d - %p - %p - %p\n", pause_on_exc, exc, throw_ctx, catch_ctx);

//normal mono_runtime_try_invoke does not capture the exception and this is a temporary workaround.
exception_on_runtime_invoke = (MonoObject*)exc;

if (pause_on_exc == EXCEPTION_MODE_NONE)
return;
Expand Down Expand Up @@ -807,7 +812,7 @@ invoke_to_string (const char *class_name, MonoClass *klass, gpointer addr)
if (!method)
return NULL;

MonoString *mstr = (MonoString*) mono_runtime_try_invoke (method, addr , NULL, &exc, error);
MonoString *mstr = (MonoString*) mono_runtime_try_invoke_internal (method, addr , NULL, &exc, error);
if (exc || !is_ok (error)) {
PRINT_DEBUG_MSG (1, "Failed to invoke ToString for %s\n", class_name);
return NULL;
Expand Down Expand Up @@ -1190,17 +1195,36 @@ invoke_and_describe_getter_value (MonoObject *obj, MonoProperty *p)

MonoMethodSignature *sig = mono_method_signature_internal (p->get);

res = mono_runtime_try_invoke (p->get, obj, NULL, &exc, error);
res = mono_runtime_try_invoke_internal (p->get, obj, NULL, &exc, error);
if (!is_ok (error) && exc == NULL)
exc = (MonoObject*) mono_error_convert_to_exception (error);
exc = (MonoObject *) mono_error_convert_to_exception (error);
if (exc)
return describe_value (mono_get_object_type (), &exc, GPFLAG_EXPAND_VALUETYPES);
{
const char *class_name = mono_class_full_name (mono_object_class (exc));
ERROR_DECL (local_error);
char *str = mono_string_to_utf8_checked_internal (((MonoException*)exc)->message, local_error);
mono_error_assert_ok (local_error); /* FIXME report error */
char *msg = g_strdup_printf("%s: %s", class_name, str);
mono_wasm_add_typed_value ("string", msg, 0);
g_free (msg);
return TRUE;
}
else if (!res || !m_class_is_valuetype (mono_object_class (res)))
return describe_value (sig->ret, &res, GPFLAG_EXPAND_VALUETYPES);
else
return describe_value (sig->ret, mono_object_unbox_internal (res), GPFLAG_EXPAND_VALUETYPES);
}

static MonoObject* mono_runtime_try_invoke_internal (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError* error)
{
exception_on_runtime_invoke = NULL;
MonoObject* res = mono_runtime_try_invoke (method, obj, params, exc, error);
if (exception_on_runtime_invoke != NULL)
*exc = exception_on_runtime_invoke;
exception_on_runtime_invoke = NULL;
return res;
}

static void
describe_object_properties_for_klass (void *obj, MonoClass *klass, gboolean isAsyncLocalThis, int gpflags)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,17 @@ await EvaluateOnCallFrameFail(id,
("this.NullIfAIsNotZero.foo", "ReferenceError"));
});

[Fact]
public async Task EvaluatePropertyThatThrows()
=> await CheckInspectLocalsAtBreakpointSite(
"DebuggerTests.EvaluateTestsClassWithProperties", "InstanceMethod", /*line_offset*/1, "InstanceMethod",
$"window.setTimeout(function() {{ invoke_static_method_async('[debugger-test] DebuggerTests.EvaluateTestsClassWithProperties:run');}}, 1);",
wait_for_event_fn: async (pause_location) =>
{
var id = pause_location["callFrames"][0]["callFrameId"].Value<string>();
await EvaluateOnCallFrameAndCheck(id, ("this.PropertyThrowException", TString("System.Exception: error")));
});

async Task EvaluateOnCallFrameAndCheck(string call_frame_id, params (string expression, JObject expected)[] args)
{
foreach (var arg in args)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public class EvaluateTestsClassWithProperties
public DateTime dateTime;
public DateTime DTProp => dateTime.AddMinutes(10);
public int IntProp => a + 5;
public string PropertyThrowException => throw new Exception("error");
public string SetOnlyProp { set { a = value.Length; } }
public EvaluateTestsClassWithProperties NullIfAIsNotZero => a != 1908712 ? null : new EvaluateTestsClassWithProperties(0);
public EvaluateTestsClassWithProperties NewInstance => new EvaluateTestsClassWithProperties(3);
Expand Down