public ulong ReadMemory(ulong address, byte[] memory, ulong size, out SbError error) { ReadMemoryResponse response = null; if (connection.InvokeRpc(() => { response = client.ReadMemory( new ReadMemoryRequest { Process = grpcSbProcess, Address = address, Size = size }); })) { error = errorFactory.Create(response.Error); var responseArray = response.Memory.ToByteArray(); int startingIndex = 0; if (responseArray.Length > memory.Length) { Trace.WriteLine("Error: buffer is not large enough for the output."); startingIndex = responseArray.Length - memory.Length; } response.Memory.ToByteArray().CopyTo(memory, startingIndex); return(response.Size); } var grpcError = new GrpcSbError { Success = false, Error = "Rpc error while calling ReadMemory." }; error = errorFactory.Create(grpcError); return(0); }
public SbWatchpoint WatchAddress(long address, ulong size, bool read, bool write, out SbError error) { WatchAddressResponse response = null; error = null; if (connection.InvokeRpc(() => { response = client.WatchAddress( new WatchAddressRequest { Target = grpcSbTarget, Address = address, Size = size, Read = read, Write = write }); })) { error = errorFactory.Create(response.Error); if (response.Watchpoint != null && response.Watchpoint.Id != 0) { return(watchpointFactory.Create(connection, response.Watchpoint)); } return(null); } var grpcError = new GrpcSbError { Success = false, Error = "Rpc error while calling WatchAddress." }; error = errorFactory.Create(grpcError); return(null); }
public ulong WriteMemory(ulong address, byte[] buffer, ulong size, out SbError error) { WriteMemoryResponse response = null; if (connection.InvokeRpc(() => { response = client.WriteMemory( new WriteMemoryRequest { Process = grpcSbProcess, Address = address, Buffer = ByteString.CopyFrom(buffer, 0, (int)size), Size = size }); })) { error = errorFactory.Create(response.Error); return(response.Size); } var grpcError = new GrpcSbError { Success = false, Error = "Rpc error while calling WriteMemory." }; error = errorFactory.Create(grpcError); return(0); }
public SbProcess AttachToProcessWithID(SbListener listener, ulong pid, out SbError error) { var request = new AttachToProcessWithIDRequest() { Target = grpcSbTarget, Listener = new GrpcSbListener() { Id = listener.GetId() }, Pid = pid, }; AttachToProcessWithIDResponse response = null; if (connection.InvokeRpc(() => { response = client.AttachToProcessWithID(request); })) { error = errorFactory.Create(response.Error); if (response.Process == null) { return(null); } return(processFactory.Create(connection, response.Process)); } var grpcError = new GrpcSbError { Success = false, Error = "Rpc error while calling AttachToProcessWithId." }; error = errorFactory.Create(grpcError); return(null); }
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); }
internal static GrpcSbError CreateError(SbError error) => error != null ? new GrpcSbError { Success = error.Success(), Code = error.GetError(), Error = error.GetCString() ?? "" } : null;
public SbProcess AttachToProcessWithID(SbListener listener, ulong pid, out SbError error) { var process = new SbProcessStub(this, listener, pid); error = _targetAttachErrorString == null ? new SbErrorStub(true) : new SbErrorStub(false, _targetAttachErrorString); return(process); }
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 RemoteValueFake(string name, string value) { this.name = name; this.value = value; valueType = DebuggerApi.ValueType.Invalid; valueFormat = ValueFormat.Default; children = new List <RemoteValue>(); expressionValues = new Dictionary <string, Queue <RemoteValue> >(); valuesForAddress = new Dictionary <ulong, RemoteValue>(); sbError = new SbErrorStub(true); addressOf = null; dereference = null; clone = this; }
public override Task <SetModuleLoadAddressResponse> SetModuleLoadAddress( SetModuleLoadAddressRequest request, ServerCallContext context) { RemoteTarget target = GrpcLookupUtils.GetTarget(request.Target, _targetStore); SbModule module = _moduleStore.GetObject(request.Module.Id); SbError error = target.SetModuleLoadAddress(module, request.SectionsOffset); var grpcError = new GrpcSbError { Success = error.Success(), Error = error.GetCString() }; return(Task.FromResult(new SetModuleLoadAddressResponse { Error = grpcError })); }
public void SetUp() { mockTarget = Substitute.For <SbTarget>(); remoteTarget = new RemoteTargetFactory(new RemoteBreakpointFactory()) .Create(mockTarget); mockAddress = Substitute.For <SbAddress>(); mockProcess = Substitute.For <SbProcess>(); mockMemoryRegion = Substitute.For <SbMemoryRegionInfo>(); mockError = Substitute.For <SbError>(); mockBreakpoint = Substitute.For <SbBreakpoint>(); remoteBreakpoint = new RemoteBreakpointFactory().Create(mockBreakpoint); mockFunction = Substitute.For <SbFunction>(); mockTarget.GetProcess().Returns(mockProcess); }
/// <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 SetUp() { var taskContext = new JoinableTaskContext(); mockBreakpointManager = Substitute.For <IBreakpointManager>(); mockBreakpointRequest = Substitute.For <IDebugBreakpointRequest2>(); mockProgram = Substitute.For <IDebugProgram2>(); mockResolution = Substitute.For <IDebugBreakpointResolution2>(); mockResolutionFactory = Substitute.For <DebugWatchpointResolution.Factory>(); mockResolutionFactory.Create(TEST_ADDRESS_STR, mockProgram).Returns(mockResolution); mockTarget = Substitute.For <RemoteTarget>(); SbError error; mockError = Substitute.For <SbError>(); mockTarget.WatchAddress(TEST_ADDRESS, WATCH_SIZE, false, true, out error).Returns(x => { x[4] = mockError; return(mockLldbWatchpoint); }); mockMarshal = Substitute.For <Marshal>(); mockMarshal.GetStringFromIntPtr(Arg.Any <IntPtr>()).Returns(TEST_ADDRESS_STR); mockLldbWatchpoint = Substitute.For <SbWatchpoint>(); requestInfo = new BP_REQUEST_INFO(); requestInfo.bpLocation.unionmember4 = (IntPtr)4; mockBreakpointRequest.GetRequestInfo(Arg.Any <enum_BPREQI_FIELDS>(), Arg.Any <BP_REQUEST_INFO[]>()).Returns(x => { enum_BPREQI_FIELDS fields = (enum_BPREQI_FIELDS)x[0]; BP_REQUEST_INFO[] breakpointRequestInfo = (BP_REQUEST_INFO[])x[1]; if (breakpointRequestInfo == null || breakpointRequestInfo.Length == 0) { return(1); } return(BuildBreakpointRequestInfo(fields, out breakpointRequestInfo[0])); }); mockLldbWatchpoint.GetId().Returns(EXPECTED_ID); SetBreakpointType(enum_BP_LOCATION_TYPE.BPLT_DATA_STRING); watchpointFactory = new DebugWatchpoint.Factory(taskContext, mockResolutionFactory, new BreakpointErrorEnumFactory(), new BoundBreakpointEnumFactory()); watchpoint = watchpointFactory.Create(mockBreakpointManager, mockBreakpointRequest, mockTarget, mockProgram, mockMarshal); }
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); }
internal CachedValue(RemoteValue remoteProxy, RemoteValue addressOf, SbType typeInfo, string expressionPath, bool hasExpressionPath, uint numChildren, string summary, string typeName, string value, ValueType valueType, bool isPointerType, ValueFormat valueFormat, ulong byteSize) { this.remoteProxy = remoteProxy; this.addressOf = addressOf; this.typeInfo = typeInfo; this.expressionPath = expressionPath; this.hasExpressionPath = hasExpressionPath; this.numChildren = numChildren; this.summary = summary; this.typeName = typeName; this.value = value; this.valueType = valueType; this.isPointerType = isPointerType; this.valueFormat = valueFormat; this.byteSize = byteSize; // These values are prefeteched by remoteProxy. error = remoteProxy.GetError(); name = remoteProxy.GetName(); }
public SbProcess AttachToProcessWithID(SbListener listener, ulong pid, out SbError error) => _sbTarget.AttachToProcessWithID(listener, pid, out error);
public SbWatchpoint WatchAddress(long address, ulong size, bool read, bool write, out SbError error) => _sbTarget.WatchAddress(address, size, read, write, out error);
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); }
public SbWatchpoint WatchAddress(long address, ulong size, bool read, bool write, out SbError error) { throw new NotImplementedTestDoubleException(); }
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 ulong WriteMemory(ulong address, byte[] buffer, ulong size, out SbError error) { throw new NotImplementedTestDoubleException(); }
public void SetError(SbError sbError) { this.sbError = sbError; }
/// <summary> /// Get a more detailed error message if attaching to the remote process failed. /// /// At the moment, we handle specially only the case when another tracer is attached. /// In that case, we detect and show which process is the tracer. /// </summary> /// <param name="lldbError">Error object from Lldb attach.</param> /// <param name="platform">Lldb platform, used to run shell commands.</param> /// <param name="processId">Process Id of the debuggee.</param> /// <returns>Returns the error string.</returns> string GetLldbAttachErrorDetails(SbError lldbError, SbPlatform platform, uint processId) { string lldbMessageWhenAlreadyTraced = "Operation not permitted"; // Compute the fallback error message. string errorString = ErrorStrings.FailedToAttachToProcess(lldbError.GetCString()); // If the error does not need special handling, just return the default message. if (platform == null || lldbError.GetCString() != lldbMessageWhenAlreadyTraced) { return(errorString); } // Let us detect if there is a debugger already attached and provide a better error // message there. string output = RunShellCommand($"cat /proc/{processId}/status", platform); if (string.IsNullOrEmpty(output)) { return(errorString); } Regex tracerRE = new Regex("[\\r\\n]TracerPid:\\W*([0-9]+)[\\r\\n]"); Regex parentRE = new Regex("[\\r\\n]PPid:\\W*([0-9]+)[\\r\\n]"); Regex firstLineRE = new Regex("^([^\\r\\n]*)([\\r\\n]|$)"); // Find the line with tracer pid in the proc-status file. Match tracerMatch = tracerRE.Match(output); Match parentMatch = parentRE.Match(output); if (!tracerMatch.Success || !parentMatch.Success) { return(errorString); } string parentPid = parentMatch.Groups[1].Value; string tracerPid = tracerMatch.Groups[1].Value; // If there was no tracer, just show the default message. if (tracerPid == "0") { return(errorString); } // If the tracer is the parent process, then the debuggee is tracing itself. if (tracerPid == parentPid) { return(ErrorStrings.FailedToAttachToProcessSelfTrace); } // Try to find the tracer in the list of processes and report it in the error message. string commOutput = RunShellCommand($"cat /proc/{tracerPid}/comm", platform); if (string.IsNullOrEmpty(output)) { return(errorString); } // Get the first line as the process name. Match commMatch = firstLineRE.Match(commOutput); string tracerName = commMatch.Success ? commMatch.Groups[1].Value : "<unkown>"; return(ErrorStrings.FailedToAttachToProcessOtherTracer(tracerName, tracerPid)); }