Пример #1
0
 public void SetSelectedPlatform(SbPlatform platform)
 {
     // We only support a single platform, so don't bother passing a platform here as the
     // server just assumes which platform to use.
     connection.InvokeRpc(() =>
     {
         client.SetSelectedPlatform(new SetSelectedPlatformRequest());
     });
 }
Пример #2
0
        string RunShellCommand(string command, SbPlatform platform)
        {
            SbPlatformShellCommand shellCommand = _lldbPlatformShellCommandFactory.Create(command);
            SbError error = platform.Run(shellCommand);

            if (error.Fail())
            {
                return(null);
            }

            return(shellCommand.GetOutput());
        }
        /// <summary>
        /// Set the selected platform.
        /// </summary>
        public override Task <SetSelectedPlatformResponse> SetSelectedPlatform(
            SetSelectedPlatformRequest request, ServerCallContext context)
        {
            SbDebuggerPreconditionCheck();

            // We currently only support one platform, so get it from the manager instead of the
            // request.
            SbPlatform sbPlatform = sbPlatformManager.GetPlatform();

            if (sbPlatform == null)
            {
                ErrorUtils.ThrowError(StatusCode.NotFound,
                                      "Could not find SBPlatform, make sure one has been created.");
            }
            sbDebugger.SetSelectedPlatform(sbPlatform);
            return(Task.FromResult(new SetSelectedPlatformResponse()));
        }
Пример #4
0
        public void SetUp()
        {
            var factory = new GrpcPlatformFactoryFake(null);

            factory.AddFakeProcess("linux-remote", "myGame", 2222);
            factory.AddFakeProcess("linux-remote", "ssh", 443244);
            factory.AddFakeProcess("linux-remote", "blah", 4545);

            var callInvokerFactory = new PipeCallInvokerFactory();
            var grpcConnection     =
                new GrpcConnection(new JoinableTaskContext().Factory, callInvokerFactory.Create());

            platform       = factory.Create("linux-remote", grpcConnection);
            connectOptions = new GrpcPlatformConnectOptionsFactory()
                             .Create("http://any/url");
            shellCommandFactory = new GrpcPlatformShellCommandFactory();
        }
Пример #5
0
        public override Task <CreateResponse> Create(CreateRequest request,
                                                     ServerCallContext context)
        {
            // We only support creating one SBPlatform object, fail if there is an attempt to
            // create more.
            if (sbPlatform != null)
            {
                ErrorUtils.ThrowError(StatusCode.FailedPrecondition,
                                      "Creating multiple SBPlatform objects is not supported.");
            }

            sbPlatform = sbPlatformFactory.Create(request.PlatformName);
            if (sbPlatform == null)
            {
                ErrorUtils.ThrowError(StatusCode.Internal, "Could not create SBPlatform.");
            }
            return(Task.FromResult(new CreateResponse()));
        }
Пример #6
0
        bool GetRemoteProcessId(string executable, SbPlatform platform, out uint pid)
        {
            pid = 0;
            var shellCommand = _lldbPlatformShellCommandFactory.Create($"pidof \"{executable}\"");

            if (platform == null)
            {
                Trace.WriteLine("Unable to find process, no platform selected");
                return(false);
            }
            var error = platform.Run(shellCommand);

            if (error.Fail())
            {
                Trace.WriteLine("Unable to find process: " + error.GetCString());
                return(false);
            }
            string output = shellCommand.GetOutput();

            if (string.IsNullOrEmpty(output))
            {
                Trace.WriteLine("Unable to find process '" + executable + "'");
                return(false);
            }
            string[] pids = output.Split(' ');
            if (pids.Length > 1)
            {
                Trace.WriteLine("Unable to select process, multiple instances of '" + executable +
                                "' are running");
                return(false);
            }
            if (!uint.TryParse(pids[0], out pid))
            {
                Trace.WriteLine("Unable to convert pid '" + pids[0] + "' to int");
                return(false);
            }
            return(true);
        }
Пример #7
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));
        }
Пример #8
0
 public void SetSelectedPlatform(SbPlatform platform)
 {
     this.selectedPlatform = platform;
 }