Skip to content

Commit e5cd390

Browse files
author
msftbot[bot]
authored
Update ws-proxy to match Mono commit 4c348d6567f42be (#19600)
1 parent f4446f3 commit e5cd390

File tree

3 files changed

+232
-189
lines changed

3 files changed

+232
-189
lines changed

src/Components/WebAssembly/Server/src/MonoDebugProxy/ws-proxy/DebugStore.cs

Lines changed: 103 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -12,56 +12,76 @@
1212
using System.Threading.Tasks;
1313
using System.Threading;
1414
using Microsoft.Extensions.Logging;
15+
using System.Runtime.CompilerServices;
1516

1617
namespace WebAssembly.Net.Debugging {
1718
internal class BreakpointRequest {
19+
public string Id { get; private set; }
1820
public string Assembly { get; private set; }
1921
public string File { get; private set; }
2022
public int Line { get; private set; }
2123
public int Column { get; private set; }
2224

25+
JObject request;
26+
27+
public bool IsResolved => Assembly != null;
28+
public List<Breakpoint> Locations { get; } = new List<Breakpoint> ();
29+
2330
public override string ToString () {
2431
return $"BreakpointRequest Assembly: {Assembly} File: {File} Line: {Line} Column: {Column}";
2532
}
2633

27-
public static BreakpointRequest Parse (JObject args, DebugStore store)
34+
public object AsSetBreakpointByUrlResponse ()
35+
=> new { breakpointId = Id, locations = Locations.Select(l => l.Location.AsLocation ()) };
36+
37+
public static BreakpointRequest Parse (string id, JObject args)
2838
{
29-
// Events can potentially come out of order, so DebugStore may not be initialized
30-
// The BP being set in these cases are JS ones, which we can safely ignore
31-
if (args == null || store == null)
32-
return null;
39+
var breakRequest = new BreakpointRequest () {
40+
Id = id,
41+
request = args
42+
};
43+
return breakRequest;
44+
}
3345

34-
var url = args? ["url"]?.Value<string> ();
35-
if (url == null) {
36-
var urlRegex = args?["urlRegex"].Value<string>();
37-
var sourceFile = store?.GetFileByUrlRegex (urlRegex);
46+
public BreakpointRequest Clone ()
47+
=> new BreakpointRequest { Id = Id, request = request };
3848

39-
url = sourceFile?.DotNetUrl;
49+
public bool IsMatch (SourceFile sourceFile)
50+
{
51+
var url = request? ["url"]?.Value<string> ();
52+
if (url == null) {
53+
var urlRegex = request?["urlRegex"].Value<string>();
54+
var regex = new Regex (urlRegex);
55+
return regex.IsMatch (sourceFile.Url.ToString ()) || regex.IsMatch (sourceFile.DocUrl);
4056
}
4157

42-
if (url != null && !url.StartsWith ("dotnet://", StringComparison.Ordinal)) {
43-
var sourceFile = store.GetFileByUrl (url);
44-
url = sourceFile?.DotNetUrl;
45-
}
58+
return sourceFile.Url.ToString () == url || sourceFile.DotNetUrl == url;
59+
}
4660

47-
if (url == null)
48-
return null;
61+
public bool TryResolve (SourceFile sourceFile)
62+
{
63+
if (!IsMatch (sourceFile))
64+
return false;
4965

50-
var parts = ParseDocumentUrl (url);
51-
if (parts.Assembly == null)
52-
return null;
66+
var line = request? ["lineNumber"]?.Value<int> ();
67+
var column = request? ["columnNumber"]?.Value<int> ();
5368

54-
var line = args? ["lineNumber"]?.Value<int> ();
55-
var column = args? ["columnNumber"]?.Value<int> ();
5669
if (line == null || column == null)
57-
return null;
70+
return false;
5871

59-
return new BreakpointRequest () {
60-
Assembly = parts.Assembly,
61-
File = parts.DocumentPath,
62-
Line = line.Value,
63-
Column = column.Value
64-
};
72+
Assembly = sourceFile.AssemblyName;
73+
File = sourceFile.DebuggerFileName;
74+
Line = line.Value;
75+
Column = column.Value;
76+
return true;
77+
}
78+
79+
public bool TryResolve (DebugStore store)
80+
{
81+
if (request == null || store == null)
82+
return false;
83+
84+
return store.AllSources().FirstOrDefault (source => TryResolve (source)) != null;
6585
}
6686

6787
static (string Assembly, string DocumentPath) ParseDocumentUrl (string url)
@@ -99,7 +119,6 @@ public override string ToString ()
99119
}
100120
}
101121

102-
103122
internal class CliLocation {
104123
public CliLocation (MethodInfo method, int offset)
105124
{
@@ -111,7 +130,6 @@ public CliLocation (MethodInfo method, int offset)
111130
public int Offset { get; private set; }
112131
}
113132

114-
115133
internal class SourceLocation {
116134
SourceId id;
117135
int line;
@@ -268,11 +286,26 @@ public MethodInfo (AssemblyInfo assembly, MethodDefinition methodDef, SourceFile
268286
this.source = source;
269287

270288
var sps = methodDef.DebugInformation.SequencePoints;
271-
if (sps != null && sps.Count > 0) {
272-
StartLocation = new SourceLocation (this, sps [0]);
273-
EndLocation = new SourceLocation (this, sps [sps.Count - 1]);
289+
if (sps == null || sps.Count() < 1)
290+
return;
291+
292+
SequencePoint start = sps [0];
293+
SequencePoint end = sps [0];
294+
295+
foreach (var sp in sps) {
296+
if (sp.StartLine < start.StartLine)
297+
start = sp;
298+
else if (sp.StartLine == start.StartLine && sp.StartColumn < start.StartColumn)
299+
start = sp;
300+
301+
if (sp.EndLine > end.EndLine)
302+
end = sp;
303+
else if (sp.EndLine == end.EndLine && sp.EndColumn > end.EndColumn)
304+
end = sp;
274305
}
275306

307+
StartLocation = new SourceLocation (this, start);
308+
EndLocation = new SourceLocation (this, end);
276309
}
277310

278311
public SourceLocation GetLocationByIl (int pos)
@@ -556,7 +589,7 @@ class DebugItem {
556589
public Task<byte[][]> Data { get; set; }
557590
}
558591

559-
public async Task Load (SessionId sessionId, string [] loaded_files, CancellationToken token)
592+
public async IAsyncEnumerable<SourceFile> Load (SessionId sessionId, string [] loaded_files, [EnumeratorCancellation] CancellationToken token)
560593
{
561594
static bool MatchPdb (string asm, string pdb)
562595
=> Path.ChangeExtension (asm, "pdb") == pdb;
@@ -585,20 +618,27 @@ static bool MatchPdb (string asm, string pdb)
585618
}
586619

587620
foreach (var step in steps) {
621+
AssemblyInfo assembly = null;
588622
try {
589623
var bytes = await step.Data;
590-
assemblies.Add (new AssemblyInfo (step.Url, bytes[0], bytes[1]));
624+
assembly = new AssemblyInfo (step.Url, bytes [0], bytes [1]);
591625
} catch (Exception e) {
592626
logger.LogDebug ($"Failed to Load {step.Url} ({e.Message})");
593627
}
628+
if (assembly == null)
629+
continue;
630+
631+
assemblies.Add (assembly);
632+
foreach (var source in assembly.Sources)
633+
yield return source;
594634
}
595635
}
596636

597637
public IEnumerable<SourceFile> AllSources ()
598638
=> assemblies.SelectMany (a => a.Sources);
599639

600640
public SourceFile GetFileById (SourceId id)
601-
=> AllSources ().FirstOrDefault (f => f.SourceId.Equals (id));
641+
=> AllSources ().SingleOrDefault (f => f.SourceId.Equals (id));
602642

603643
public AssemblyInfo GetAssemblyByName (string name)
604644
=> assemblies.FirstOrDefault (a => a.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase));
@@ -612,15 +652,16 @@ static bool Match (SequencePoint sp, SourceLocation start, SourceLocation end)
612652
var spStart = (Line: sp.StartLine - 1, Column: sp.StartColumn - 1);
613653
var spEnd = (Line: sp.EndLine - 1, Column: sp.EndColumn - 1);
614654

615-
if (start.Line > spStart.Line)
655+
if (start.Line > spEnd.Line)
616656
return false;
617-
if (start.Column > spStart.Column && start.Line == sp.StartLine)
657+
658+
if (start.Column > spEnd.Column && start.Line == spEnd.Line)
618659
return false;
619660

620-
if (end.Line < spEnd.Line)
661+
if (end.Line < spStart.Line)
621662
return false;
622663

623-
if (end.Column < spEnd.Column && end.Line == spEnd.Line)
664+
if (end.Column < spStart.Column && end.Line == spStart.Line)
624665
return false;
625666

626667
return true;
@@ -629,22 +670,25 @@ static bool Match (SequencePoint sp, SourceLocation start, SourceLocation end)
629670
public List<SourceLocation> FindPossibleBreakpoints (SourceLocation start, SourceLocation end)
630671
{
631672
//XXX FIXME no idea what todo with locations on different files
632-
if (start.Id != end.Id)
673+
if (start.Id != end.Id) {
674+
logger.LogDebug ($"FindPossibleBreakpoints: documents differ (start: {start.Id}) (end {end.Id}");
633675
return null;
634-
var src_id = start.Id;
676+
}
635677

636-
var doc = GetFileById (src_id);
678+
var sourceId = start.Id;
679+
680+
var doc = GetFileById (sourceId);
637681

638682
var res = new List<SourceLocation> ();
639683
if (doc == null) {
640-
logger.LogDebug ($"Could not find document {src_id}");
684+
logger.LogDebug ($"Could not find document {sourceId}");
641685
return res;
642686
}
643687

644-
foreach (var m in doc.Methods) {
645-
foreach (var sp in m.methodDef.DebugInformation.SequencePoints) {
646-
if (Match (sp, start, end))
647-
res.Add (new SourceLocation (m, sp));
688+
foreach (var method in doc.Methods) {
689+
foreach (var sequencePoint in method.methodDef.DebugInformation.SequencePoints) {
690+
if (!sequencePoint.IsHidden && Match (sequencePoint, start, end))
691+
res.Add (new SourceLocation (method, sequencePoint));
648692
}
649693
}
650694
return res;
@@ -674,35 +718,26 @@ static bool Match (SequencePoint sp, int line, int column)
674718
return true;
675719
}
676720

677-
public SourceLocation FindBestBreakpoint (BreakpointRequest req)
721+
public IEnumerable<SourceLocation> FindBreakpointLocations (BreakpointRequest request)
678722
{
679-
var asm = assemblies.FirstOrDefault (a => a.Name.Equals (req.Assembly, StringComparison.OrdinalIgnoreCase));
680-
var src = asm?.Sources?.FirstOrDefault (s => s.DebuggerFileName.Equals (req.File, StringComparison.OrdinalIgnoreCase));
723+
request.TryResolve (this);
681724

682-
if (src == null)
683-
return null;
725+
var asm = assemblies.FirstOrDefault (a => a.Name.Equals (request.Assembly, StringComparison.OrdinalIgnoreCase));
726+
var sourceFile = asm?.Sources?.SingleOrDefault (s => s.DebuggerFileName.Equals (request.File, StringComparison.OrdinalIgnoreCase));
727+
728+
if (sourceFile == null)
729+
yield break;
684730

685-
foreach (var m in src.Methods) {
686-
foreach (var sp in m.methodDef.DebugInformation.SequencePoints) {
731+
foreach (var method in sourceFile.Methods) {
732+
foreach (var sequencePoint in method.methodDef.DebugInformation.SequencePoints) {
687733
//FIXME handle multi doc methods
688-
if (Match (sp, req.Line, req.Column))
689-
return new SourceLocation (m, sp);
734+
if (!sequencePoint.IsHidden && Match (sequencePoint, request.Line, request.Column))
735+
yield return new SourceLocation (method, sequencePoint);
690736
}
691737
}
692-
693-
return null;
694738
}
695739

696740
public string ToUrl (SourceLocation location)
697741
=> location != null ? GetFileById (location.Id).Url : "";
698-
699-
public SourceFile GetFileByUrlRegex (string urlRegex)
700-
{
701-
var regex = new Regex (urlRegex);
702-
return AllSources ().FirstOrDefault (file => regex.IsMatch (file.Url.ToString()) || regex.IsMatch (file.DocUrl));
703-
}
704-
705-
public SourceFile GetFileByUrl (string url)
706-
=> AllSources ().FirstOrDefault (file => file.Url.ToString() == url);
707742
}
708743
}

src/Components/WebAssembly/Server/src/MonoDebugProxy/ws-proxy/DevToolsProxy.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,14 @@ void SendEventInternal (SessionId sessionId, string method, JObject args, Cancel
290290

291291
internal void SendResponse (MessageId id, Result result, CancellationToken token)
292292
{
293-
//Log ("verbose", $"sending response: {id}: {result.ToJObject (id)}");
294293
SendResponseInternal (id, result, token);
295294
}
296295

297296
void SendResponseInternal (MessageId id, Result result, CancellationToken token)
298297
{
299298
JObject o = result.ToJObject (id);
299+
if (result.IsErr)
300+
logger.LogError ("sending error response {result}", result);
300301

301302
Send (this.ide, o, token);
302303
}

0 commit comments

Comments
 (0)