[wasm][debugger] Fixing race condition (#64394)
authorThays Grazia <thaystg@gmail.com>
Mon, 7 Feb 2022 17:24:29 +0000 (14:24 -0300)
committerGitHub <noreply@github.com>
Mon, 7 Feb 2022 17:24:29 +0000 (14:24 -0300)
* Fixing race condition.

* Completely avoid race condition as @lewing suggested.

* keeping old name

* Addressing @radical comments

* Addressing @lewing comments.

* fix unrelated change

* Addressing @lewing comment offline.

src/mono/mono/component/mini-wasm-debugger.c
src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs
src/mono/wasm/runtime/debug.ts

index faf918d..28b8391 100644 (file)
@@ -368,9 +368,7 @@ EMSCRIPTEN_KEEPALIVE gboolean
 mono_wasm_send_dbg_command_with_parms (int id, MdbgProtCommandSet command_set, int command, guint8* data, unsigned int size, int valtype, char* newvalue)
 {
        if (!debugger_enabled) {
-               EM_ASM ({
-                       MONO.mono_wasm_add_dbg_command_received ($0, $1, $2, $3);
-               }, 0, id, 0, 0);
+               mono_wasm_add_dbg_command_received (0, id, 0, 0);
                return TRUE;
        }
        MdbgProtBuffer bufWithParms;
@@ -389,9 +387,7 @@ EMSCRIPTEN_KEEPALIVE gboolean
 mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command, guint8* data, unsigned int size)
 {
        if (!debugger_enabled) {
-               EM_ASM ({
-                       MONO.mono_wasm_add_dbg_command_received ($0, $1, $2, $3);
-               }, 0, id, 0, 0);
+               mono_wasm_add_dbg_command_received(0, id, 0, 0);
                return TRUE;
        }
        ss_calculate_framecount (NULL, NULL, TRUE, NULL, NULL);
@@ -410,7 +406,7 @@ mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command,
        else
                error = mono_process_dbg_packet (id, command_set, command, &no_reply, data, data + size, &buf);
 
-       mono_wasm_add_dbg_command_received(error == MDBGPROT_ERR_NONE, id, buf.buf, buf.p-buf.buf);
+       mono_wasm_add_dbg_command_received (error == MDBGPROT_ERR_NONE, id, buf.buf, buf.p-buf.buf);
 
        buffer_free (&buf);
        return TRUE;
@@ -419,7 +415,7 @@ mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command,
 static gboolean
 receive_debugger_agent_message (void *data, int len)
 {
-       mono_wasm_add_dbg_command_received(1, -1, data, len);
+       mono_wasm_add_dbg_command_received(1, 0, data, len);
        mono_wasm_save_thread_context();
        mono_wasm_fire_debugger_agent_message ();
        return FALSE;
index 173dfd3..b3e1feb 100644 (file)
@@ -700,8 +700,8 @@ namespace Microsoft.WebAssembly.Diagnostics
     internal class MonoSDBHelper
     {
         private static int debuggerObjectId;
-        private static int cmdId;
-        private static int GetId() {return cmdId++;}
+        private static int cmdId = 1; //cmdId == 0 is used by events which come from runtime
+        private static int GetNewId() {return cmdId++;}
         private static int MINOR_VERSION = 61;
         private static int MAJOR_VERSION = 2;
 
@@ -862,7 +862,7 @@ namespace Microsoft.WebAssembly.Diagnostics
         }
 
         internal async Task<MonoBinaryReader> SendDebuggerAgentCommand<T>(T command, MonoBinaryWriter arguments, CancellationToken token) =>
-            MonoBinaryReader.From (await proxy.SendMonoCommand(sessionId, MonoCommands.SendDebuggerAgentCommand(proxy.RuntimeId, GetId(), (int)GetCommandSetForCommand(command), (int)(object)command, arguments?.ToBase64().data ?? string.Empty), token));
+            MonoBinaryReader.From (await proxy.SendMonoCommand(sessionId, MonoCommands.SendDebuggerAgentCommand(proxy.RuntimeId, GetNewId(), (int)GetCommandSetForCommand(command), (int)(object)command, arguments?.ToBase64().data ?? string.Empty), token));
 
         internal CommandSet GetCommandSetForCommand<T>(T command) =>
             command switch {
@@ -885,7 +885,7 @@ namespace Microsoft.WebAssembly.Diagnostics
             };
 
         internal async Task<MonoBinaryReader> SendDebuggerAgentCommandWithParms<T>(T command, (string data, int length) encoded, int type, string extraParm, CancellationToken token) =>
-            MonoBinaryReader.From(await proxy.SendMonoCommand(sessionId, MonoCommands.SendDebuggerAgentCommandWithParms(proxy.RuntimeId, GetId(), (int)GetCommandSetForCommand(command), (int)(object)command, encoded.data, encoded.length, type, extraParm), token));
+            MonoBinaryReader.From(await proxy.SendMonoCommand(sessionId, MonoCommands.SendDebuggerAgentCommandWithParms(proxy.RuntimeId, GetNewId(), (int)GetCommandSetForCommand(command), (int)(object)command, encoded.data, encoded.length, type, extraParm), token));
 
         public async Task<int> CreateString(string value, CancellationToken token)
         {
@@ -2180,6 +2180,7 @@ namespace Microsoft.WebAssembly.Diagnostics
                                 command = CmdVM.InvokeMethod,
                                 buffer = data,
                                 length = length,
+                                id = GetNewId()
                                 }),
                             name = propertyNameStr
                         }));
@@ -2505,7 +2506,8 @@ namespace Microsoft.WebAssembly.Diagnostics
                             command = CmdObject.RefSetValues,
                             buffer = data,
                             valtype,
-                            length = length
+                            length,
+                            id = GetNewId()
                         }));
                     }
                     if (!isRootHidden)
@@ -2636,7 +2638,8 @@ namespace Microsoft.WebAssembly.Diagnostics
                                         command = CmdVM.InvokeMethod,
                                         buffer = data,
                                         valtype = attr["set"]["valtype"],
-                                        length = length
+                                        length,
+                                        id = GetNewId()
                                 });
                         }
                         continue;
@@ -2655,7 +2658,8 @@ namespace Microsoft.WebAssembly.Diagnostics
                                     commandSet = CommandSet.Vm,
                                     command = CmdVM.InvokeMethod,
                                     buffer = data,
-                                    length = length
+                                    length = length,
+                                    id = GetNewId()
                                     }),
                                 name = propertyNameStr
                             }));
index ee10a5d..ac7b035 100644 (file)
@@ -6,7 +6,8 @@ import { toBase64StringImpl } from "./base64";
 import cwraps from "./cwraps";
 import { VoidPtr, CharPtr } from "./types/emscripten";
 
-let commands_received: CommandResponse;
+const commands_received : any = new Map<number, CommandResponse>();
+commands_received.remove = function (key: number) : CommandResponse { const value = this.get(key); this.delete(key); return value;};
 let _call_function_res_cache: any = {};
 let _next_call_function_res_id = 0;
 let _debugger_buffer_len = -1;
@@ -43,7 +44,9 @@ export function mono_wasm_add_dbg_command_received(res_ok: boolean, id: number,
             value: base64String
         }
     };
-    commands_received = buffer_obj;
+    if (commands_received.has(id))
+        console.warn("Addind an id that already exists in commands_received");
+    commands_received.set(id, buffer_obj);
 }
 
 function mono_wasm_malloc_and_set_debug_buffer(command_parameters: string) {
@@ -63,7 +66,7 @@ export function mono_wasm_send_dbg_command_with_parms(id: number, command_set: n
     mono_wasm_malloc_and_set_debug_buffer(command_parameters);
     cwraps.mono_wasm_send_dbg_command_with_parms(id, command_set, command, _debugger_buffer, length, valtype, newvalue.toString());
 
-    const { res_ok, res } = commands_received;
+    const { res_ok, res } = commands_received.remove(id);
     if (!res_ok)
         throw new Error("Failed on mono_wasm_invoke_method_debugger_agent_with_parms");
     return res;
@@ -73,7 +76,8 @@ export function mono_wasm_send_dbg_command(id: number, command_set: number, comm
     mono_wasm_malloc_and_set_debug_buffer(command_parameters);
     cwraps.mono_wasm_send_dbg_command(id, command_set, command, _debugger_buffer, command_parameters.length);
 
-    const { res_ok, res } = commands_received;
+    const { res_ok, res } = commands_received.remove(id);
+
     if (!res_ok)
         throw new Error("Failed on mono_wasm_send_dbg_command");
     return res;
@@ -81,7 +85,8 @@ export function mono_wasm_send_dbg_command(id: number, command_set: number, comm
 }
 
 export function mono_wasm_get_dbg_command_info(): CommandResponseResult {
-    const { res_ok, res } = commands_received;
+    const { res_ok, res } = commands_received.remove(0);
+
     if (!res_ok)
         throw new Error("Failed on mono_wasm_get_dbg_command_info");
     return res;
@@ -138,10 +143,10 @@ function _create_proxy_from_object_id(objectId: string, details: any) {
                 prop.name,
                 {
                     get() {
-                        return mono_wasm_send_dbg_command(-1, prop.get.commandSet, prop.get.command, prop.get.buffer);
+                        return mono_wasm_send_dbg_command(prop.get.id, prop.get.commandSet, prop.get.command, prop.get.buffer);
                     },
                     set: function (newValue) {
-                        mono_wasm_send_dbg_command_with_parms(-1, prop.set.commandSet, prop.set.command, prop.set.buffer, prop.set.length, prop.set.valtype, newValue); return commands_received.res_ok;
+                        mono_wasm_send_dbg_command_with_parms(prop.set.id, prop.set.commandSet, prop.set.command, prop.set.buffer, prop.set.length, prop.set.valtype, newValue); return true;
                     }
                 }
             );
@@ -153,7 +158,7 @@ function _create_proxy_from_object_id(objectId: string, details: any) {
                         return prop.value;
                     },
                     set: function (newValue) {
-                        mono_wasm_send_dbg_command_with_parms(-1, prop.set.commandSet, prop.set.command, prop.set.buffer, prop.set.length, prop.set.valtype, newValue); return commands_received.res_ok;
+                        mono_wasm_send_dbg_command_with_parms(prop.set.id, prop.set.commandSet, prop.set.command, prop.set.buffer, prop.set.length, prop.set.valtype, newValue); return true;
                     }
                 }
             );