// Create default mocks, and return values for the lldb breakpoint and breakpoint locations // for an assembly breakpoint. breakpointLocations is a list of mock breakpoint locations // that will be returned by the mock lldb breakpoint. void MockAssemblyBreakpoint(List <SbBreakpointLocation> breakpointLocations) { for (uint i = 0; i < breakpointLocations.Count; i++) { mockLldbBreakpoint.GetLocationAtIndex(i).Returns(breakpointLocations[(int)i]); } mockLldbBreakpoint.GetNumLocations().Returns((uint)breakpointLocations.Count); mockTarget.BreakpointCreateByAddress(TEST_ADDRESS).Returns(mockLldbBreakpoint); }
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); }