private void MockFunctionData(uint startPosition, uint endPosition, string directory, string fileName) { SbBreakpointLocation location = mockBreakpoint.GetLocationAtIndex(0); SbAddress mockBreakpointAddress = Substitute.For <SbAddress>(); SbAddress mockStartAddress = Substitute.For <SbAddress>(); SbAddress mockFunctionEndAddress = Substitute.For <SbAddress>(); SbAddress mockActualEndAddress = Substitute.For <SbAddress>(); SbLineEntry mockStartLineEntry = Substitute.For <SbLineEntry>(); SbLineEntry mockEndLineEntry = Substitute.For <SbLineEntry>(); ulong address = 0x1234567; location.GetAddress().Returns(mockBreakpointAddress); mockBreakpointAddress.GetFunction().Returns(mockFunction); mockFunction.GetStartAddress().Returns(mockStartAddress); mockFunction.GetEndAddress().Returns(mockFunctionEndAddress); mockFunctionEndAddress.GetLoadAddress(mockTarget).Returns(address); mockTarget.ResolveLoadAddress(address - 1).Returns(mockActualEndAddress); mockStartAddress.GetLineEntry().Returns(mockStartLineEntry); mockActualEndAddress.GetLineEntry().Returns(mockEndLineEntry); mockStartLineEntry.GetLine().Returns(startPosition); mockStartLineEntry.GetDirectory().Returns(directory); mockStartLineEntry.GetFileName().Returns(fileName); mockEndLineEntry.GetLine().Returns(endPosition); }
internal static GrpcLineEntryInfo CreateGrpcLineEntryInfo(SbLineEntry lineEntry) { return(lineEntry == null ? null : new GrpcLineEntryInfo { FileName = lineEntry.GetFileName() ?? "", Directory = lineEntry.GetDirectory() ?? "", Line = lineEntry.GetLine(), Column = lineEntry.GetColumn() }); }
public BreakpointErrorPair CreateFunctionOffsetBreakpoint(string symbolName, uint offset) { RemoteBreakpoint functionBreakpoint = BreakpointCreateByName(symbolName); if (functionBreakpoint.GetNumLocations() < 1) { return(new BreakpointErrorPair(null, BreakpointError.NoFunctionLocation)); } // At the moment if there are two functions with the same offset will be applied only // for one of them. In base VS 2017 the breakpoint is created only for one // function if there are overloaded functions. SbFunction function = functionBreakpoint.GetLocationAtIndex(0).GetAddress().GetFunction(); // Delete the breakpoint as we don't need it anymore and don't want it to linger _sbTarget.BreakpointDelete(functionBreakpoint.GetId()); if (function == null) { return(new BreakpointErrorPair(null, BreakpointError.NoFunctionFound)); } SbLineEntry startLineEntry = function.GetStartAddress().GetLineEntry(); uint startLine = startLineEntry.GetLine(); // EndAddress points to the first address after the function so we // subtract one from that address and get the corresponding lineEntry. SbAddress endAddress = function.GetEndAddress(); ulong address = endAddress.GetLoadAddress(_sbTarget); endAddress = ResolveLoadAddress(address - 1); uint endLine = endAddress.GetLineEntry().GetLine(); uint newPosition = startLine + offset + 1; if (newPosition > endLine) { return(new BreakpointErrorPair(null, BreakpointError.PositionNotAvailable)); } string fileName = startLineEntry.GetFileName(); string directory = startLineEntry.GetDirectory(); string path = Path.Combine(directory, fileName); RemoteBreakpoint breakpoint = BreakpointCreateByLocation(path, newPosition); return(new BreakpointErrorPair(breakpoint, BreakpointError.Success)); }
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); }