public void EnumCodeContexts(int numLocations) { var mockDocumentPosition = Substitute.For <IDebugDocumentPosition2>(); mockDocumentPosition.GetRange(Arg.Any <TEXT_POSITION[]>(), null).Returns(x => { var startPositions = x[0] as TEXT_POSITION[]; startPositions[0].dwLine = LINE; return(VSConstants.S_OK); }); mockDocumentPosition.GetFileName(out string _).Returns(x => { x[0] = Path.Combine(DIRECTORY, FILE_NAME); return(VSConstants.S_OK); }); var mockBreakpoint = Substitute.For <RemoteBreakpoint>(); var mockCodeContexts = new IDebugCodeContext2[numLocations]; for (uint i = 0; i < numLocations; ++i) { var mockAddress = Substitute.For <SbAddress>(); mockAddress.GetLoadAddress(mockRemoteTarget).Returns(ADDRESS + i); var mockFunction = Substitute.For <SbFunction>(); mockFunction.GetName().Returns(NAME + i); mockAddress.GetFunction().Returns(mockFunction); var lineEntry = new LineEntryInfo(); mockAddress.GetLineEntry().Returns(lineEntry); var mockDocumentContext = Substitute.For <IDebugDocumentContext2>(); mockDocumentContextFactory.Create(lineEntry).Returns(mockDocumentContext); var mockCodeContext = Substitute.For <IDebugCodeContext2>(); mockCodeContextFactory .Create(ADDRESS + i, NAME + i, mockDocumentContext, Guid.Empty) .Returns(mockCodeContext); var mockBreakpointLocation = Substitute.For <SbBreakpointLocation>(); mockBreakpointLocation.GetAddress().Returns(mockAddress); mockBreakpoint.GetLocationAtIndex(i).Returns(mockBreakpointLocation); mockCodeContexts[i] = mockCodeContext; } mockBreakpoint.GetNumLocations().Returns((uint)numLocations); mockRemoteTarget.BreakpointCreateByLocation(Path.Combine(DIRECTORY, FILE_NAME), LINE + 1).Returns(mockBreakpoint); int result = program.EnumCodeContexts(mockDocumentPosition, out IEnumDebugCodeContexts2 enumCodeContexts); Assert.AreEqual(VSConstants.S_OK, result); enumCodeContexts.GetCount(out uint count); Assert.AreEqual(numLocations, count); IDebugCodeContext2[] codeContexts = new IDebugCodeContext2[count]; uint actual = 0; enumCodeContexts.Next(count, codeContexts, ref actual); Assert.AreEqual(count, actual); Assert.AreEqual(mockCodeContexts, codeContexts); }
public void BindBreakpointFailed() { mockTarget.BreakpointCreateByLocation(TEST_FILE_NAME, LINE_NUMBER).Returns( (RemoteBreakpoint)null); MockDocumentPosition(TEST_FILE_NAME, LINE_NUMBER, COLUMN_NUMBER); var result = pendingBreakpoint.Bind(); IDebugErrorBreakpoint2 breakpointError = GetBreakpointError(); mockBreakpointManager.Received().ReportBreakpointError( Arg.Any <DebugBreakpointError>()); Assert.AreNotEqual(null, breakpointError); Assert.AreEqual(VSConstants.S_FALSE, result); }
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); }