Пример #1
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());
        }
Пример #2
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);
        }
Пример #3
0
        internal static GrpcSbError CreateError(SbError error) =>
        error != null ? new GrpcSbError
        {
            Success = error.Success(),
            Code    = error.GetError(),
            Error   = error.GetCString() ?? ""
        }

              : null;
        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
            }));
        }
Пример #5
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}>");
        }
Пример #6
0
        /// <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));
        }
Пример #7
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);
        }