diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index c6d294efa0460b..61afdfe1108278 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -3787,7 +3787,7 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx default: g_assert_not_reached (); } -#ifdef HOST_WASI + #ifdef HOST_WASI resumed_from_wasi = FALSE; while (suspend_policy != SUSPEND_POLICY_NONE && !resumed_from_wasi) { @@ -4122,7 +4122,14 @@ jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo) dbg_unlock (); if (assembly) { - process_profiler_event (EVENT_KIND_ASSEMBLY_LOAD, assembly); + DebuggerTlsData *tls; + tls = (DebuggerTlsData *)mono_native_tls_get_value (debugger_tls_id); + if (tls->invoke == NULL) { + process_profiler_event (EVENT_KIND_ASSEMBLY_LOAD, assembly); + } else { + assembly_load(prof, assembly); //send later + break; + } } else { break; } @@ -5043,20 +5050,16 @@ buffer_add_info_for_null_value (Buffer* buf, MonoType* t, MonoDomain* domain) { buffer_add_byte (buf, t->type); switch (t->type) { - case MONO_TYPE_CLASS: - case MONO_TYPE_STRING: - buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (t)); - break; - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - buffer_add_byte (buf, m_class_get_byval_arg (m_class_get_element_class (mono_class_from_mono_type_internal (t)))->type); - buffer_add_int (buf, m_class_get_rank (mono_class_from_mono_type_internal (t))); - if (m_class_get_byval_arg (m_class_get_element_class (mono_class_from_mono_type_internal (t)))->type == MONO_TYPE_CLASS) - buffer_add_typeid (buf, domain, m_class_get_element_class (mono_class_from_mono_type_internal (t))); - buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (t)); - break; - default: - buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (t)); + case MONO_TYPE_SZARRAY: + case MONO_TYPE_ARRAY: + buffer_add_byte (buf, m_class_get_byval_arg (m_class_get_element_class (mono_class_from_mono_type_internal (t)))->type); + buffer_add_int (buf, m_class_get_rank (mono_class_from_mono_type_internal (t))); + if (m_class_get_byval_arg (m_class_get_element_class (mono_class_from_mono_type_internal (t)))->type == MONO_TYPE_CLASS) + buffer_add_typeid (buf, domain, m_class_get_element_class (mono_class_from_mono_type_internal (t))); + buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (t)); + break; + default: + buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (t)); } } /* @@ -5073,6 +5076,9 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, MonoObject *obj; gboolean boxed_vtype = FALSE; + if (CHECK_ICORDBG (TRUE)) + buffer_add_byte (buf, !!m_type_is_byref (t)); + if (m_type_is_byref (t)) { if (!(*(void**)addr)) { /* This can happen with compiler generated locals */ @@ -5273,6 +5279,8 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, if (mono_vtype_get_field_addr (addr, f) == addr && mono_class_from_mono_type_internal (t) == mono_class_from_mono_type_internal (f->type) && !boxed_vtype) //to avoid infinite recursion { gssize val = *(gssize*)addr; + if (CHECK_ICORDBG (TRUE)) + buffer_add_byte (buf, !!m_type_is_byref (f->type)); buffer_add_byte (buf, MONO_TYPE_PTR); buffer_add_long (buf, val); if (CHECK_PROTOCOL_VERSION(2, 46)) @@ -7092,6 +7100,8 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) minor_version = decode_int (p, &p, end); if (p < end) using_icordbg = decode_byte (p, &p, end); + if (using_icordbg) + mono_de_set_using_icordbg (); protocol_version_set = TRUE; PRINT_DEBUG_MSG (1, "[dbg] Protocol version %d.%d, client protocol version %d.%d.\n", MAJOR_VERSION, MINOR_VERSION, major_version, minor_version); break; @@ -7115,7 +7125,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) wait_for_suspend (); break; case CMD_VM_RESUME: -#ifndef HOST_WASI + #ifndef HOST_WASI if (suspend_count == 0) { if (agent_config.defer && !agent_config.suspend) // Workaround for issue in debugger-libs when running in defer attach mode. @@ -7703,7 +7713,7 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf) if (req->event_kind == EVENT_KIND_BREAKPOINT) { g_assert (method); - + req->info = mono_de_set_breakpoint (method, location, req, error); if (!is_ok (error)) { g_free (req); @@ -7940,6 +7950,42 @@ domain_commands (int command, guint8 *p, guint8 *end, Buffer *buf) buffer_add_objid (buf, o); break; } + case MDBGPROT_CMD_APPDOMAIN_GET_ARRAY_OR_POINTER_TYPE: { + MonoClass *klass; + domain = decode_domainid (p, &p, end, NULL, &err); + MonoTypeEnum type = decode_int (p, &p, end); + klass = decode_typeid (p, &p, end, NULL, &err); + int rank = decode_int (p, &p, end); + if (type == MONO_TYPE_SZARRAY || type == MONO_TYPE_ARRAY) + klass = mono_class_create_array (klass, rank); + else + return ERR_INVALID_ARGUMENT; + buffer_add_typeid (buf, domain, klass); + break; + } + + case MDBGPROT_CMD_APPDOMAIN_CREATE_ARRAY: { + ERROR_DECL (error); + MonoClass *klass; + MonoArray *arr; + domain = decode_domainid (p, &p, end, NULL, &err); + klass = decode_typeid (p, &p, end, NULL, &err); + int rank = decode_int (p, &p, end); + uintptr_t *lengths = g_newa (uintptr_t, rank); + intptr_t *lower_bounds = g_newa (intptr_t, rank); + for (int i = 0 ; i < rank; i++) + { + lengths [i] = decode_int (p, &p, end); + } + for (int i = 0 ; i < rank; i++) + { + lower_bounds [i] = decode_int (p, &p, end); + } + arr = mono_array_new_full_checked (klass, lengths, lower_bounds, error); + buffer_add_objid (buf, (MonoObject*) arr); + break; + } + default: return ERR_NOT_IMPLEMENTED; } @@ -8282,6 +8328,21 @@ field_commands (int command, guint8 *p, guint8 *end, Buffer *buf) } break; } + case MDBGPROT_CMD_FIELD_GET_TOKEN_AND_TYPE: { + MonoClassField *f = decode_fieldid (p, &p, end, &domain, &err); + if (G_UNLIKELY (!f->type)) { + ERROR_DECL(field_error); + mono_field_resolve_type (f, field_error); + mono_error_cleanup (field_error); + if (!f->type) + return ERR_INVALID_OBJECT; + } + buffer_add_int (buf, mono_class_get_field_token (f)); + buffer_add_byte(buf, GINT_TO_UINT8(m_class_is_valuetype (mono_class_from_mono_type_internal (f->type)))); + buffer_add_int (buf, f->type->type); + buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (f->type)); + break; + } default: return ERR_NOT_IMPLEMENTED; } @@ -8471,6 +8532,19 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint buffer_add_int (buf, 0); } } + if (CHECK_ICORDBG (TRUE)) + { + if (type->type == MONO_TYPE_FNPTR) + { + buffer_add_int (buf, 1 + type->data.method->param_count); + buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (type->data.method->ret)); + for (int j = 0; j < type->data.method->param_count; ++j) { + buffer_add_typeid (buf, domain, mono_class_from_mono_type_internal (type->data.method->params[j])); + } + } else { + buffer_add_int (buf, 0); + } + } break; } case CMD_TYPE_GET_METHODS: { @@ -8886,43 +8960,8 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint if (CHECK_ICORDBG (TRUE)) { buffer_add_byte(buf, GINT_TO_UINT8(m_class_is_valuetype (klass))); - if (m_class_is_valuetype (klass)) - { - int nfields = 0; - gpointer iter = NULL; - while ((f = mono_class_get_fields_internal (klass, &iter))) { - if (G_UNLIKELY (!f->type)) { - ERROR_DECL(field_error); - mono_field_resolve_type (f, field_error); - mono_error_cleanup (field_error); - if (!f->type) - continue; - } - if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) - continue; - if (mono_field_is_deleted (f)) - continue; - nfields ++; - } - buffer_add_int (buf, nfields); - - iter = NULL; - while ((f = mono_class_get_fields_internal (klass, &iter))) { - if (G_UNLIKELY (!f->type)) { - ERROR_DECL(field_error); - mono_field_resolve_type (f, field_error); - mono_error_cleanup (field_error); - if (!f->type) - continue; - } - if (f->type->attrs & FIELD_ATTRIBUTE_STATIC) - continue; - if (mono_field_is_deleted (f)) - continue; - buffer_add_int (buf, mono_class_get_field_token (f)); - buffer_add_byte (buf, f->type->type); - } - } + buffer_add_int (buf, m_class_get_byval_arg (klass)->type); + buffer_add_typeid (buf, domain, klass); } break; } @@ -9002,6 +9041,33 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint buffer_add_byte (buf, m_class_get_rank (klass)); break; } + case MDBGPROT_CMD_TYPE_GET_FIELD_RVA: + { + gpointer iter = NULL; + int field_token = decode_int (p, &p, end); + while ((f = mono_class_get_fields_internal (klass, &iter))) { + if (mono_class_get_field_token (f) == field_token) + { + if (G_UNLIKELY (!f->type)) { + ERROR_DECL(field_error); + mono_field_resolve_type (f, field_error); + mono_error_cleanup (field_error); + if (!f->type) + continue; + } + if (f->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) + { + gint32 count = 0; + const char* arr = mono_get_span_data_from_field (f, f->type, f->type, &count); + m_dbgprot_buffer_add_byte_array (buf, (uint8_t *)arr, count); + err = ERR_NONE; + goto exit; + } + } + } + m_dbgprot_buffer_add_int (buf, 0); + break; + } default: err = ERR_NOT_IMPLEMENTED; goto exit; @@ -10181,7 +10247,7 @@ array_commands (int command, guint8 *p, guint8 *end, Buffer *buf) MonoTypeEnum type = m_class_get_byval_arg (m_class_get_element_class (arr->obj.vtable->klass))->type; buffer_add_byte(buf, type); buffer_add_int (buf, m_class_get_rank (arr->obj.vtable->klass)); - if (type == MONO_TYPE_CLASS || type == MONO_TYPE_GENERICINST || type == MONO_TYPE_OBJECT) + if (type == MONO_TYPE_CLASS || type == MONO_TYPE_GENERICINST || type == MONO_TYPE_OBJECT || (CHECK_ICORDBG (TRUE) && (type == MONO_TYPE_VALUETYPE || type == MONO_TYPE_PTR))) { buffer_add_typeid (buf, arr->obj.vtable->domain, m_class_get_element_class (arr->obj.vtable->klass)); if (CHECK_ICORDBG (TRUE)) @@ -10389,8 +10455,7 @@ object_commands (int command, guint8 *p, guint8 *end, Buffer *buf) break; } } - if (!k) - goto invalid_fieldid; + while ((f = mono_class_get_fields_internal (k, &iter))) { if (mono_class_get_field_token (f) == field_token) { goto get_field_value; diff --git a/src/mono/mono/component/debugger-engine.c b/src/mono/mono/component/debugger-engine.c index 02f7eb090f6aec..5ec3e68b62aee4 100644 --- a/src/mono/mono/component/debugger-engine.c +++ b/src/mono/mono/component/debugger-engine.c @@ -35,6 +35,7 @@ static DebuggerEngineCallbacks rt_callbacks; static int log_level; static FILE *log_file; +static bool using_icordbg = FALSE; /* * Locking @@ -160,6 +161,19 @@ insert_breakpoint (MonoSeqPointInfo *seq_points, MonoDomain *domain, MonoJitInfo } } + if (!it_has_sp && using_icordbg) + { + mono_seq_point_iterator_init (&it, seq_points); + while (mono_seq_point_iterator_next (&it)) { + if (it.seq_point.il_offset != METHOD_ENTRY_IL_OFFSET && + it.seq_point.il_offset != METHOD_EXIT_IL_OFFSET && + it.seq_point.il_offset > bp->il_offset) { + it_has_sp = TRUE; + break; + } + } + } + if (!it_has_sp) { char *s = g_strdup_printf ("Unable to insert breakpoint at %s:%ld", mono_method_full_name (jinfo_get_method (ji), TRUE), bp->il_offset); @@ -581,10 +595,10 @@ ss_req_cleanup (void) void mono_de_start_single_stepping (void) { - int val = mono_atomic_inc_i32 (&ss_count); + int val = mono_atomic_inc_i32 (&ss_count); if (val == 1) { -#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED + #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED mono_arch_start_single_stepping (); #endif mini_get_interp_callbacks_api ()->start_single_stepping (); @@ -594,10 +608,10 @@ mono_de_start_single_stepping (void) void mono_de_stop_single_stepping (void) { - int val = mono_atomic_dec_i32 (&ss_count); + int val = mono_atomic_dec_i32 (&ss_count); if (val == 0) { -#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED + #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED mono_arch_stop_single_stepping (); #endif mini_get_interp_callbacks_api ()->stop_single_stepping (); @@ -1534,6 +1548,12 @@ mono_de_set_log_level (int level, FILE *file) log_file = file; } +void +mono_de_set_using_icordbg () +{ + using_icordbg = TRUE; +} + /* * mono_de_init: * diff --git a/src/mono/mono/component/debugger-engine.h b/src/mono/mono/component/debugger-engine.h index b0f6c5ca729b38..d3c9b0696be5d1 100644 --- a/src/mono/mono/component/debugger-engine.h +++ b/src/mono/mono/component/debugger-engine.h @@ -345,6 +345,8 @@ mono_debugger_get_thread_state (DebuggerTlsData *ref); void mono_de_cleanup (void); void mono_de_set_log_level (int level, FILE *file); +void mono_de_set_using_icordbg (void); + //locking - we expose the lock object from the debugging engine to ensure we keep the same locking semantics of sdb. void mono_de_lock (void); void mono_de_unlock (void); diff --git a/src/mono/mono/component/debugger-protocol.h b/src/mono/mono/component/debugger-protocol.h index 9fe3c690c93e72..2379f5361ee6be 100644 --- a/src/mono/mono/component/debugger-protocol.h +++ b/src/mono/mono/component/debugger-protocol.h @@ -132,6 +132,8 @@ typedef enum { MDBGPROT_CMD_APPDOMAIN_GET_CORLIB = 6, MDBGPROT_CMD_APPDOMAIN_CREATE_BOXED_VALUE = 7, MDBGPROT_CMD_APPDOMAIN_CREATE_BYTE_ARRAY = 8, + MDBGPROT_CMD_APPDOMAIN_GET_ARRAY_OR_POINTER_TYPE = 9, + MDBGPROT_CMD_APPDOMAIN_CREATE_ARRAY = 10 } MdbgProtCmdAppDomain; typedef enum { @@ -162,6 +164,7 @@ typedef enum { typedef enum { MDBGPROT_CMD_FIELD_GET_INFO = 1, + MDBGPROT_CMD_FIELD_GET_TOKEN_AND_TYPE = 2 } MdbgProtCmdField; typedef enum { @@ -215,7 +218,8 @@ typedef enum { MDBGPROT_CMD_TYPE_BIND_GENERIC_PARAMETERS = 24, MDBGPROT_CMD_TYPE_ELEMENT_TYPE = 25, MDBGPROT_CMD_TYPE_RANK = 26, - MDBGPROT_CMD_TYPE_SET_VALUES_BY_FIELD_TOKEN = 27 + MDBGPROT_CMD_TYPE_SET_VALUES_BY_FIELD_TOKEN = 27, + MDBGPROT_CMD_TYPE_GET_FIELD_RVA = 28 } MdbgProtCmdType; typedef enum { diff --git a/src/mono/mono/metadata/class-internals.h b/src/mono/mono/metadata/class-internals.h index f9647d12aec216..0015177d5c2c33 100644 --- a/src/mono/mono/metadata/class-internals.h +++ b/src/mono/mono/metadata/class-internals.h @@ -1450,7 +1450,7 @@ mono_class_get_object_finalize_slot (void); MonoMethod * mono_class_get_default_finalize_method (void); -const char * +MONO_COMPONENT_API const char * mono_field_get_rva (MonoClassField *field, int swizzle); MONO_COMPONENT_API void diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 75d06bace0fe8c..6a4048119ed877 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -989,16 +989,7 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetSpanDataFrom (MonoCl mono_error_set_argument (error, "array", "Cannot initialize array of non-primitive type"); return NULL; } - - int swizzle = 1; - int align; -#if G_BYTE_ORDER != G_LITTLE_ENDIAN - swizzle = mono_type_size (type, &align); -#endif - - int dummy; - *count = mono_type_size (field_type, &dummy)/mono_type_size (type, &align); - return (gpointer)mono_field_get_rva (field_handle, swizzle); + return mono_get_span_data_from_field (field_handle, field_type, type, count); } void diff --git a/src/mono/mono/metadata/object-internals.h b/src/mono/mono/metadata/object-internals.h index 2f62c2530e8e46..1909411c7d03ef 100644 --- a/src/mono/mono/metadata/object-internals.h +++ b/src/mono/mono/metadata/object-internals.h @@ -2161,4 +2161,7 @@ mono_method_get_unmanaged_wrapper_ftnptr_internal (MonoMethod *method, gboolean void mono_runtime_run_startup_hooks (void); +MONO_COMPONENT_API gpointer +mono_get_span_data_from_field (MonoClassField *field_handle, MonoType *field_type, MonoType *target_type, gint32 *count); + #endif /* __MONO_OBJECT_INTERNALS_H__ */ diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index 9cbe2ee44a8350..c79b0f23597923 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -8215,6 +8215,20 @@ mono_runtime_run_startup_hooks (void) mono_error_raise_exception_deprecated (error); } +gpointer +mono_get_span_data_from_field (MonoClassField *field_handle, MonoType *field_type, MonoType *target_type, gint32 *count) +{ + int swizzle = 1; + int align; +#if G_BYTE_ORDER != G_LITTLE_ENDIAN + swizzle = mono_type_size (target_type, &align); +#endif + + int dummy; + *count = mono_type_size (field_type, &dummy)/mono_type_size (target_type, &align); + return (gpointer)mono_field_get_rva (field_handle, swizzle); +} + #if NEVER_DEFINED /* * The following section is purely to declare prototypes and