예제 #1
0
        public IEnumerable <SourceLocation> FindBreakpointLocations(BreakpointRequest request)
        {
            request.TryResolve(this);

            AssemblyInfo asm        = assemblies.FirstOrDefault(a => a.Name.Equals(request.Assembly, StringComparison.OrdinalIgnoreCase));
            SourceFile   sourceFile = asm?.Sources?.SingleOrDefault(s => s.DebuggerFileName.Equals(request.File, StringComparison.OrdinalIgnoreCase));

            if (sourceFile == null)
            {
                yield break;
            }

            foreach (MethodInfo method in sourceFile.Methods)
            {
                if (!method.DebugInformation.SequencePointsBlob.IsNil)
                {
                    foreach (SequencePoint sequencePoint in method.DebugInformation.GetSequencePoints())
                    {
                        if (!sequencePoint.IsHidden && Match(sequencePoint, request.Line, request.Column))
                        {
                            yield return(new SourceLocation(method, sequencePoint));
                        }
                    }
                }
            }
        }
예제 #2
0
        async Task SetBreakPoint(MessageId msg_id, BreakpointRequest req, CancellationToken token)
        {
            var context = GetContext(msg_id);
            var bp_loc  = context.Store.FindBestBreakpoint(req);

            Log("info", $"BP request for '{req}' runtime ready {context.RuntimeReady} location '{bp_loc}'");
            if (bp_loc == null)
            {
                Log("verbose", $"Could not resolve breakpoint request: {req}");
                SendResponse(msg_id, Result.Err(JObject.FromObject(new {
                    code    = (int)MonoErrorCodes.BpNotFound,
                    message = $"C# Breakpoint at {req} not found."
                })), token);
                return;
            }

            Breakpoint bp = null;

            if (!context.RuntimeReady)
            {
                bp = new Breakpoint(bp_loc, context.NextBreakpointId(), BreakpointState.Pending);
            }
            else
            {
                bp = new Breakpoint(bp_loc, context.NextBreakpointId(), BreakpointState.Disabled);

                var res = await EnableBreakPoint(msg_id, bp, token);

                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 (!ret_code.HasValue)
                {
                    SendResponse(msg_id, res, token);
                    return;
                }
            }

            context.Breakpoints.Add(bp);

            var ok = new {
                breakpointId = bp.StackId,
                locations    = new [] {
                    new {
                        scriptId     = bp_loc.Id.ToString(),
                        lineNumber   = bp_loc.Line,
                        columnNumber = bp_loc.Column
                    }
                },
            };

            SendResponse(msg_id, Result.OkFromObject(ok), token);
        }
예제 #3
0
파일: MonoProxy.cs 프로젝트: vdavyan/mono
        async Task <Breakpoint> SetMonoBreakpoint(SessionId sessionId, BreakpointRequest req, SourceLocation location, CancellationToken token)
        {
            var bp           = new Breakpoint(req.Id, location, BreakpointState.Pending);
            var asm_name     = bp.Location.CliLocation.Method.Assembly.Name;
            var method_token = bp.Location.CliLocation.Method.Token;
            var il_offset    = bp.Location.CliLocation.Offset;

            var res = await SendMonoCommand(sessionId, MonoCommands.SetBreakpoint(asm_name, method_token, il_offset), token);

            var ret_code = res.Value? ["result"]? ["value"]?.Value <int> ();

            if (ret_code.HasValue)
            {
                bp.RemoteId = ret_code.Value;
                bp.State    = BreakpointState.Active;
                //Log ("verbose", $"BP local id {bp.LocalId} enabled with remote id {bp.RemoteId}");
            }

            return(bp);
        }
예제 #4
0
파일: MonoProxy.cs 프로젝트: vdavyan/mono
        async Task SetBreakpoint(SessionId sessionId, DebugStore store, BreakpointRequest req, CancellationToken token)
        {
            var context = GetContext(sessionId);

            if (req.Locations.Any())
            {
                Log("debug", $"locations already loaded for {req.Id}");
                return;
            }

            var locations = store.FindBreakpointLocations(req).ToList();

            logger.LogDebug("BP request for '{req}' runtime ready {context.RuntimeReady}", req, GetContext(sessionId).IsRuntimeReady);

            var breakpoints = new List <Breakpoint> ();

            foreach (var loc in locations)
            {
                var bp = await SetMonoBreakpoint(sessionId, req, loc, token);

                // If we didn't successfully enable the breakpoint
                // don't add it to the list of locations for this id
                if (bp.State != BreakpointState.Active)
                {
                    continue;
                }

                breakpoints.Add(bp);

                var resolvedLocation = new {
                    breakpointId = req.Id,
                    location     = loc.AsLocation()
                };

                SendEvent(sessionId, "Debugger.breakpointResolved", JObject.FromObject(resolvedLocation), token);
            }

            req.Locations.AddRange(breakpoints);
            return;
        }
예제 #5
0
        protected override async Task <bool> AcceptCommand(MessageId id, string method, JObject args, CancellationToken token)
        {
            switch (method)
            {
            case "Debugger.getScriptSource": {
                var script = args? ["scriptId"]?.Value <string> ();
                return(await OnGetScriptSource(id, script, token));
            }

            case "Runtime.compileScript": {
                var exp = args? ["expression"]?.Value <string> ();
                if (exp.StartsWith("//dotnet:", StringComparison.Ordinal))
                {
                    OnCompileDotnetScript(id, token);
                    return(true);
                }
                break;
            }

            case "Debugger.getPossibleBreakpoints": {
                var start = SourceLocation.Parse(args? ["start"] as JObject);
                //FIXME support variant where restrictToFunction=true and end is omitted
                var end = SourceLocation.Parse(args? ["end"] as JObject);
                if (start != null && end != null)
                {
                    return(GetPossibleBreakpoints(id, start, end, token));
                }
                break;
            }

            case "Debugger.setBreakpointByUrl": {
                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);
                }
                break;
            }

            case "Debugger.removeBreakpoint": {
                return(await RemoveBreakpoint(id, args, token));
            }

            case "Debugger.resume": {
                await OnResume(id, token);

                break;
            }

            case "Debugger.stepInto": {
                return(await Step(id, StepKind.Into, token));
            }

            case "Debugger.stepOut": {
                return(await Step(id, StepKind.Out, token));
            }

            case "Debugger.stepOver": {
                return(await Step(id, StepKind.Over, token));
            }

            case "Runtime.getProperties": {
                var objId = args? ["objectId"]?.Value <string> ();
                if (objId.StartsWith("dotnet:", StringComparison.Ordinal))
                {
                    var parts = objId.Split(new char [] { ':' });
                    if (parts.Length < 3)
                    {
                        return(true);
                    }
                    switch (parts[1])
                    {
                    case "scope": {
                        await GetScopeProperties(id, int.Parse(parts[2]), token);

                        break;
                    }

                    case "object": {
                        await GetDetails(id, MonoCommands.GetObjectProperties(int.Parse(parts[2])), token);

                        break;
                    }

                    case "array": {
                        await GetDetails(id, MonoCommands.GetArrayValues(int.Parse(parts [2])), token);

                        break;
                    }
                    }
                    return(true);
                }
                break;
            }
            }

            return(false);
        }
예제 #6
0
    //from ide
    protected override async Task <bool> AcceptCommand(MessageId sessionId, JObject args, CancellationToken token)
    {
        if (args["type"] == null)
        {
            return(false);
        }

        switch (args["type"].Value <string>())
        {
        case "resume":
        {
            if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
            {
                return(false);
            }
            context.PausedOnWasm = false;
            if (context.CallStack == null)
            {
                return(false);
            }
            if (args["resumeLimit"] == null || args["resumeLimit"].Type == JTokenType.Null)
            {
                await OnResume(sessionId, token);

                return(false);
            }
            switch (args["resumeLimit"]["type"].Value <string>())
            {
            case "next":
                await context.SdbAgent.Step(context.ThreadId, StepKind.Over, token);

                break;

            case "finish":
                await context.SdbAgent.Step(context.ThreadId, StepKind.Out, token);

                break;

            case "step":
                await context.SdbAgent.Step(context.ThreadId, StepKind.Into, token);

                break;
            }
            await SendResume(sessionId, token);

            return(true);
        }

        case "isAttached":
        case "attach":
        {
            var ctx = GetContextFixefox(sessionId);
            ctx.ThreadName = args["to"].Value <string>();
            break;
        }

        case "source":
        {
            return(await OnGetScriptSource(sessionId, args["to"].Value <string>(), token));
        }

        case "getBreakableLines":
        {
            return(await OnGetBreakableLines(sessionId, args["to"].Value <string>(), token));
        }

        case "getBreakpointPositionsCompressed":
        {
            //{"positions":{"39":[20,28]},"from":"server1.conn2.child10/source27"}
            if (args["to"].Value <string>().StartsWith("dotnet://"))
            {
                var line    = new JObject();
                var offsets = new JArray();
                offsets.Add(0);
                line.Add(args["query"]["start"]["line"].Value <string>(), offsets);
                var o = JObject.FromObject(new
                    {
                        positions = line,
                        from      = args["to"].Value <string>()
                    });

                await SendEventInternal(sessionId, "", o, token);

                return(true);
            }
            break;
        }

        case "setBreakpoint":
        {
            if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
            {
                return(false);
            }
            var req = JObject.FromObject(new
                {
                    url          = args["location"]["sourceUrl"].Value <string>(),
                    lineNumber   = args["location"]["line"].Value <int>() - 1,
                    columnNumber = args["location"]["column"].Value <int>()
                });

            var bp = context.BreakpointRequests.Where(request => request.Value.CompareRequest(req)).FirstOrDefault();

            if (bp.Value != null)
            {
                bp.Value.UpdateCondition(args["options"]?["condition"]?.Value <string>());
                await SendCommand(sessionId, "", args, token);

                return(true);
            }

            string bpid = Interlocked.Increment(ref context.breakpointId).ToString();

            if (args["options"]?["condition"]?.Value <string>() != null)
            {
                req["condition"] = args["options"]?["condition"]?.Value <string>();
            }

            var  request = BreakpointRequest.Parse(bpid, req);
            bool loaded  = context.Source.Task.IsCompleted;

            context.BreakpointRequests[bpid] = request;

            if (await IsRuntimeAlreadyReadyAlready(sessionId, token))
            {
                DebugStore store = await RuntimeReady(sessionId, token);

                Log("verbose", $"BP req {args}");
                await SetBreakpoint(sessionId, store, request, !loaded, false, token);
            }
            await SendCommand(sessionId, "", args, token);

            return(true);
        }

        case "removeBreakpoint":
        {
            if (!contexts.TryGetValue(sessionId, out ExecutionContext context))
            {
                return(false);
            }
            Result resp = await SendCommand(sessionId, "", args, token);

            var reqToRemove = JObject.FromObject(new
                {
                    url          = args["location"]["sourceUrl"].Value <string>(),
                    lineNumber   = args["location"]["line"].Value <int>() - 1,
                    columnNumber = args["location"]["column"].Value <int>()
                });

            foreach (var req in context.BreakpointRequests.Values)
            {
                if (req.CompareRequest(reqToRemove))
                {
                    foreach (var bp in req.Locations)
                    {
                        var breakpoint_removed = await context.SdbAgent.RemoveBreakpoint(bp.RemoteId, token);

                        if (breakpoint_removed)
                        {
                            bp.RemoteId = -1;
                            bp.State    = BreakpointState.Disabled;
                        }
                    }
                }
            }
            return(true);
        }

        case "prototypeAndProperties":
        case "slice":
        {
            var to = args?["to"].Value <string>().Replace("propertyIterator", "");
            if (!DotnetObjectId.TryParse(to, out DotnetObjectId objectId))
            {
                return(false);
            }
            var res = await RuntimeGetObjectMembers(sessionId, objectId, args, token);

            var variables = ConvertToFirefoxContent(res);
            var o         = JObject.FromObject(new
                {
                    ownProperties = variables,
                    from          = args["to"].Value <string>()
                });
            if (args["type"].Value <string>() == "prototypeAndProperties")
            {
                o.Add("prototype", GetPrototype(objectId, args));
            }
            await SendEvent(sessionId, "", o, token);

            return(true);
        }

        case "prototype":
        {
            if (!DotnetObjectId.TryParse(args?["to"], out DotnetObjectId objectId))
            {
                return(false);
            }
            var o = JObject.FromObject(new
                {
                    prototype = GetPrototype(objectId, args),
                    from      = args["to"].Value <string>()
                });
            await SendEvent(sessionId, "", o, token);

            return(true);
        }

        case "enumSymbols":
        {
            if (!DotnetObjectId.TryParse(args?["to"], out DotnetObjectId objectId))
            {
                return(false);
            }
            var o = JObject.FromObject(new
                {
                    type  = "symbolIterator",
                    count = 0,
                    actor = args["to"].Value <string>() + "symbolIterator"
                });

            var iterator = JObject.FromObject(new
                {
                    iterator = o,
                    from     = args["to"].Value <string>()
                });

            await SendEvent(sessionId, "", iterator, token);

            return(true);
        }

        case "enumProperties":
        {
            //{"iterator":{"type":"propertyIterator","actor":"server1.conn19.child63/propertyIterator73","count":3},"from":"server1.conn19.child63/obj71"}
            if (!DotnetObjectId.TryParse(args?["to"], out DotnetObjectId objectId))
            {
                return(false);
            }
            var res = await RuntimeGetObjectMembers(sessionId, objectId, args, token);

            var variables = ConvertToFirefoxContent(res);
            var o         = JObject.FromObject(new
                {
                    type  = "propertyIterator",
                    count = variables.Count,
                    actor = args["to"].Value <string>() + "propertyIterator"
                });

            var iterator = JObject.FromObject(new
                {
                    iterator = o,
                    from     = args["to"].Value <string>()
                });

            await SendEvent(sessionId, "", iterator, token);

            return(true);
        }

        case "getEnvironment":
        {
            if (!DotnetObjectId.TryParse(args?["to"], out DotnetObjectId objectId))
            {
                return(false);
            }
            var ctx = GetContextFixefox(sessionId);
            if (ctx.CallStack == null)
            {
                return(false);
            }
            Frame scope = ctx.CallStack.FirstOrDefault(s => s.Id == objectId.Value);
            var   res   = await RuntimeGetObjectMembers(sessionId, objectId, args, token);

            var variables = ConvertToFirefoxContent(res);
            var o         = JObject.FromObject(new
                {
                    actor     = args["to"].Value <string>() + "_0",
                    type      = "function",
                    scopeKind = "function",
                    function  = new
                    {
                        displayName = scope.Method.Name
                    },
                    bindings = new
                    {
                        arguments = new JArray(),
                        variables
                    },
                    from = args["to"].Value <string>()
                });

            await SendEvent(sessionId, "", o, token);

            return(true);
        }

        case "frames":
        {
            ExecutionContext ctx = GetContextFixefox(sessionId);
            if (ctx.PausedOnWasm)
            {
                try
                {
                    await GetFrames(sessionId, ctx, args, token);

                    return(true);
                }
                catch (Exception)         //if the page is refreshed maybe it stops here.
                {
                    await SendResume(sessionId, token);

                    return(true);
                }
            }
            //var ret = await SendCommand(sessionId, "frames", args, token);
            //await SendEvent(sessionId, "", ret.Value["result"]["fullContent"] as JObject, token);
            return(false);
        }

        case "evaluateJSAsync":
        {
            var context = GetContextFixefox(sessionId);
            if (context.CallStack != null)
            {
                var resultID = $"runtimeResult-{context.GetResultID()}";
                var o        = JObject.FromObject(new
                    {
                        resultID,
                        from = args["to"].Value <string>()
                    });
                await SendEvent(sessionId, "", o, token);

                Frame scope = context.CallStack.First <Frame>();

                var     resolver = new MemberReferenceResolver(this, context, sessionId, scope.Id, logger);
                JObject retValue = await resolver.Resolve(args?["text"]?.Value <string>(), token);

                if (retValue == null)
                {
                    retValue = await ExpressionEvaluator.CompileAndRunTheExpression(args?["text"]?.Value <string>(), resolver, logger, token);
                }
                var osend = JObject.FromObject(new
                    {
                        type = "evaluationResult",
                        resultID,
                        hasException = false,
                        input        = args?["text"],
                        from         = args["to"].Value <string>()
                    });
                if (retValue["type"].Value <string>() == "object")
                {
                    osend["result"] = JObject.FromObject(new
                        {
                            type        = retValue["type"],
                            @class      = retValue["className"],
                            description = retValue["description"],
                            actor       = retValue["objectId"],
                        });
                }
                else
                {
                    osend["result"]            = retValue["value"];
                    osend["resultType"]        = retValue["type"];
                    osend["resultDescription"] = retValue["description"];
                }
                await SendEvent(sessionId, "", osend, token);
            }
            else
            {
                var ret = await SendCommand(sessionId, "evaluateJSAsync", args, token);

                var o = JObject.FromObject(new
                    {
                        resultID = ret.FullContent["resultID"],
                        from     = args["to"].Value <string>()
                    });
                await SendEvent(sessionId, "", o, token);
                await SendEvent(sessionId, "", ret.FullContent, token);
            }
            return(true);
        }

        case "DotnetDebugger.getMethodLocation":
        {
            var ret = await GetMethodLocation(sessionId, args, token);

            ret.Value["from"] = "internal";
            await SendEvent(sessionId, "", ret.Value, token);

            return(true);
        }

        default:
            return(false);
        }
        return(false);
    }
예제 #7
0
파일: MonoProxy.cs 프로젝트: vdavyan/mono
        protected override async Task <bool> AcceptCommand(MessageId id, string method, JObject args, CancellationToken token)
        {
            switch (method)
            {
            case "Debugger.enable": {
                    var resp = await SendCommand(id, method, args, token);

                    GetContext(id).DebuggerId = resp.Value ["debuggerId"]?.ToString();

                    if (await IsRuntimeAlreadyReadyAlready(id, token))
                    {
                        await RuntimeReady(id, token);
                    }

                    SendResponse(id, resp, token);
                    return(true);
            }

            case "Debugger.getScriptSource": {
                    var script = args? ["scriptId"]?.Value <string> ();
                    return(await OnGetScriptSource(id, script, token));
            }

            case "Runtime.compileScript": {
                var exp = args? ["expression"]?.Value <string> ();
                if (exp.StartsWith("//dotnet:", StringComparison.Ordinal))
                {
                    OnCompileDotnetScript(id, token);
                    return(true);
                }
                break;
            }

            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);
                //FIXME support variant where restrictToFunction=true and end is omitted
                var end = SourceLocation.Parse(args? ["end"] as JObject);
                if (start != null && end != null && await GetPossibleBreakpoints(id, start, end, token))
                {
                    return(true);
                }

                SendResponse(id, resp, token);
                return(true);
            }

            case "Debugger.setBreakpoint": {
                break;
            }

            case "Debugger.setBreakpointByUrl": {
                var context = GetContext(id);
                var resp    = await SendCommand(id, method, args, token);

                if (!resp.IsOk)
                {
                    SendResponse(id, resp, token);
                    return(true);
                }

                var bpid    = resp.Value["breakpointId"]?.ToString();
                var request = BreakpointRequest.Parse(bpid, args);
                context.BreakpointRequests[bpid] = request;
                if (await IsRuntimeAlreadyReadyAlready(id, token))
                {
                    var store = await RuntimeReady(id, token);

                    Log("verbose", $"BP req {args}");
                    await SetBreakpoint(id, store, request, token);
                }

                SendResponse(id, Result.OkFromObject(request.AsSetBreakpointByUrlResponse()), token);
                return(true);
            }

            case "Debugger.removeBreakpoint": {
                return(await RemoveBreakpoint(id, args, token));
            }

            case "Debugger.resume": {
                await OnResume(id, token);

                break;
            }

            case "Debugger.stepInto": {
                return(await Step(id, StepKind.Into, token));
            }

            case "Debugger.stepOut": {
                return(await Step(id, StepKind.Out, token));
            }

            case "Debugger.stepOver": {
                return(await Step(id, StepKind.Over, token));
            }

            case "Runtime.getProperties": {
                var objId = args? ["objectId"]?.Value <string> ();
                if (objId.StartsWith("dotnet:", StringComparison.Ordinal))
                {
                    var parts = objId.Split(new char [] { ':' });
                    if (parts.Length < 3)
                    {
                        return(true);
                    }
                    switch (parts[1])
                    {
                    case "scope": {
                        await GetScopeProperties(id, int.Parse(parts[2]), token);

                        break;
                    }

                    case "object": {
                        await GetDetails(id, MonoCommands.GetObjectProperties(int.Parse(parts[2])), token);

                        break;
                    }

                    case "array": {
                        await GetDetails(id, MonoCommands.GetArrayValues(int.Parse(parts [2])), token);

                        break;
                    }
                    }
                    return(true);
                }
                break;
            }
            }

            return(false);
        }