Example #1
0
        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);
        }
Example #2
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);
        }
Example #3
0
        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);
        }
Example #4
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);
        }
Example #5
0
        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());
        }
Example #6
0
        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;
Example #8
0
        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());
        }
Example #10
0
 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);
        }
Example #13
0
        /// <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);
        }
Example #16
0
        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();
        }
Example #17
0
 public SbProcess AttachToProcessWithID(SbListener listener, ulong pid, out SbError error) =>
 _sbTarget.AttachToProcessWithID(listener, pid, out error);
Example #18
0
 public SbWatchpoint WatchAddress(long address, ulong size, bool read, bool write,
                                  out SbError error) => _sbTarget.WatchAddress(address, size,
                                                                               read, write,
                                                                               out error);
Example #19
0
        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);
        }
Example #20
0
 public SbWatchpoint WatchAddress(long address, ulong size, bool read, bool write,
                                  out SbError error)
 {
     throw new NotImplementedTestDoubleException();
 }
Example #21
0
        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);
        }
Example #22
0
 public ulong WriteMemory(ulong address, byte[] buffer, ulong size, out SbError error)
 {
     throw new NotImplementedTestDoubleException();
 }
Example #23
0
 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));
        }