From e549253dedf3ed9e79282582068c6e27a7a17efe Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Thu, 15 Oct 2020 16:28:58 -0300 Subject: [PATCH] [debugger][wasm] Implement Debugger.IsAttached on wasm (#42532) * Debugger.IsAttached is now working on wasm. And can be used to detect if debugger is attached. Fix #42411 * Update src/mono/wasm/runtime/library_mono.js Co-authored-by: Ryan Lucia * Using the infrastructure to not send dynamically loaded assemblies if debugger is not attached. Changing where to check if the assembly is already added to avoid unnecessary checks. * Checking the assembly name size. Co-authored-by: Ryan Lucia --- src/mono/mono/mini/mini-wasm-debugger.c | 30 ++++++++++++++++++++++ src/mono/mono/mini/mini-wasm.h | 2 ++ .../debugger/BrowserDebugProxy/DevToolsHelper.cs | 2 ++ .../wasm/debugger/BrowserDebugProxy/MonoProxy.cs | 5 ++++ src/mono/wasm/runtime/driver.c | 5 ++-- src/mono/wasm/runtime/library_mono.js | 12 ++++++--- 6 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/mini/mini-wasm-debugger.c b/src/mono/mono/mini/mini-wasm-debugger.c index 76eeede..cc838c5 100644 --- a/src/mono/mono/mini/mini-wasm-debugger.c +++ b/src/mono/mono/mini/mini-wasm-debugger.c @@ -53,6 +53,7 @@ EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_get_array_values (int object_id, int sta EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_invoke_getter_on_object (int object_id, const char* name); EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_invoke_getter_on_value (void *value, MonoClass *klass, const char *name); EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_get_deref_ptr_value (void *value_addr, MonoClass *klass); +EMSCRIPTEN_KEEPALIVE void mono_wasm_set_is_debugger_attached (gboolean is_attached); //JS functions imported that we use extern void mono_wasm_add_frame (int il_offset, int method_token, int frame_id, const char *assembly_name, const char *method_name); @@ -76,6 +77,8 @@ static void assembly_loaded (MonoProfiler *prof, MonoAssembly *assembly); //FIXME move all of those fields to the profiler object static gboolean debugger_enabled; +static gboolean has_pending_lazy_loaded_assemblies; + static int event_request_id; static GHashTable *objrefs; static GHashTable *obj_to_objref; @@ -497,6 +500,15 @@ assembly_loaded (MonoProfiler *prof, MonoAssembly *assembly) DEBUG_PRINTF (2, "assembly_loaded callback called for %s\n", assembly->aname.name); MonoImage *assembly_image = assembly->image; MonoImage *pdb_image = NULL; + + if (!mono_is_debugger_attached ()) { + has_pending_lazy_loaded_assemblies = TRUE; + return; + } + + if (mono_wasm_assembly_already_added(assembly->aname.name)) + return; + if (mono_has_pdb_checksum ((char *) assembly_image->raw_data, assembly_image->raw_data_len)) { //if it's a release assembly we don't need to send to DebuggerProxy MonoDebugHandle *handle = mono_debug_get_handle (assembly_image); if (handle) { @@ -1557,6 +1569,24 @@ mono_wasm_invoke_getter_on_value (void *value, MonoClass *klass, const char *nam return invoke_getter (value, klass, name); } +EMSCRIPTEN_KEEPALIVE void +mono_wasm_set_is_debugger_attached (gboolean is_attached) +{ + mono_set_is_debugger_attached (is_attached); + if (is_attached && has_pending_lazy_loaded_assemblies) + { + MonoDomain* domain = mono_domain_get (); + mono_domain_assemblies_lock (domain); + GSList *tmp; + for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) { + MonoAssembly *ass = (MonoAssembly *)tmp->data; + assembly_loaded (NULL, ass); + } + mono_domain_assemblies_unlock (domain); + has_pending_lazy_loaded_assemblies = FALSE; + } +} + // Functions required by debugger-state-machine. gsize mono_debugger_tls_thread_id (DebuggerTlsData *debuggerTlsData) diff --git a/src/mono/mono/mini/mini-wasm.h b/src/mono/mono/mini/mini-wasm.h index cdc5e81..ac35ed3 100644 --- a/src/mono/mono/mini/mini-wasm.h +++ b/src/mono/mono/mini/mini-wasm.h @@ -112,4 +112,6 @@ void mono_wasm_set_timeout (int timeout, int id); void mono_wasm_single_step_hit (void); void mono_wasm_breakpoint_hit (void); +int mono_wasm_assembly_already_added (const char *assembly_name); + #endif /* __MONO_MINI_WASM_H__ */ diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs index 3b1ca11..1ba773e 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs @@ -209,6 +209,8 @@ namespace Microsoft.WebAssembly.Diagnostics public static MonoCommands Resume() => new MonoCommands($"MONO.mono_wasm_debugger_resume ()"); public static MonoCommands SetPauseOnExceptions(string state) => new MonoCommands($"MONO.mono_wasm_set_pause_on_exceptions(\"{state}\")"); + + public static MonoCommands DetachDebugger() => new MonoCommands($"MONO.mono_wasm_detach_debugger()"); } internal enum MonoErrorCodes diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index b71b338..302c916 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -167,6 +167,11 @@ namespace Microsoft.WebAssembly.Diagnostics break; } + case "Target.targetDestroyed": + { + await SendMonoCommand(sessionId, MonoCommands.DetachDebugger(), token); + break; + } } return false; diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 3f17256..d339400 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -39,7 +39,6 @@ void mono_wasm_enable_debugging (int); int mono_wasm_register_root (char *start, size_t size, const char *name); void mono_wasm_deregister_root (char *addr); -int mono_wasm_assembly_already_added (const char *assembly_name); void mono_ee_interp_init (const char *opts); void mono_marshal_ilgen_init (void); @@ -206,7 +205,7 @@ mono_wasm_add_assembly (const char *name, const unsigned char *data, unsigned in return mono_has_pdb_checksum (data, size); } -EMSCRIPTEN_KEEPALIVE int +int mono_wasm_assembly_already_added (const char *assembly_name) { if (assembly_count == 0) @@ -214,7 +213,7 @@ mono_wasm_assembly_already_added (const char *assembly_name) WasmAssembly *entry = assemblies; while (entry != NULL) { - if (strcmp (entry->assembly.name, assembly_name) == 0) + if (strlen(entry->assembly.name - 4) == strlen(assembly_name) && strncmp (entry->assembly.name, assembly_name, strlen(entry->assembly.name - 4)) == 0) return 1; entry = entry->next; } diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index 6c0f30c..4d5164c 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -1255,6 +1255,12 @@ var MonoSupportLib = { return this.mono_wasm_pause_on_exceptions (state_enum); }, + mono_wasm_detach_debugger: function () { + if (!this.mono_wasm_set_is_debugger_attached) + this.mono_wasm_set_is_debugger_attached = Module.cwrap ('mono_wasm_set_is_debugger_attached', 'void', ['bool']); + this.mono_wasm_set_is_debugger_attached(false); + }, + _register_c_fn: function (name, ...args) { Object.defineProperty (this._c_fn_table, name + '_wrapper', { value: Module.cwrap (name, ...args) }); }, @@ -1817,6 +1823,9 @@ var MonoSupportLib = { // Used by the debugger to enumerate loaded dlls and pdbs mono_wasm_get_loaded_files: function() { + if (!this.mono_wasm_set_is_debugger_attached) + this.mono_wasm_set_is_debugger_attached = Module.cwrap ('mono_wasm_set_is_debugger_attached', 'void', ['bool']); + this.mono_wasm_set_is_debugger_attached (true); return MONO.loaded_files; }, @@ -2357,10 +2366,7 @@ var MonoSupportLib = { if (!this.mono_wasm_assembly_already_added) this.mono_wasm_assembly_already_added = Module.cwrap ("mono_wasm_assembly_already_added", 'number', ['string']); - // And for assemblies that have not already been loaded const assembly_name_str = assembly_name !== 0 ? Module.UTF8ToString(assembly_name).concat('.dll') : ''; - if (this.mono_wasm_assembly_already_added(assembly_name_str)) - return; const assembly_data = new Uint8Array(Module.HEAPU8.buffer, assembly_ptr, assembly_len); const assembly_b64 = MONO._base64Converter.toBase64StringImpl(assembly_data); -- 2.7.4