diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index 1130f53efc97d8..cf4bb725cdc348 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -361,37 +361,44 @@ protected override async Task AcceptCommand(MessageId id, JObject parms, C SendResponse(id, resp, token); return true; } + try + { + string bpid = resp.Value["breakpointId"]?.ToString(); + IEnumerable locations = resp.Value["locations"]?.Values(); + var request = BreakpointRequest.Parse(bpid, args); - string bpid = resp.Value["breakpointId"]?.ToString(); - IEnumerable locations = resp.Value["locations"]?.Values(); - var request = BreakpointRequest.Parse(bpid, args); + // is the store done loading? + bool loaded = context.Source.Task.IsCompleted; + if (!loaded) + { + // Send and empty response immediately if not + // and register the breakpoint for resolution + context.BreakpointRequests[bpid] = request; + SendResponse(id, resp, token); + } - // is the store done loading? - bool loaded = context.Source.Task.IsCompleted; - if (!loaded) - { - // Send and empty response immediately if not - // and register the breakpoint for resolution - context.BreakpointRequests[bpid] = request; - SendResponse(id, resp, token); - } + if (await IsRuntimeAlreadyReadyAlready(id, token)) + { + DebugStore store = await RuntimeReady(id, token); - if (await IsRuntimeAlreadyReadyAlready(id, token)) - { - DebugStore store = await RuntimeReady(id, token); + Log("verbose", $"BP req {args}"); + await SetBreakpoint(id, store, request, !loaded, false, token); + } - Log("verbose", $"BP req {args}"); - await SetBreakpoint(id, store, request, !loaded, false, token); - } + if (loaded) + { + // we were already loaded so we should send a response + // with the locations included and register the request + context.BreakpointRequests[bpid] = request; + var result = Result.OkFromObject(request.AsSetBreakpointByUrlResponse(locations)); + SendResponse(id, result, token); - if (loaded) + } + } + catch (Exception e) { - // we were already loaded so we should send a response - // with the locations included and register the request - context.BreakpointRequests[bpid] = request; - var result = Result.OkFromObject(request.AsSetBreakpointByUrlResponse(locations)); - SendResponse(id, result, token); - + logger.LogDebug($"Debugger.setBreakpointByUrl - {args} - failed with exception: {e}"); + SendResponse(id, Result.Err($"Debugger.setBreakpointByUrl - {args} - failed with exception: {e}"), token); } return true; } @@ -1449,7 +1456,8 @@ private async Task SetMonoBreakpoint(SessionId sessionId, string req var assembly_id = await context.SdbAgent.GetAssemblyId(asm_name, token); var methodId = await context.SdbAgent.GetMethodIdByToken(assembly_id, method_token, token); - var breakpoint_id = await context.SdbAgent.SetBreakpoint(methodId, il_offset, token); + //the breakpoint can be invalid because a race condition between the changes already applied on runtime and not applied yet on debugger side + var breakpoint_id = await context.SdbAgent.SetBreakpointNoThrow(methodId, il_offset, token); if (breakpoint_id > 0) { @@ -1726,7 +1734,10 @@ private async Task OnSetNextIP(MessageId sessionId, SourceLocation targetL if (!ret) return false; - var breakpointId = await context.SdbAgent.SetBreakpoint(scope.Method.DebugId, ilOffset.Offset, token); + var breakpointId = await context.SdbAgent.SetBreakpointNoThrow(scope.Method.DebugId, ilOffset.Offset, token); + if (breakpointId == -1) + return false; + context.TempBreakpointForSetNextIP = breakpointId; await SendResume(sessionId, token); return true; diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs index 3a25a7fac07929..8ff9f8ae9af99e 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs @@ -1356,7 +1356,7 @@ public async Task GetParameters(int methodId, CancellationToken token) return parameters; } - public async Task SetBreakpoint(int methodId, long il_offset, CancellationToken token) + public async Task SetBreakpointNoThrow(int methodId, long il_offset, CancellationToken token) { using var commandParamsWriter = new MonoBinaryWriter(); commandParamsWriter.Write((byte)EventKind.Breakpoint); @@ -1365,7 +1365,9 @@ public async Task SetBreakpoint(int methodId, long il_offset, CancellationT commandParamsWriter.Write((byte)ModifierKind.LocationOnly); commandParamsWriter.Write(methodId); commandParamsWriter.Write(il_offset); - using var retDebuggerCmdReader = await SendDebuggerAgentCommand(CmdEventRequest.Set, commandParamsWriter, token); + using var retDebuggerCmdReader = await SendDebuggerAgentCommand(CmdEventRequest.Set, commandParamsWriter, token, throwOnError: false); + if (retDebuggerCmdReader.HasError) + return -1; return retDebuggerCmdReader.ReadInt32(); }