public bool Assign(string expression, out string error) { if (IsReadOnly) { error = string.Format( "Attempted to assign a value to a read only variable with name '{0}'.", DisplayName); return(false); } string cast = ""; if (_remoteValue.TypeIsPointerType() || _remoteValue.GetTypeInfo().GetTypeFlags().HasFlag(TypeFlags.IS_ENUMERATION)) { cast = $"({_remoteValue.GetTypeInfo().GetCanonicalType().GetName()})"; } expression = _remoteValueFormat.FormatExpressionForAssignment(_remoteValue, expression); // Avoid using parentheses to enclose registers because they can prevent assignments // involving initialization lists from succeeding. if (_remoteValue.GetValueType() != DebuggerApi.ValueType.Register) { expression = $"({expression})"; } RemoteValue tempValue = _remoteValue.CreateValueFromExpression( DisplayName, $"{_remoteValue.GetVariableAssignExpression()} = {cast}{expression}"); SbError sbError = tempValue.GetError(); error = sbError.Fail() ? sbError.GetCString() : null; return(sbError.Success()); }
public bool ApplyPlaceholderProperties(SbModule destModule, PlaceholderModuleProperties properties, RemoteTarget lldbTarget) { long slide = properties.Slide; SbAddress headerAddress = destModule.GetObjectFileHeaderAddress(); if (headerAddress != null) { // For libraries this will generally equal 0, for executables it will equal // |placeholderBaseLoadAddress|. ulong fileBaseAddress = headerAddress.GetFileAddress(); slide -= (long)fileBaseAddress; } SbError error = lldbTarget.SetModuleLoadAddress(destModule, slide); if (error.Fail()) { Trace.WriteLine( $"Failed to set load address on destination module: {error.GetCString()}."); return(false); } if (!destModule.SetPlatformFileSpec(properties.PlatformFileSpec)) { Trace.WriteLine("Failed to set file spec on the destination module."); return(false); } return(true); }
string RunShellCommand(string command, SbPlatform platform) { SbPlatformShellCommand shellCommand = _lldbPlatformShellCommandFactory.Create(command); SbError error = platform.Run(shellCommand); if (error.Fail()) { return(null); } return(shellCommand.GetOutput()); }
public void ReadMemoryRegionFail() { uint numberInstructions = 20; MockRead(numberInstructions, numberInstructions, mockAddress, mockMemoryRegion); mockError.Fail().Returns(true); var instructions = remoteTarget.ReadInstructionInfos(mockAddress, numberInstructions, "intel"); Assert.AreEqual(0, instructions.Count); mockMemoryRegion.DidNotReceive().IsMapped(); mockTarget.DidNotReceiveWithAnyArgs().ReadInstructions(mockAddress, numberInstructions, "intel"); }
/// <summary> /// Returns an error string if the _remoteValue's error is in fail state and null otherwise. /// </summary> string GetErrorString() { SbError error = _remoteValue.GetError(); if (!error.Fail()) { return(null); } // TODO: Determine why we are suppressing error strings for REGISTER // ValueTypes. Add comments if needed or remove otherwise. string errorString = _remoteValue.GetValueType() == DebuggerApi.ValueType.Register ? "unavailable" : error.GetCString(); return($"<{errorString}>"); }
public void BindWatchpointFailed() { SbError error; SbError mockError = Substitute.For <SbError>(); mockError.Fail().Returns(true); mockTarget.WatchAddress(TEST_ADDRESS, WATCH_SIZE, false, true, out error).Returns( x => { x[4] = mockError; return(null); }); var result = watchpoint.Bind(); IDebugErrorBreakpoint2 watchpointError = GetWatchpointError(); mockBreakpointManager.Received().ReportBreakpointError( Arg.Any <DebugBreakpointError>()); Assert.AreNotEqual(null, watchpointError); Assert.AreEqual(VSConstants.S_FALSE, result); }
public int SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { int result = CanSetNextStatement(stackFrame, codeContext); if (result != VSConstants.S_OK) { return(VSConstants.E_FAIL); } uint line; string filePath; codeContext.GetDocumentContext(out IDebugDocumentContext2 documentContext); if (documentContext != null) { documentContext.GetName(enum_GETNAME_TYPE.GN_FILENAME, out filePath); var beginPosition = new TEXT_POSITION[1]; var endPosition = new TEXT_POSITION[1]; documentContext.GetStatementRange(beginPosition, endPosition); line = beginPosition[0].dwLine + 1; Trace.WriteLine($"Settings next statement to {filePath} line {line}."); } else { var process = _remoteThread.GetProcess(); if (process == null) { Trace.WriteLine("Error: Failed to obtain process." + " Unable to set next statement"); return(VSConstants.E_FAIL); } var target = process.GetTarget(); if (target == null) { Trace.WriteLine("Error: Failed to obtain target." + " Unable to set next statement"); return(VSConstants.E_FAIL); } var address = target.ResolveLoadAddress(codeContext.GetAddress()); if (address == null) { Trace.WriteLine("Error: Failed to obtain address." + " Unable to set next statement"); return(VSConstants.E_FAIL); } var lineEntry = address.GetLineEntry(); if (lineEntry == null) { Trace.WriteLine("Error: Failed to obtain line entry." + " Unable to set next statement"); return(VSConstants.E_FAIL); } filePath = Path.Combine(lineEntry.Directory, lineEntry.FileName); line = lineEntry.Line; Trace.WriteLine($"Settings next statement to {address} at {filePath} line {line}"); } SbError error = _remoteThread.JumpToLine(filePath, line); if (error.Fail()) { Trace.WriteLine(error.GetCString()); return(VSConstants.E_FAIL); } return(VSConstants.S_OK); }
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); }