Update debug proxy to match Mono commit b91580bafa7208b4a52d66cfadce070551f1904a
This commit is contained in:
parent
085f6e1585
commit
fee14d8e13
|
|
@ -183,19 +183,36 @@ namespace WebAssembly.Net.Debugging {
|
||||||
|
|
||||||
public SourceId (string id)
|
public SourceId (string id)
|
||||||
{
|
{
|
||||||
id = id.Substring (Scheme.Length);
|
if (!TryParse (id, out assembly, out document))
|
||||||
var sp = id.Split ('_');
|
throw new ArgumentException ("invalid source identifier", nameof (id));
|
||||||
this.assembly = int.Parse (sp [0]);
|
|
||||||
this.document = int.Parse (sp [1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TryParse (string id, out SourceId script)
|
public static bool TryParse (string id, out SourceId source)
|
||||||
{
|
{
|
||||||
script = null;
|
source = null;
|
||||||
|
if (!TryParse (id, out var assembly, out var document))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
source = new SourceId (assembly, document);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool TryParse (string id, out int assembly, out int document)
|
||||||
|
{
|
||||||
|
assembly = document = 0;
|
||||||
if (id == null || !id.StartsWith (Scheme, StringComparison.Ordinal))
|
if (id == null || !id.StartsWith (Scheme, StringComparison.Ordinal))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
script = new SourceId (id);
|
var sp = id.Substring (Scheme.Length).Split ('_');
|
||||||
|
if (sp.Length != 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!int.TryParse (sp [0], out assembly))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!int.TryParse (sp [1], out document))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -495,6 +512,7 @@ namespace WebAssembly.Net.Debugging {
|
||||||
|
|
||||||
public IEnumerable<MethodInfo> Methods => this.methods;
|
public IEnumerable<MethodInfo> Methods => this.methods;
|
||||||
public byte[] EmbeddedSource => doc.EmbeddedSource;
|
public byte[] EmbeddedSource => doc.EmbeddedSource;
|
||||||
|
public string DocUrl => doc.Url;
|
||||||
|
|
||||||
public (int startLine, int startColumn, int endLine, int endColumn) GetExtents ()
|
public (int startLine, int startColumn, int endLine, int endColumn) GetExtents ()
|
||||||
{
|
{
|
||||||
|
|
@ -681,7 +699,7 @@ namespace WebAssembly.Net.Debugging {
|
||||||
public SourceFile GetFileByUrlRegex (string urlRegex)
|
public SourceFile GetFileByUrlRegex (string urlRegex)
|
||||||
{
|
{
|
||||||
var regex = new Regex (urlRegex);
|
var regex = new Regex (urlRegex);
|
||||||
return AllSources ().FirstOrDefault (file => regex.IsMatch (file.Url.ToString()));
|
return AllSources ().FirstOrDefault (file => regex.IsMatch (file.Url.ToString()) || regex.IsMatch (file.DocUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourceFile GetFileByUrl (string url)
|
public SourceFile GetFileByUrl (string url)
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,14 @@ namespace WebAssembly.Net.Debugging {
|
||||||
protected override async Task<bool> AcceptEvent (SessionId sessionId, string method, JObject args, CancellationToken token)
|
protected override async Task<bool> AcceptEvent (SessionId sessionId, string method, JObject args, CancellationToken token)
|
||||||
{
|
{
|
||||||
switch (method) {
|
switch (method) {
|
||||||
|
case "Runtime.consoleAPICalled": {
|
||||||
|
var type = args["type"]?.ToString ();
|
||||||
|
if (type == "debug") {
|
||||||
|
if (args["args"]?[0]?["value"]?.ToString () == MonoConstants.RUNTIME_IS_READY && args["args"]?[1]?["value"]?.ToString () == "fe00e07a-5519-4dfe-b35a-f867dbaf2e28")
|
||||||
|
await RuntimeReady (sessionId, token);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "Runtime.executionContextCreated": {
|
case "Runtime.executionContextCreated": {
|
||||||
SendEvent (sessionId, method, args, token);
|
SendEvent (sessionId, method, args, token);
|
||||||
var ctx = args? ["context"];
|
var ctx = args? ["context"];
|
||||||
|
|
@ -167,7 +175,6 @@ namespace WebAssembly.Net.Debugging {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
//break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case "Debugger.paused": {
|
case "Debugger.paused": {
|
||||||
|
|
@ -177,10 +184,6 @@ namespace WebAssembly.Net.Debugging {
|
||||||
if (top_func == "mono_wasm_fire_bp" || top_func == "_mono_wasm_fire_bp") {
|
if (top_func == "mono_wasm_fire_bp" || top_func == "_mono_wasm_fire_bp") {
|
||||||
return await OnBreakpointHit (sessionId, args, token);
|
return await OnBreakpointHit (sessionId, args, token);
|
||||||
}
|
}
|
||||||
if (top_func == MonoConstants.RUNTIME_IS_READY) {
|
|
||||||
await OnRuntimeReady (sessionId, token);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -221,22 +224,36 @@ namespace WebAssembly.Net.Debugging {
|
||||||
}
|
}
|
||||||
|
|
||||||
case "Debugger.getPossibleBreakpoints": {
|
case "Debugger.getPossibleBreakpoints": {
|
||||||
|
var resp = await SendCommand (id, method, args, token);
|
||||||
|
if (resp.IsOk && resp.Value["locations"].HasValues) {
|
||||||
|
SendResponse (id, resp, token);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var start = SourceLocation.Parse (args? ["start"] as JObject);
|
var start = SourceLocation.Parse (args? ["start"] as JObject);
|
||||||
//FIXME support variant where restrictToFunction=true and end is omitted
|
//FIXME support variant where restrictToFunction=true and end is omitted
|
||||||
var end = SourceLocation.Parse (args? ["end"] as JObject);
|
var end = SourceLocation.Parse (args? ["end"] as JObject);
|
||||||
if (start != null && end != null)
|
if (start != null && end != null && await GetPossibleBreakpoints (id, start, end, token))
|
||||||
return GetPossibleBreakpoints (id, start, end, token);
|
return true;
|
||||||
break;
|
|
||||||
|
SendResponse (id, resp, token);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "Debugger.setBreakpointByUrl": {
|
case "Debugger.setBreakpointByUrl": {
|
||||||
Log ("info", $"BP req {args}");
|
var resp = await SendCommand (id, method, args, token);
|
||||||
var bp_req = BreakpointRequest.Parse (args, GetContext (id).Store);
|
if (resp.IsOk && resp.Value ["locations"].HasValues) {
|
||||||
if (bp_req != null) {
|
SendResponse (id, resp, token);
|
||||||
await SetBreakPoint (id, bp_req, token);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
Log ("info", $"BP req {args}");
|
||||||
|
var bp_req = BreakpointRequest.Parse (args, GetContext (id).Store);
|
||||||
|
if (bp_req != null && await SetBreakpoint (id, bp_req, token))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
SendResponse (id, resp, token);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "Debugger.removeBreakpoint": {
|
case "Debugger.removeBreakpoint": {
|
||||||
|
|
@ -289,14 +306,6 @@ namespace WebAssembly.Net.Debugging {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task OnRuntimeReady (SessionId sessionId, CancellationToken token)
|
|
||||||
{
|
|
||||||
Log ("info", "Runtime ready");
|
|
||||||
await RuntimeReady (sessionId, token);
|
|
||||||
await SendCommand (sessionId, "Debugger.resume", new JObject (), token);
|
|
||||||
SendEvent (sessionId, "Mono.runtimeReady", new JObject (), token);
|
|
||||||
}
|
|
||||||
|
|
||||||
//static int frame_id=0;
|
//static int frame_id=0;
|
||||||
async Task<bool> OnBreakpointHit (SessionId sessionId, JObject args, CancellationToken token)
|
async Task<bool> OnBreakpointHit (SessionId sessionId, JObject args, CancellationToken token)
|
||||||
{
|
{
|
||||||
|
|
@ -428,14 +437,12 @@ namespace WebAssembly.Net.Debugging {
|
||||||
b.State = BreakpointState.Pending;
|
b.State = BreakpointState.Pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log ("info", "checking if the runtime is ready");
|
Log ("debug", "checking if the runtime is ready");
|
||||||
var res = await SendMonoCommand (sessionId, MonoCommands.IsRuntimeReady (), token);
|
var res = await SendMonoCommand (sessionId, MonoCommands.IsRuntimeReady (), token);
|
||||||
var is_ready = res.Value? ["result"]? ["value"]?.Value<bool> ();
|
var is_ready = res.Value? ["result"]? ["value"]?.Value<bool> ();
|
||||||
//Log ("verbose", $"\t{is_ready}");
|
|
||||||
if (is_ready.HasValue && is_ready.Value == true) {
|
if (is_ready.HasValue && is_ready.Value == true) {
|
||||||
Log ("info", "RUNTIME LOOK READY. GO TIME!");
|
|
||||||
await RuntimeReady (sessionId, token);
|
await RuntimeReady (sessionId, token);
|
||||||
SendEvent (sessionId, "Mono.runtimeReady", new JObject (), token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -452,6 +459,9 @@ namespace WebAssembly.Net.Debugging {
|
||||||
if (context.CallStack == null)
|
if (context.CallStack == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (context.CallStack.Count <= 1 && kind == StepKind.Out)
|
||||||
|
return false;
|
||||||
|
|
||||||
var res = await SendMonoCommand (msg_id, MonoCommands.StartSingleStepping (kind), token);
|
var res = await SendMonoCommand (msg_id, MonoCommands.StartSingleStepping (kind), token);
|
||||||
|
|
||||||
SendResponse (msg_id, Result.Ok (new JObject ()), token);
|
SendResponse (msg_id, Result.Ok (new JObject ()), token);
|
||||||
|
|
@ -579,7 +589,7 @@ namespace WebAssembly.Net.Debugging {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task<Result> EnableBreakPoint (SessionId sessionId, Breakpoint bp, CancellationToken token)
|
async Task<Result> EnableBreakpoint (SessionId sessionId, Breakpoint bp, CancellationToken token)
|
||||||
{
|
{
|
||||||
var asm_name = bp.Location.CliLocation.Method.Assembly.Name;
|
var asm_name = bp.Location.CliLocation.Method.Assembly.Name;
|
||||||
var method_token = bp.Location.CliLocation.Method.Token;
|
var method_token = bp.Location.CliLocation.Method.Token;
|
||||||
|
|
@ -643,7 +653,7 @@ namespace WebAssembly.Net.Debugging {
|
||||||
foreach (var bp in context.Breakpoints) {
|
foreach (var bp in context.Breakpoints) {
|
||||||
if (bp.State != BreakpointState.Pending)
|
if (bp.State != BreakpointState.Pending)
|
||||||
continue;
|
continue;
|
||||||
var res = await EnableBreakPoint (sessionId, bp, token);
|
var res = await EnableBreakpoint (sessionId, bp, token);
|
||||||
var ret_code = res.Value? ["result"]? ["value"]?.Value<int> ();
|
var ret_code = res.Value? ["result"]? ["value"]?.Value<int> ();
|
||||||
|
|
||||||
//if we fail we just buble that to the IDE (and let it panic over it)
|
//if we fail we just buble that to the IDE (and let it panic over it)
|
||||||
|
|
@ -653,6 +663,7 @@ namespace WebAssembly.Net.Debugging {
|
||||||
bp.State = BreakpointState.Disabled;
|
bp.State = BreakpointState.Disabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SendEvent (sessionId, "Mono.runtimeReady", new JObject (), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task<bool> RemoveBreakpoint(MessageId msg_id, JObject args, CancellationToken token) {
|
async Task<bool> RemoveBreakpoint(MessageId msg_id, JObject args, CancellationToken token) {
|
||||||
|
|
@ -689,19 +700,14 @@ namespace WebAssembly.Net.Debugging {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task SetBreakPoint (MessageId msg_id, BreakpointRequest req, CancellationToken token)
|
async Task<bool> SetBreakpoint (MessageId msg_id, BreakpointRequest req, CancellationToken token)
|
||||||
{
|
{
|
||||||
var context = GetContext (msg_id);
|
var context = GetContext (msg_id);
|
||||||
var bp_loc = context.Store.FindBestBreakpoint (req);
|
var bp_loc = context.Store.FindBestBreakpoint (req);
|
||||||
Log ("info", $"BP request for '{req}' runtime ready {context.RuntimeReady} location '{bp_loc}'");
|
Log ("info", $"BP request for '{req}' runtime ready {context.RuntimeReady} location '{bp_loc}'");
|
||||||
if (bp_loc == null) {
|
if (bp_loc == null) {
|
||||||
|
|
||||||
Log ("verbose", $"Could not resolve breakpoint request: {req}");
|
Log ("verbose", $"Could not resolve breakpoint request: {req}");
|
||||||
SendResponse (msg_id, Result.Err(JObject.FromObject (new {
|
return false;
|
||||||
code = (int)MonoErrorCodes.BpNotFound,
|
|
||||||
message = $"C# Breakpoint at {req} not found."
|
|
||||||
})), token);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Breakpoint bp = null;
|
Breakpoint bp = null;
|
||||||
|
|
@ -710,13 +716,12 @@ namespace WebAssembly.Net.Debugging {
|
||||||
} else {
|
} else {
|
||||||
bp = new Breakpoint (bp_loc, context.NextBreakpointId (), BreakpointState.Disabled);
|
bp = new Breakpoint (bp_loc, context.NextBreakpointId (), BreakpointState.Disabled);
|
||||||
|
|
||||||
var res = await EnableBreakPoint (msg_id, bp, token);
|
var res = await EnableBreakpoint (msg_id, bp, token);
|
||||||
var ret_code = res.Value? ["result"]? ["value"]?.Value<int> ();
|
var ret_code = res.Value? ["result"]? ["value"]?.Value<int> ();
|
||||||
|
|
||||||
//if we fail we just buble that to the IDE (and let it panic over it)
|
//if we fail we just buble that to the IDE (and let it panic over it)
|
||||||
if (!ret_code.HasValue) {
|
if (!ret_code.HasValue) {
|
||||||
SendResponse (msg_id, res, token);
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -730,11 +735,12 @@ namespace WebAssembly.Net.Debugging {
|
||||||
};
|
};
|
||||||
|
|
||||||
SendResponse (msg_id, Result.OkFromObject (ok), token);
|
SendResponse (msg_id, Result.OkFromObject (ok), token);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetPossibleBreakpoints (MessageId msg_id, SourceLocation start, SourceLocation end, CancellationToken token)
|
async Task<bool> GetPossibleBreakpoints (MessageId msg_id, SourceLocation start, SourceLocation end, CancellationToken token)
|
||||||
{
|
{
|
||||||
var bps = GetContext (msg_id).Store.FindPossibleBreakpoints (start, end);
|
var bps = (await LoadStore (msg_id, token)).FindPossibleBreakpoints (start, end);
|
||||||
if (bps == null)
|
if (bps == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -752,7 +758,7 @@ namespace WebAssembly.Net.Debugging {
|
||||||
if (!SourceId.TryParse (script_id, out var id))
|
if (!SourceId.TryParse (script_id, out var id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var src_file = GetContext (msg_id).Store.GetFileById (id);
|
var src_file = (await LoadStore (msg_id, token)).GetFileById (id);
|
||||||
var res = new StringWriter ();
|
var res = new StringWriter ();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue