static SourcePosition GetPositionFor(LineEntryInfo lineEntry) { if (lineEntry == null) { return(SourcePosition.Empty); } string directory = lineEntry.Directory; string filename = lineEntry.FileName; uint line = lineEntry.Line; if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(filename) || line == 0) { return(SourcePosition.Empty); } // Note: VS (at least VS2017) does not handle file paths with forward slashes // well - opening of disassembly gets very slow with them. Let's just use // backslashes (prepended with file://). string url = "file://" + System.IO.Path.Combine(directory, filename); return(new SourcePosition { Url = url, Line = line - 1 }); }
IDebugDocumentContext2 CreateDocumentContext() { LineEntryInfo lineEntry = lldbFrame.GetLineEntry(); return(lineEntry != null ? debugDocumentContextFactory.Create(lineEntry) : null); }
public InstructionInfo(ulong address, string operands, string comment, string mnemonic, string symbolName, LineEntryInfo lineEntry) { Address = address; Operands = operands; Comment = comment; Mnemonic = mnemonic; SymbolName = symbolName; LineEntry = lineEntry; }
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 GetDocumentContextNoLineEntry() { LineEntryInfo lineEntryNull = null; mockDebuggerStackFrame.GetLineEntry().Returns(lineEntryNull); IDebugDocumentContext2 documentContext; Assert.AreEqual(VSConstants.E_FAIL, stackFrame.GetDocumentContext(out documentContext)); Assert.AreEqual(null, documentContext); }
public void GetCodeContextNoDocumentContext() { var mockCodeContext = Substitute.For <IDebugCodeContext2>(); mockCodeContextFactory .Create(TEST_PC, NAME, null, Guid.Empty) .Returns(mockCodeContext); LineEntryInfo lineEntryNull = null; mockDebuggerStackFrame.GetLineEntry().Returns(lineEntryNull); IDebugCodeContext2 codeContext; Assert.AreEqual(VSConstants.S_OK, stackFrame.GetCodeContext(out codeContext)); Assert.AreEqual(codeContext, mockCodeContext); }
public void SetUp() { lineEntry = new LineEntryInfo(); mockDocumentContext = Substitute.For <IDebugDocumentContext2>(); mockThread = Substitute.For <IDebugThread>(); mockDocumentContextFactory = Substitute.For <DebugDocumentContext.Factory>(); mockDocumentContextFactory.Create(lineEntry).Returns(mockDocumentContext); mockDebuggerStackFrame = Substitute.For <RemoteFrame>(); mockDebuggerStackFrame.GetLineEntry().Returns(lineEntry); mockDebuggerStackFrame.GetPC().Returns(TEST_PC); mockDebuggerStackFrame.GetFunctionName().Returns(NAME); mockDebuggerStackFrame.GetFunctionNameWithSignature().Returns(NAME); mockCodeContextFactory = Substitute.For <DebugCodeContext.Factory>(); mockExpressionFactory = Substitute.For <DebugExpression.Factory>(); mockModuleCache = Substitute.For <IDebugModuleCache>(); mockDebugEngineHandler = Substitute.For <IDebugEngineHandler>(); mockProgram = Substitute.For <IGgpDebugProgram>(); taskExecutor = new TaskExecutor(new JoinableTaskContext().Factory); var childAdapterFactory = new RemoteValueChildAdapter.Factory(); var varInfoFactory = new LLDBVariableInformationFactory(childAdapterFactory); var varInfoEnumFactory = new VariableInformationEnum.Factory(taskExecutor); var childrenProviderFactory = new ChildrenProvider.Factory(); var propertyFactory = new DebugProperty.Factory(varInfoEnumFactory, childrenProviderFactory, Substitute.For <DebugCodeContext.Factory>(), new VsExpressionCreator(), taskExecutor); childrenProviderFactory.Initialize(propertyFactory.Create); var registerSetsBuilderFactory = new RegisterSetsBuilder.Factory(varInfoFactory); stackFrame = new DebugStackFrame.Factory(mockDocumentContextFactory, childrenProviderFactory, mockCodeContextFactory, mockExpressionFactory.Create, varInfoFactory, varInfoEnumFactory, registerSetsBuilderFactory, taskExecutor) .Create(new AD7FrameInfoCreator(mockModuleCache), mockDebuggerStackFrame, mockThread, mockDebugEngineHandler, mockProgram); stackFrameAsync = new DebugStackFrameAsync.Factory(mockDocumentContextFactory, childrenProviderFactory, mockCodeContextFactory, mockExpressionFactory.Create, varInfoFactory, varInfoEnumFactory, registerSetsBuilderFactory, taskExecutor) .Create(new AD7FrameInfoCreator(mockModuleCache), mockDebuggerStackFrame, mockThread, mockDebugEngineHandler, mockProgram); }
public void ReadOneInstructionWithSourceSameFile() { uint numberInstructionsToCreate = 1; uint numberInstructionsToRead = 10; uint previousLine = 6u; uint endLine = 9u; var mockInstructions = MockRead(numberInstructionsToCreate, numberInstructionsToRead); var lineEntry = CreateLineEntry(_testFilename, _testDirectory, endLine + 1u, 0u); mockInstructions[0].LineEntry = lineEntry; var previousEntry = new LineEntryInfo { Line = previousLine + 1u, Directory = _testDirectory, FileName = _testFilename }; _mockTarget.ResolveLoadAddress(_testAddress - 1).GetLineEntry().Returns(previousEntry); var disassembly = new DisassemblyData[numberInstructionsToRead]; Assert.AreEqual(VSConstants.S_OK, _disassemblyStream.Read((uint)disassembly.Length, enum_DISASSEMBLY_STREAM_FIELDS.DSF_ALL, out uint numberInstructionsRead, disassembly)); Assert.AreEqual(1, numberInstructionsRead); Assert.AreEqual(enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS | enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID | enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE | enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL | enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION | enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET | enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS, disassembly[0].dwFields); Assert.AreEqual(FormatUrl(_testDirectory, _testFilename), disassembly[0].bstrDocumentUrl); Assert.AreEqual(previousLine + 1, disassembly[0].posBeg.dwLine); Assert.AreEqual(0, disassembly[0].dwByteOffset); Assert.AreEqual(enum_DISASSEMBLY_FLAGS.DF_HASSOURCE, disassembly[0].dwFlags); }
public void SetUp() { string name = ""; mockBreakpoint = Substitute.For <RemoteBreakpoint>(); lineEntry = new LineEntryInfo(); mockPendingBreakpoint = Substitute.For <IDebugPendingBreakpoint2>(); mockBreakpointLocation = Substitute.For <SbBreakpointLocation>(); mockAddress = Substitute.For <SbAddress>(); mockAddress.GetLineEntry().Returns(lineEntry); mockBreakpointLocation.GetHitCount().Returns(HIT_COUNT); mockBreakpointLocation.GetLoadAddress().Returns(ADDRESS); mockBreakpointLocation.GetBreakpoint().Returns(mockBreakpoint); mockBreakpointLocation.GetId().Returns(ID); mockBreakpointLocation.GetAddress().Returns(mockAddress); mockprogram = Substitute.For <IDebugProgram2>(); mockDocumentContext = Substitute.For <IDebugDocumentContext2>(); mockDocumentContext.GetName(enum_GETNAME_TYPE.GN_NAME, out name).Returns( x => { x[1] = NAME; return(VSConstants.S_OK); }); mockBreakpointResolution = Substitute.For <IDebugBreakpointResolution2>(); mockDocumentContextFactory = Substitute.For <DebugDocumentContext.Factory>(); mockDocumentContextFactory.Create(lineEntry).Returns(mockDocumentContext); mockCodeContext = Substitute.For <IDebugCodeContext2>(); mockCodeContextFactory = Substitute.For <DebugCodeContext.Factory>(); mockCodeContextFactory.Create(ADDRESS, NAME, mockDocumentContext, Guid.Empty).Returns(mockCodeContext); mockBreakpointResolutionFactory = Substitute.For <DebugBreakpointResolution.Factory>(); mockBreakpointResolutionFactory.Create(mockCodeContext, mockprogram).Returns( mockBreakpointResolution); boundBreakpointFactory = new DebugBoundBreakpoint.Factory(mockDocumentContextFactory, mockCodeContextFactory, mockBreakpointResolutionFactory); boundBreakpoint = boundBreakpointFactory.Create( mockPendingBreakpoint, mockBreakpointLocation, mockprogram, Guid.Empty); }
// Constructor with factories for tests. DebugBoundBreakpoint(DebugDocumentContext.Factory documentContextFactory, DebugCodeContext.Factory codeContextFactory, DebugBreakpointResolution.Factory breakpointResolutionFactory, IDebugPendingBreakpoint2 pendingBreakpoint, SbBreakpointLocation breakpointLocation, IDebugProgram2 program, Guid languageGuid) { _pendingBreakpoint = pendingBreakpoint; _breakpointLocation = breakpointLocation; _enabled = true; _deleted = false; _disabledByPassCount = false; SbAddress address = breakpointLocation.GetAddress(); if (address != null) { LineEntryInfo lineEntry = address.GetLineEntry(); IDebugDocumentContext2 documentContext = null; string name = ""; // |lineEntry| is null if the breakpoint is set on an external function. if (lineEntry != null) { documentContext = documentContextFactory.Create(lineEntry); documentContext.GetName(enum_GETNAME_TYPE.GN_NAME, out name); } IDebugCodeContext2 codeContext = codeContextFactory.Create( breakpointLocation.GetLoadAddress(), name, documentContext, languageGuid); _breakpointResolution = breakpointResolutionFactory.Create(codeContext, program); } else { Trace.WriteLine("Warning: Unable to obtain address from breakpoint location." + " No breakpoint resolution created."); } }
public void SetUp() { lineEntry = new LineEntryInfo(); documentContextFactory = new DebugDocumentContext.Factory(); documentContext = documentContextFactory.Create(lineEntry); }
DebugDocumentContext(LineEntryInfo lldbLineEntry) { _lldbLineEntry = lldbLineEntry; }
public virtual IDebugDocumentContext2 Create( LineEntryInfo lldbLineEntry) => new DebugDocumentContext(lldbLineEntry);
public void SetNextStatementNoDocumentContext() { // We need CanSetNextStatement() to pass in order to execute SetNexStatement(). const string NAME = "test"; const ulong ADDRESS = 0xabcd; var threadId = 1u; var mockThread = Substitute.For <RemoteThread>(); mockThread.GetThreadId().Returns(threadId); var mockStackFrame = Substitute.For <IDebugStackFrame2>(); string name; mockStackFrame.GetName(out name).Returns(x => { x[0] = NAME; return(VSConstants.S_OK); }); IDebugThread2 outThread; IDebugThread thread = CreateDebugThread <IDebugThread>(mockThread); mockStackFrame.GetThread(out outThread).Returns(x => { x[0] = thread; return(VSConstants.S_OK); }); var mockCodeContext = Substitute.For <IDebugCodeContext2>(); System.Action <CONTEXT_INFO[]> setContextInfo = infos => { infos[0].bstrFunction = NAME; infos[0].bstrAddress = "0x" + ADDRESS.ToString("x16"); infos[0].dwFields = enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS | enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION; }; mockCodeContext .GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS | enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, Arg.Do(setContextInfo)) .Returns(VSConstants.S_OK); ((IDebugMemoryContext2)mockCodeContext) .GetInfo(Arg.Any <enum_CONTEXT_INFO_FIELDS>(), Arg.Do(setContextInfo)) .Returns(VSConstants.S_OK); IDebugDocumentContext2 documentContext; mockCodeContext.GetDocumentContext(out documentContext).Returns(x => { x[0] = null; return(VSConstants.S_OK); }); const string DIR = "path\\to"; const string FILE_NAME = "file"; const uint LINE = 2; var mockProcess = Substitute.For <SbProcess>(); mockThread.GetProcess().Returns(mockProcess); var mockTarget = Substitute.For <RemoteTarget>(); mockProcess.GetTarget().Returns(mockTarget); var mockAddress = Substitute.For <SbAddress>(); var mockLineEntry = new LineEntryInfo(); mockLineEntry.Directory = DIR; mockLineEntry.FileName = FILE_NAME; mockLineEntry.Line = LINE; var mockError = Substitute.For <SbError>(); mockError.Fail().Returns(false); mockThread.JumpToLine(Path.Combine(DIR, FILE_NAME), LINE).Returns(mockError); mockAddress.GetLineEntry().Returns(mockLineEntry); mockTarget.ResolveLoadAddress(ADDRESS).Returns(mockAddress); Assert.AreEqual(VSConstants.S_OK, thread.SetNextStatement(mockStackFrame, mockCodeContext)); mockThread.Received(1).JumpToLine(Path.Combine(DIR, FILE_NAME), LINE); }
public List <InstructionInfo> ReadInstructionInfos(SbAddress address, uint count, string flavor) { SbProcess process = _sbTarget.GetProcess(); var instructions = new List <InstructionInfo>(); while (instructions.Count < count) { SbMemoryRegionInfo memoryRegion = null; SbError error = process.GetMemoryRegionInfo(address.GetLoadAddress(_sbTarget), out memoryRegion); if (error.Fail()) { Trace.WriteLine("Unable to retrieve memory region info."); return(new List <InstructionInfo>()); } // If the address we are given is not mapped we should not try to disassemble it. if (!memoryRegion.IsMapped()) { uint instructionsLeft = count - (uint)instructions.Count; ulong nextAddress = AddUnmappedInstructions(address, instructionsLeft, memoryRegion, instructions); address = _sbTarget.ResolveLoadAddress(nextAddress); // Continue in case we still need more instructions continue; } List <SbInstruction> sbInstructions = _sbTarget.ReadInstructions(address, count - (uint)instructions.Count, flavor); foreach (SbInstruction sbInstruction in sbInstructions) { SbAddress sbAddress = sbInstruction.GetAddress(); if (sbAddress == null) { // It should never happen that we cannot get an address for an instruction Trace.WriteLine("Unable to retrieve address."); return(new List <InstructionInfo>()); } ulong instructionAddress = sbAddress.GetLoadAddress(_sbTarget); SbSymbol symbol = sbAddress.GetSymbol(); string symbolName = null; // Only set symbolName if it is the start of a function SbAddress startAddress = symbol?.GetStartAddress(); if (startAddress != null && startAddress.GetLoadAddress(_sbTarget) == instructionAddress) { symbolName = symbol.GetName(); } SbLineEntry lineEntry = sbAddress.GetLineEntry(); LineEntryInfo lineEntryInfo = null; if (lineEntry != null) { lineEntryInfo = new LineEntryInfo { FileName = lineEntry.GetFileName(), Directory = lineEntry.GetDirectory(), Line = lineEntry.GetLine(), Column = lineEntry.GetColumn(), }; } // Create a new instruction and fill in the values var instruction = new InstructionInfo { Address = instructionAddress, Operands = sbInstruction.GetOperands(_sbTarget), Comment = sbInstruction.GetComment(_sbTarget), Mnemonic = sbInstruction.GetMnemonic(_sbTarget), SymbolName = symbolName, LineEntry = lineEntryInfo, }; instructions.Add(instruction); } // If we haven't managed to retrieve all the instructions we wanted, add // an invalid instruction and keep going from the next address. if (instructions.Count < count) { ulong nextAddress = AddInvalidInstruction(address, sbInstructions, instructions); // Set the address to the next address after the invalid instruction address = _sbTarget.ResolveLoadAddress(nextAddress); } } return(instructions); }