public override Task <CreateFunctionOffsetBreakpointResponse> CreateFunctionOffsetBreakpoint(
            CreateFunctionOffsetBreakpointRequest request, ServerCallContext context)
        {
            if (!_targetStore.TryGetValue(request.Target.Id, out RemoteTarget target))
            {
                ErrorUtils.ThrowError(StatusCode.Internal,
                                      "Could not find target in store: " + request.Target.Id);
            }

            var response = new CreateFunctionOffsetBreakpointResponse();
            BreakpointErrorPair breakpointErrorPair =
                target.CreateFunctionOffsetBreakpoint(request.SymbolName, request.Offset);

            if (breakpointErrorPair.breakpoint != null)
            {
                response.Breakpoint = new GrpcSbBreakpoint {
                    Target = request.Target,
                    Id     = breakpointErrorPair.breakpoint.GetId(),
                };
            }
            response.Error = (Debugger.Common.BreakpointError)breakpointErrorPair.error;
            return(Task.FromResult(response));
        }
예제 #2
0
        public int Bind()
        {
            if (_deleted)
            {
                return(AD7Constants.E_BP_DELETED);
            }

            switch ((enum_BP_LOCATION_TYPE)_requestInfo.bpLocation.bpLocationType)
            {
            case enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE:
                IDebugDocumentPosition2 documentPosition =
                    _marshal.GetDocumentPositionFromIntPtr(_requestInfo.bpLocation.unionmember2);
                if (documentPosition.GetFileName(out string fileName) != 0)
                {
                    SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noSourceFilename);
                    return(VSConstants.S_FALSE);
                }

                TEXT_POSITION[] startPosition = new TEXT_POSITION[1];
                // TODO: Check if we need the end position or not.  This might
                // matter when setting a breakpoint on a comment.  It's possible LLDB will just
                // handle this for us and we don't need to worry about the end position.
                if (documentPosition.GetRange(startPosition, null) != VSConstants.S_OK)
                {
                    SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noSourceLineNumber);
                    return(VSConstants.S_FALSE);
                }

                // Visual Studio uses a zero based index for line numbers, where LLDB uses a one
                // based index for line numbers.  We need to add one to the line number here to
                // convert visual studio line numbers to LLDB line numbers.
                _lldbBreakpoint =
                    _target.BreakpointCreateByLocation(fileName, startPosition[0].dwLine + 1);
                break;

            case enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET:
                IDebugFunctionPosition2 functionPosition =
                    _marshal.GetFunctionPositionFromIntPtr(_requestInfo.bpLocation.unionmember2);
                uint offset = 0;
                if (functionPosition.GetFunctionName(out string functionName) != 0)
                {
                    SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noFunctionName);
                    return(VSConstants.S_FALSE);
                }
                MatchCollection matches = _funcOffsetRegex.Matches(functionName);
                if (matches.Count == 1)
                {
                    functionName = matches[0].Groups["name"].Value;
                    string offsetString = matches[0].Groups["offset"].Value;
                    if (!string.IsNullOrWhiteSpace(offsetString))
                    {
                        offset = uint.Parse(offsetString);
                    }
                }

                if (offset > 0)
                {
                    BreakpointErrorPair breakpointErrorPair =
                        _target.CreateFunctionOffsetBreakpoint(functionName, offset);
                    _lldbBreakpoint = breakpointErrorPair.breakpoint;
                    if (_lldbBreakpoint == null)
                    {
                        switch (breakpointErrorPair.error)
                        {
                        case BreakpointError.NoFunctionFound:
                            SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noFunctionFound);
                            break;

                        case BreakpointError.NoFunctionLocation:
                            SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING,
                                     _breakpointLocationNotSet);
                            break;

                        case BreakpointError.PositionNotAvailable:
                            SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING,
                                     _positionNotAvailable);
                            break;

                        default:
                            SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING,
                                     _positionNotAvailable);
                            break;
                        }
                        return(VSConstants.S_FALSE);
                    }
                }
                else
                {
                    _lldbBreakpoint = _target.BreakpointCreateByName(functionName);
                }
                break;

            case enum_BP_LOCATION_TYPE.BPLT_CODE_CONTEXT:
                IDebugCodeContext2 codeContext =
                    _marshal.GetCodeContextFromIntPtr(_requestInfo.bpLocation.unionmember1);
                if (codeContext == null)
                {
                    SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noCodeContext);
                    return(VSConstants.S_FALSE);
                }
                ulong address = codeContext.GetAddress();
                _lldbBreakpoint = _target.BreakpointCreateByAddress(address);
                break;

            case enum_BP_LOCATION_TYPE.BPLT_CODE_ADDRESS:
                string strAddress =
                    _marshal.GetStringFromIntPtr(_requestInfo.bpLocation.unionmember4);
                if (strAddress == null)
                {
                    SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _noCodeAddress);
                    return(VSConstants.S_FALSE);
                }
                ulong address2 = Convert.ToUInt64(strAddress, 16);
                _lldbBreakpoint = _target.BreakpointCreateByAddress(address2);
                break;

            default:
                SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _breakpointNotSupported);
                return(VSConstants.S_FALSE);
            }

            if (_lldbBreakpoint == null)
            {
                SetError(enum_BP_ERROR_TYPE.BPET_GENERAL_WARNING, _breakpointNotSet);
                return(VSConstants.S_FALSE);
            }

            UpdateLocations();
            _breakpointManager.RegisterPendingBreakpoint(Self);

            return(_boundBreakpoints.Count == 0
                ? VSConstants.S_FALSE
                : VSConstants.S_OK);
        }