From: monojenkins Date: Mon, 24 Feb 2020 21:17:30 +0000 (-0500) Subject: [wasm][debugger] Improve accessing locals (#32701) X-Git-Tag: submit/tizen/20210909.063632~9529 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bc4fd91f9c894e927682e3c23ae3e050e4012d66;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [wasm][debugger] Improve accessing locals (#32701) This fixes various issues in accessing locals on the stack. Co-authored-by: Ankit Jain --- diff --git a/src/mono/mono/mini/mini-wasm-debugger.c b/src/mono/mono/mini/mini-wasm-debugger.c index 32dedb8..43dc402 100644 --- a/src/mono/mono/mini/mini-wasm-debugger.c +++ b/src/mono/mono/mini/mini-wasm-debugger.c @@ -595,7 +595,8 @@ mono_wasm_enum_frames (void) typedef struct { int cur_frame; int target_frame; - int variable; + int len; + int *pos; } FrameDescData; static gboolean describe_value(MonoType * type, gpointer addr) @@ -766,100 +767,41 @@ describe_array_values (guint64 objectId) return TRUE; } -static gboolean -describe_async_method_locals (MonoStackFrameInfo *info, MonoContext *ctx, gpointer ud) +static void +describe_async_method_locals (InterpFrame *frame, MonoMethod *method) { //Async methods are special in the way that local variables can be lifted to generated class fields - FrameDescData *data = (FrameDescData*)ud; - - //skip wrappers - if (info->type != FRAME_TYPE_MANAGED && info->type != FRAME_TYPE_INTERP) { - return FALSE; - } - - if (data->cur_frame < data->target_frame) { - ++data->cur_frame; - return FALSE; - } - - InterpFrame *frame = (InterpFrame*)info->interp_frame; - g_assert (frame); - MonoMethod *method = frame->imethod->method; - g_assert (method); gpointer addr = NULL; if (mono_debug_lookup_method_async_debug_info (method)) { addr = mini_get_interp_callbacks ()->frame_get_this (frame); MonoObject *obj = *(MonoObject**)addr; describe_object_properties(get_object_id(obj), TRUE); } - return TRUE; } -static gboolean -describe_this (MonoStackFrameInfo *info, MonoContext *ctx, gpointer ud) +static void +describe_this (InterpFrame *frame, MonoMethod *method) { - //Async methods are special in the way that local variables can be lifted to generated class fields - FrameDescData *data = (FrameDescData*)ud; - - //skip wrappers - if (info->type != FRAME_TYPE_MANAGED && info->type != FRAME_TYPE_INTERP) { - return FALSE; - } - - if (data->cur_frame < data->target_frame) { - ++data->cur_frame; - return FALSE; - } - - InterpFrame *frame = (InterpFrame*)info->interp_frame; - g_assert (frame); - MonoMethod *method = frame->imethod->method; - g_assert (method); gpointer addr = NULL; if (mono_method_signature_internal (method)->hasthis) { addr = mini_get_interp_callbacks ()->frame_get_this (frame); MonoObject *obj = *(MonoObject**)addr; + char *class_name = mono_class_full_name (obj->vtable->klass); + mono_wasm_add_properties_var("this"); - GString *class_name; - class_name = g_string_new (""); - if (*(m_class_get_name_space (obj->vtable->klass))) { - g_string_append (class_name, m_class_get_name_space (obj->vtable->klass)); - g_string_append_c (class_name, '.'); - } - g_string_append (class_name, m_class_get_name (obj->vtable->klass)); - mono_wasm_add_obj_var (class_name->str, get_object_id(obj)); - g_string_free(class_name, FALSE); + mono_wasm_add_obj_var (class_name, get_object_id(obj)); + g_free (class_name); } - return TRUE; } - static gboolean -describe_variable (MonoStackFrameInfo *info, MonoContext *ctx, gpointer ud) +describe_variable (InterpFrame *frame, MonoMethod *method, int pos) { ERROR_DECL (error); MonoMethodHeader *header = NULL; - FrameDescData *data = (FrameDescData*)ud; - - //skip wrappers - if (info->type != FRAME_TYPE_MANAGED && info->type != FRAME_TYPE_INTERP) { - return FALSE; - } - - if (data->cur_frame < data->target_frame) { - ++data->cur_frame; - return FALSE; - } - - InterpFrame *frame = (InterpFrame*)info->interp_frame; - g_assert (frame); - MonoMethod *method = frame->imethod->method; - g_assert (method); - MonoType *type = NULL; gpointer addr = NULL; - int pos = data->variable; if (pos < 0) { pos = -pos - 1; type = mono_method_signature_internal (method)->params [pos]; @@ -881,21 +823,48 @@ describe_variable (MonoStackFrameInfo *info, MonoContext *ctx, gpointer ud) return TRUE; } +static gboolean +describe_variables_on_frame (MonoStackFrameInfo *info, MonoContext *ctx, gpointer ud) +{ + FrameDescData *data = (FrameDescData*)ud; + + //skip wrappers + if (info->type != FRAME_TYPE_MANAGED && info->type != FRAME_TYPE_INTERP) { + return FALSE; + } + + if (data->cur_frame < data->target_frame) { + ++data->cur_frame; + return FALSE; + } + + InterpFrame *frame = (InterpFrame*)info->interp_frame; + g_assert (frame); + MonoMethod *method = frame->imethod->method; + g_assert (method); + + for (int i = 0; i < data->len; i++) + { + describe_variable (frame, method, data->pos[i]); + } + + describe_async_method_locals (frame, method); + describe_this (frame, method); + + return TRUE; +} + //FIXME this doesn't support getting the return value pseudo-var EMSCRIPTEN_KEEPALIVE void mono_wasm_get_var_info (int scope, int* pos, int len) { FrameDescData data; - data.cur_frame = 0; data.target_frame = scope; - for (int i = 0; i < len; i++) - { - DEBUG_PRINTF (2, "getting var %d of scope %d - %d\n", pos[i], scope, len); - data.variable = pos[i]; - mono_walk_stack_with_ctx (describe_variable, NULL, MONO_UNWIND_NONE, &data); - } - mono_walk_stack_with_ctx (describe_async_method_locals, NULL, MONO_UNWIND_NONE, &data); - mono_walk_stack_with_ctx (describe_this, NULL, MONO_UNWIND_NONE, &data); + data.cur_frame = 0; + data.len = len; + data.pos = pos; + + mono_walk_stack_with_ctx (describe_variables_on_frame, NULL, MONO_UNWIND_NONE, &data); } EMSCRIPTEN_KEEPALIVE void