Skip to content

Commit

Permalink
[mono][debugger] Support debug after hot-reload (#55220)
Browse files Browse the repository at this point in the history
* Add test case for debug after hot reload.

* Implementing debug after hot reload, on runtime side, and on client side for wasm.

* Reuse some code.

* Remove unrelated comment.

* Reuse code.

* Refactor new code.

* Fix log.

* Apply suggestions from code review

Co-authored-by: Aleksey Kliger (λgeek) <akliger@gmail.com>

* Fixing hot reload without debug information.

* replacing spaces with tabs.

* Fixing CI.

Co-authored-by: Aleksey Kliger (λgeek) <akliger@gmail.com>
  • Loading branch information
thaystg and lambdageek authored Jul 13, 2021
1 parent da7bce7 commit c786e4f
Show file tree
Hide file tree
Showing 30 changed files with 852 additions and 132 deletions.
58 changes: 54 additions & 4 deletions src/mono/mono/component/debugger-agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,14 @@ typedef struct {
MonoStackHash *hashes;
} EventInfo;

typedef struct {
MonoImage *image;
gconstpointer meta_bytes;
int meta_len;
gconstpointer pdb_bytes;
int pdb_len;
} EnCInfo;

#ifdef HOST_WIN32
#define get_last_sock_error() WSAGetLastError()
#define MONO_EWOULDBLOCK WSAEWOULDBLOCK
Expand Down Expand Up @@ -1604,7 +1612,7 @@ static MonoGHashTable *suspended_objs;

#ifdef TARGET_WASM
void
mono_init_debugger_agent_for_wasm (int log_level_parm)
mono_init_debugger_agent_for_wasm (int log_level_parm, MonoProfilerHandle *prof)
{
if (mono_atomic_cas_i32 (&agent_inited, 1, 0) == 1)
return;
Expand All @@ -1615,13 +1623,16 @@ mono_init_debugger_agent_for_wasm (int log_level_parm)
ids_init();
objrefs = g_hash_table_new_full (NULL, NULL, NULL, mono_debugger_free_objref);
obj_to_objref = g_hash_table_new (NULL, NULL);
pending_assembly_loads = g_ptr_array_new ();

log_level = log_level_parm;
event_requests = g_ptr_array_new ();
vm_start_event_sent = TRUE;
transport = &transports [0];
memset(&debugger_wasm_thread, 0, sizeof(DebuggerTlsData));
agent_config.enabled = TRUE;

mono_profiler_set_jit_done_callback (*prof, jit_done);
}
#endif

Expand Down Expand Up @@ -3600,6 +3611,9 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx
case EVENT_KIND_TYPE_LOAD:
buffer_add_typeid (&buf, domain, (MonoClass *)arg);
break;
case MDBGPROT_EVENT_KIND_METHOD_UPDATE:
buffer_add_methodid (&buf, domain, (MonoMethod *)arg);
break;
case EVENT_KIND_BREAKPOINT:
case EVENT_KIND_STEP: {
GET_DEBUGGER_TLS();
Expand Down Expand Up @@ -3655,6 +3669,15 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx
case EVENT_KIND_KEEPALIVE:
suspend_policy = SUSPEND_POLICY_NONE;
break;

case MDBGPROT_EVENT_KIND_ENC_UPDATE: {
EnCInfo *ei = (EnCInfo *)arg;
buffer_add_moduleid (&buf, mono_domain_get (), ei->image);
m_dbgprot_buffer_add_byte_array (&buf, (uint8_t *) ei->meta_bytes, ei->meta_len);
m_dbgprot_buffer_add_byte_array (&buf, (uint8_t *) ei->pdb_bytes, ei->pdb_len);
break;
}

default:
g_assert_not_reached ();
}
Expand Down Expand Up @@ -4060,6 +4083,9 @@ jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo)

send_type_load (method->klass);

if (m_class_get_image(method->klass)->has_updates) {
process_profiler_event (MDBGPROT_EVENT_KIND_METHOD_UPDATE, method);
}
if (jinfo)
mono_de_add_pending_breakpoints (method, jinfo);
}
Expand Down Expand Up @@ -6517,6 +6543,28 @@ get_types_for_source_file (gpointer key, gpointer value, gpointer user_data)
}
}

static void
send_enc_delta (MonoImage *image, gconstpointer dmeta_bytes, int32_t dmeta_len, gconstpointer dpdb_bytes, int32_t dpdb_len)
{
//TODO: if it came from debugger we don't need to pass the parameters back, they are already on debugger client side.
if (agent_config.enabled) {
int suspend_policy;
GSList *events;
mono_loader_lock ();
events = create_event_list (MDBGPROT_EVENT_KIND_ENC_UPDATE, NULL, NULL, NULL, &suspend_policy);
mono_loader_unlock ();

EnCInfo info;
info.image = image;
info.meta_bytes = dpdb_bytes;
info.meta_len = dpdb_len;
info.pdb_bytes = dpdb_bytes;
info.pdb_len = dpdb_len;

process_event (MDBGPROT_EVENT_KIND_ENC_UPDATE, &info, 0, NULL, events, suspend_policy);
}
}

static gboolean
module_apply_changes (MonoImage *image, MonoArray *dmeta, MonoArray *dil, MonoArray *dpdb, MonoError *error)
{
Expand All @@ -6525,9 +6573,9 @@ module_apply_changes (MonoImage *image, MonoArray *dmeta, MonoArray *dil, MonoAr
int32_t dmeta_len = mono_array_length_internal (dmeta);
gpointer dil_bytes = (gpointer)mono_array_addr_internal (dil, char, 0);
int32_t dil_len = mono_array_length_internal (dil);
gpointer dpdb_bytes G_GNUC_UNUSED = !dpdb ? NULL : (gpointer)mono_array_addr_internal (dpdb, char, 0);
int32_t dpdb_len G_GNUC_UNUSED = !dpdb ? 0 : mono_array_length_internal (dpdb);
mono_image_load_enc_delta (image, dmeta_bytes, dmeta_len, dil_bytes, dil_len, error);
gpointer dpdb_bytes = !dpdb ? NULL : (gpointer)mono_array_addr_internal (dpdb, char, 0);
int32_t dpdb_len = !dpdb ? 0 : mono_array_length_internal (dpdb);
mono_image_load_enc_delta (image, dmeta_bytes, dmeta_len, dil_bytes, dil_len, dpdb_bytes, dpdb_len, error);
return is_ok (error);
}

Expand Down Expand Up @@ -7239,6 +7287,7 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
req->info = mono_de_set_breakpoint (NULL, METHOD_EXIT_IL_OFFSET, req, NULL);
} else if (req->event_kind == EVENT_KIND_EXCEPTION) {
} else if (req->event_kind == EVENT_KIND_TYPE_LOAD) {
} else if (req->event_kind == MDBGPROT_EVENT_KIND_METHOD_UPDATE) {
} else {
if (req->nmodifiers) {
g_free (req);
Expand Down Expand Up @@ -10278,6 +10327,7 @@ debugger_agent_add_function_pointers(MonoComponentDebugger* fn_table)
fn_table->debug_log_is_enabled = debugger_agent_debug_log_is_enabled;
fn_table->send_crash = mono_debugger_agent_send_crash;
fn_table->transport_handshake = debugger_agent_transport_handshake;
fn_table->send_enc_delta = send_enc_delta;
}


Expand Down
2 changes: 1 addition & 1 deletion src/mono/mono/component/debugger-agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ DebuggerTlsData*
mono_wasm_get_tls (void);

void
mono_init_debugger_agent_for_wasm (int log_level);
mono_init_debugger_agent_for_wasm (int log_level, MonoProfilerHandle *prof);

void
mono_wasm_save_thread_context (void);
Expand Down
4 changes: 3 additions & 1 deletion src/mono/mono/component/debugger-protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,9 @@ typedef enum {
MDBGPROT_EVENT_KIND_KEEPALIVE = 14,
MDBGPROT_EVENT_KIND_USER_BREAK = 15,
MDBGPROT_EVENT_KIND_USER_LOG = 16,
MDBGPROT_EVENT_KIND_CRASH = 17
MDBGPROT_EVENT_KIND_CRASH = 17,
MDBGPROT_EVENT_KIND_ENC_UPDATE = 18,
MDBGPROT_EVENT_KIND_METHOD_UPDATE = 19,
} MdbgProtEventKind;

typedef enum {
Expand Down
13 changes: 12 additions & 1 deletion src/mono/mono/component/debugger-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ stub_mono_wasm_breakpoint_hit (void);
static void
stub_mono_wasm_single_step_hit (void);

static void
stub_send_enc_delta (MonoImage *image, gconstpointer dmeta_bytes, int32_t dmeta_len, gconstpointer dpdb_bytes, int32_t dpdb_len);

static MonoComponentDebugger fn_table = {
{ MONO_COMPONENT_ITF_VERSION, &debugger_avaliable },
&stub_debugger_init,
Expand All @@ -87,7 +90,10 @@ static MonoComponentDebugger fn_table = {

//wasm
&stub_mono_wasm_breakpoint_hit,
&stub_mono_wasm_single_step_hit
&stub_mono_wasm_single_step_hit,

//HotReload
&stub_send_enc_delta,
};

static bool
Expand Down Expand Up @@ -201,3 +207,8 @@ static void
stub_mono_wasm_single_step_hit (void)
{
}

static void
stub_send_enc_delta (MonoImage *image, gconstpointer dmeta_bytes, int32_t dmeta_len, gconstpointer dpdb_bytes, int32_t dpdb_len)
{
}
3 changes: 3 additions & 0 deletions src/mono/mono/component/debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ typedef struct MonoComponentDebugger {
void (*mono_wasm_breakpoint_hit) (void);
void (*mono_wasm_single_step_hit) (void);

//HotReload
void (*send_enc_delta) (MonoImage *image, gconstpointer dmeta_bytes, int32_t dmeta_len, gconstpointer dpdb_bytes, int32_t dpdb_len);

} MonoComponentDebugger;


Expand Down
17 changes: 14 additions & 3 deletions src/mono/mono/component/hot_reload-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static bool
hot_reload_stub_available (void);

static void
hot_reload_stub_apply_changes (MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, MonoError *error);
hot_reload_stub_apply_changes (MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error);

static MonoComponentHotReload *
component_hot_reload_stub_init (void);
Expand Down Expand Up @@ -59,6 +59,9 @@ hot_reload_stub_table_bounds_check (MonoImage *base_image, int table_index, int
static gboolean
hot_reload_stub_delta_heap_lookup (MonoImage *base_image, MetadataHeapGetterFunc get_heap, uint32_t orig_index, MonoImage **image_out, uint32_t *index_out);

static gpointer
hot_reload_stub_get_updated_method_ppdb (MonoImage *base_image, uint32_t idx);

static gboolean
hot_reload_stub_has_modified_rows (const MonoTableInfo *table);

Expand All @@ -78,6 +81,7 @@ static MonoComponentHotReload fn_table = {
&hot_reload_stub_get_updated_method_rva,
&hot_reload_stub_table_bounds_check,
&hot_reload_stub_delta_heap_lookup,
&hot_reload_stub_get_updated_method_ppdb,
&hot_reload_stub_has_modified_rows,
};

Expand Down Expand Up @@ -143,7 +147,7 @@ hot_reload_stub_relative_delta_index (MonoImage *image_dmeta, int token)
}

void
hot_reload_stub_apply_changes (MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, MonoError *error)
hot_reload_stub_apply_changes (MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error)
{
mono_error_set_not_supported (error, "Hot reload not supported in this runtime.");
}
Expand Down Expand Up @@ -176,8 +180,15 @@ hot_reload_stub_delta_heap_lookup (MonoImage *base_image, MetadataHeapGetterFunc
g_assert_not_reached ();
}

static gpointer
hot_reload_stub_get_updated_method_ppdb (MonoImage *base_image, uint32_t idx)
{
g_assert_not_reached ();
}

static gboolean
hot_reload_stub_has_modified_rows (const MonoTableInfo *table){
hot_reload_stub_has_modified_rows (const MonoTableInfo *table)
{
return FALSE;
}

Expand Down
Loading

0 comments on commit c786e4f

Please sign in to comment.