예제 #1
0
 public static IEnumerable <VersionInfo> EnumerateClrVersions(IProcessInfo info)
 {
     using (var session = DebugSession.Create(info))
     {
         return(session.DataTarget.ClrVersions.Select(v => v.Version));
     }
 }
예제 #2
0
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            return(Task.Run(async() =>
            {
                while (!stoppingToken.IsCancellationRequested)
                {
                    stoppingToken.ThrowIfCancellationRequested();

                    try
                    {
                        //TODO In multi-process scenarios, how do we decide which process to choose?
                        //One possibility is to enable metrics after a request to begin polling for metrics
                        IProcessInfo pi = await _services.GetProcessAsync(filter: null, stoppingToken);
                        _counterPipeline = new EventCounterPipeline(pi.Client, new EventPipeCounterPipelineSettings
                        {
                            CounterGroups = Array.Empty <EventPipeCounterGroup>(),
                            Duration = Timeout.InfiniteTimeSpan,
                            RefreshInterval = TimeSpan.FromSeconds(_options.UpdateIntervalSeconds)
                        }, metricsLogger: new[] { new MetricsLogger(_store.MetricsStore) });

                        await _counterPipeline.RunAsync(stoppingToken);
                    }
                    catch (Exception e) when(!(e is OperationCanceledException))
                    {
                        //Most likely we failed to resolve the pid. Attempt to do this again.
                        if (_counterPipeline != null)
                        {
                            await _counterPipeline.DisposeAsync();
                        }
                        await Task.Delay(5000);
                    }
                }
            }, stoppingToken));
        }
예제 #3
0
        public async Task <IStreamWithCleanup> StartTrace(IProcessInfo pi, MonitoringSourceConfiguration configuration, TimeSpan duration, CancellationToken token)
        {
            DiagnosticsMonitor monitor = new DiagnosticsMonitor(configuration);
            Stream             stream  = await monitor.ProcessEvents(pi.Client, duration, token);

            return(new StreamWithCleanup(monitor, stream));
        }
예제 #4
0
 public static ProcessModel FromProcessInfo(IProcessInfo processInfo)
 {
     return(new ProcessModel()
     {
         Pid = processInfo.Pid, Uid = processInfo.Uid
     });
 }
예제 #5
0
        private async Task <ActionResult> StartTrace(
            ProcessFilter?processFilter,
            MonitoringSourceConfiguration configuration,
            TimeSpan duration)
        {
            IProcessInfo processInfo = await _diagnosticServices.GetProcessAsync(processFilter, HttpContext.RequestAborted);

            return(new OutputStreamResult(async(outputStream, token) =>
            {
                Func <Stream, CancellationToken, Task> streamAvailable = async(Stream eventStream, CancellationToken token) =>
                {
                    //Buffer size matches FileStreamResult
                    //CONSIDER Should we allow client to change the buffer size?
                    await eventStream.CopyToAsync(outputStream, 0x10000, token);
                };

                await using EventTracePipeline pipeProcessor = new EventTracePipeline(processInfo.Client, new EventTracePipelineSettings
                {
                    Configuration = configuration,
                    Duration = duration,
                }, streamAvailable);

                await pipeProcessor.RunAsync(token);
            }, "application/octet-stream", FormattableString.Invariant($"{GetFileNameTimeStampUtcNow()}_{processInfo.ProcessId}.nettrace")));
        }
예제 #6
0
        public Task <ActionResult <IEnumerable <Models.ProcessIdentifier> > > GetProcesses()
        {
            return(this.InvokeService(async() =>
            {
                IProcessInfo defaultProcessInfo = null;
                try
                {
                    defaultProcessInfo = await _diagnosticServices.GetProcessAsync(null, HttpContext.RequestAborted);
                }
                catch (Exception)
                {
                    // Unable to locate a default process; no action required
                }

                IList <Models.ProcessIdentifier> processesIdentifiers = new List <Models.ProcessIdentifier>();
                foreach (IProcessInfo p in await _diagnosticServices.GetProcessesAsync(processFilter: null, HttpContext.RequestAborted))
                {
                    processesIdentifiers.Add(new Models.ProcessIdentifier()
                    {
                        Pid = p.EndpointInfo.ProcessId,
                        Uid = p.EndpointInfo.RuntimeInstanceCookie,
                        Name = p.ProcessName,
                        IsDefault = (defaultProcessInfo != null &&
                                     p.EndpointInfo.ProcessId == defaultProcessInfo.EndpointInfo.ProcessId &&
                                     p.EndpointInfo.RuntimeInstanceCookie == defaultProcessInfo.EndpointInfo.RuntimeInstanceCookie)
                    });
                }
                _logger.WrittenToHttpStream();
                return new ActionResult <IEnumerable <Models.ProcessIdentifier> >(processesIdentifiers);
            }, _logger));
        }
예제 #7
0
        private Task <ActionResult> StartTrace(
            IProcessInfo processInfo,
            MonitoringSourceConfiguration configuration,
            TimeSpan duration,
            string egressProvider)
        {
            string fileName = TraceUtilities.GenerateTraceFileName(processInfo.EndpointInfo);

            return(Result(
                       Utilities.ArtifactType_Trace,
                       egressProvider,
                       async(outputStream, token) =>
            {
                IDisposable operationRegistration = null;
                try
                {
                    if (_diagnosticPortOptions.Value.ConnectionMode == DiagnosticPortConnectionMode.Listen)
                    {
                        operationRegistration = _operationTrackerService.Register(processInfo.EndpointInfo);
                    }
                    await TraceUtilities.CaptureTraceAsync(null, processInfo.EndpointInfo, configuration, duration, outputStream, token);
                }
                finally
                {
                    operationRegistration?.Dispose();
                }
            },
                       fileName,
                       ContentTypes.ApplicationOctetStream,
                       processInfo.EndpointInfo));
        }
예제 #8
0
        public Task <ActionResult> Logs(
            ProcessFilter?processFilter,
            [FromQuery][Range(-1, int.MaxValue)] int durationSeconds = 30,
            [FromQuery] LogLevel level = LogLevel.Debug)
        {
            TimeSpan duration = ConvertSecondsToTimeSpan(durationSeconds);

            return(this.InvokeService(async() =>
            {
                IProcessInfo processInfo = await _diagnosticServices.GetProcessAsync(processFilter, HttpContext.RequestAborted);

                LogFormat format = ComputeLogFormat(Request.GetTypedHeaders().Accept);
                if (format == LogFormat.None)
                {
                    return this.NotAcceptable();
                }

                string contentType = (format == LogFormat.EventStream) ? ContentTypeEventStream : ContentTypeNdJson;
                string downloadName = (format == LogFormat.EventStream) ? null : FormattableString.Invariant($"{GetFileNameTimeStampUtcNow()}_{processInfo.ProcessId}.txt");

                return new OutputStreamResult(async(outputStream, token) =>
                {
                    await _diagnosticServices.StartLogs(outputStream, processInfo, duration, format, level, token);
                }, contentType, downloadName);
            }));
        }
예제 #9
0
        public Task <ActionResult> GetGcDump(
            ProcessFilter?processFilter)
        {
            return(this.InvokeService(async() =>
            {
                IProcessInfo processInfo = await _diagnosticServices.GetProcessAsync(processFilter, HttpContext.RequestAborted);

                var graph = new Graphs.MemoryGraph(50_000);

                EventGCPipelineSettings settings = new EventGCPipelineSettings
                {
                    Duration = Timeout.InfiniteTimeSpan,
                };
                await using var pipeline = new EventGCDumpPipeline(processInfo.Client, settings, graph);
                await pipeline.RunAsync(HttpContext.RequestAborted);
                var dumper = new GCHeapDump(graph);
                dumper.CreationTool = "dotnet-monitor";

                //We can't use FastSerialization directly against the Response stream because
                //the response stream size is not known.
                var stream = new MemoryStream();
                var serializer = new FastSerialization.Serializer(stream, dumper, leaveOpen: true);
                serializer.Close();

                stream.Position = 0;

                return File(stream, "application/octet-stream", FormattableString.Invariant($"{GetFileNameTimeStampUtcNow()}_{processInfo.ProcessId}.gcdump"));
            }));
        }
예제 #10
0
 public ConfigurationDefault(IProcessInfo info)
 {
     _info    = info;
     _appPath = Directory.GetCurrentDirectory();
     SetDefaults();
     CreateDirectories();
 }
예제 #11
0
        /// <inheritdoc/>
        public void AddChild(IProcessInfo processInfo)
        {
            lock (_lockObj)
            {
                if (processInfo == this)
                {
                    return;
                }

                if (processInfo == null)
                {
                    return;
                }

                if (_childrenProcessInfoList.Contains(processInfo))
                {
                    return;
                }

                _childrenProcessInfoList.Add(processInfo);

                if (processInfo.ParentProcessInfo != this)
                {
                    processInfo.ParentProcessInfo = this;
                }
            }
        }
예제 #12
0
        public Task <ActionResult> GetDump(
            ProcessFilter?processFilter,
            [FromQuery] DumpType type         = DumpType.WithHeap,
            [FromQuery] string egressProvider = null)
        {
            return(this.InvokeService(async() =>
            {
                IProcessInfo processInfo = await _diagnosticServices.GetProcessAsync(processFilter, HttpContext.RequestAborted);

                string dumpFileName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
                                      FormattableString.Invariant($"dump_{GetFileNameTimeStampUtcNow()}.dmp") :
                                      FormattableString.Invariant($"core_{GetFileNameTimeStampUtcNow()}");

                if (string.IsNullOrEmpty(egressProvider))
                {
                    Stream dumpStream = await _diagnosticServices.GetDump(processInfo, type, HttpContext.RequestAborted);

                    //Compression is done automatically by the response
                    //Chunking is done because the result has no content-length
                    return File(dumpStream, ContentTypes.ApplicationOctectStream, dumpFileName);
                }
                else
                {
                    return new EgressStreamResult(
                        token => _diagnosticServices.GetDump(processInfo, type, token),
                        egressProvider,
                        dumpFileName,
                        processInfo.EndpointInfo,
                        ContentTypes.ApplicationOctectStream);
                }
            }));
        }
예제 #13
0
        private async Task <ActionResult <T> > InvokeForProcess <T>(Func <IProcessInfo, Task <ActionResult <T> > > func, ProcessFilter?filter, string artifactType = null)
        {
            IDisposable artifactTypeRegistration = null;

            if (!string.IsNullOrEmpty(artifactType))
            {
                KeyValueLogScope artifactTypeScope = new KeyValueLogScope();
                artifactTypeScope.AddArtifactType(artifactType);
                artifactTypeRegistration = _logger.BeginScope(artifactTypeScope);
            }

            try
            {
                return(await this.InvokeService(async() =>
                {
                    IProcessInfo processInfo = await _diagnosticServices.GetProcessAsync(filter, HttpContext.RequestAborted);

                    KeyValueLogScope processInfoScope = new KeyValueLogScope();
                    processInfoScope.AddEndpointInfo(processInfo.EndpointInfo);
                    using var _ = _logger.BeginScope(processInfoScope);

                    _logger.LogDebug("Resolved target process.");

                    return await func(processInfo);
                }, _logger));
            }
            finally
            {
                artifactTypeRegistration?.Dispose();
            }
        }
예제 #14
0
        public ServiceProcess(IProcessInfo processInfo)
        {
            var filePath = processInfo.FilePath;

            if (!Path.IsPathRooted(processInfo.FilePath))
            {
                filePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), filePath);
            }

            _process = new Process()
            {
                StartInfo = new ProcessStartInfo(filePath, processInfo.Arguments)
                {
                    RedirectStandardOutput = true,
                    UseShellExecute        = false,
                    CreateNoWindow         = true
                },
                EnableRaisingEvents = true
            };
            _process.Exited             += OnExited;
            _process.OutputDataReceived += OnOutputDataReceived;

            _process.Start();
            _process.BeginOutputReadLine();
        }
예제 #15
0
 public static IEnumerable<VersionInfo> EnumerateClrVersions(IProcessInfo info)
 {
     using (var session = DebugSession.Create(info))
     {
         return session.DataTarget.ClrVersions.Select(v => v.Version);
     }
 }
예제 #16
0
        public ContentDetailPage(string PackageName)
        {
            InitializeComponent();

            this.PackageName = PackageName;

            AppInfo = DependencyService.Get <IProcessInfo>();

            PackageItem pkgitem = AppInfo.GetPackageInfo(PackageName);

            string sCacheInfo = AppInfo.GetPackageCache(PackageName);

            lblPackageName.Text    = string.Format("패키지명: {0}", pkgitem.PackageName);
            lblInstallTime.Text    = string.Format("설치일: {0}", pkgitem.InstallTime);
            lblUpdateTime.Text     = string.Format("업데이트일: {0}", pkgitem.UpdateTime);
            lblApkFilePath.Text    = string.Format("APK 경로: {0}", pkgitem.ApkFilePath);
            lblFilesize.Text       = string.Format("APK 파일 사이즈: {0}", pkgitem.Filesize);
            lblPermissionInfo.Text = string.Format("권한: {0}", pkgitem.PermissionInfo);
            lblCacheInfo.Text      = string.Format("임시파일 삭제: {0}", sCacheInfo);

            ImageSource icon = AppInfo.GetPackageIcon(pkgitem.PackageName);

            if (icon == null)
            {
                icon = "Android.png";
            }
            PackageIcon.Source = icon;

            PackageLabel.Text   = AppInfo.GetPackageLabel(pkgitem.PackageName);
            PackageVersion.Text = pkgitem.VersionName;


            NavigationPage.SetHasNavigationBar(this, false);
        }
예제 #17
0
 public Notifier(ICatServiceClient cats, IImageProvider images, IMemoryStatusProvider memory, IProcessInfo processes, IHubContext <AppHub, IAppHub> hub)
 {
     _cats      = cats;
     _images    = images;
     _memory    = memory;
     _processes = processes;
     _hub       = hub;
 }
예제 #18
0
        public ProcessMonitor()
        {
            this._processCache = new Dictionary <IntPtr, string>(512);

            // This field cannot be initialized properly in constructor
            // At the moment this code is executed the main application window is not yet initialized
            this._currentProcessInfo = new ProcessInfo(IntPtr.Zero, "");
        }
예제 #19
0
 internal static ProcessIdentifierModel FromProcessInfo(IProcessInfo processInfo)
 {
     return(new ProcessIdentifierModel()
     {
         Pid = processInfo.EndpointInfo.ProcessId,
         Uid = processInfo.EndpointInfo.RuntimeInstanceCookie
     });
 }
예제 #20
0
 public void Dispose()
 {
     this._workspace         = null;
     this._actionParameters  = null;
     this._iControllerFinder = null;
     this._iWorkspaceInfo    = null;
     this._processer         = null;
 }
예제 #21
0
        /// <summary>
        /// Creates a DebugSession against a process, optionally pausing and/or controlling the process for the lifetime of the session.
        /// </summary>
        /// <remarks>
        /// First verifies that the target process's architecture matches this process, throwing a Requires32/64BitEnvironmentException as necessary.
        /// </remarks>
        /// <param name="process"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static DebugSession Create(IProcessInfo process, DebugMode mode = DebugMode.Observe)
        {
            process.Architecture.AssertMatchesCurrent();

            // Create the data target.  This tells us the versions of CLR loaded in the target process.
            var dataTarget = AttachWithMode(process, mode);

            return new DebugSession(dataTarget);
        }
예제 #22
0
 public Process(IProcessInfo processInfo, IUser user)
 {
     Id = processInfo.Id;
     ParentProcessId = processInfo.ParentProcessId;
     Name            = processInfo.Name;
     Description     = processInfo.Description;
     Symbol          = processInfo.Symbol;
     User            = user;
 }
예제 #23
0
        /// <summary>
        /// Creates a DebugSession against a process, optionally pausing and/or controlling the process for the lifetime of the session.
        /// </summary>
        /// <remarks>
        /// First verifies that the target process's architecture matches this process, throwing a Requires32/64BitEnvironmentException as necessary.
        /// </remarks>
        /// <param name="process"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static DebugSession Create(IProcessInfo process, DebugMode mode = DebugMode.Observe)
        {
            process.Architecture.AssertMatchesCurrent();

            // Create the data target.  This tells us the versions of CLR loaded in the target process.
            var dataTarget = AttachWithMode(process, mode);

            return(new DebugSession(dataTarget));
        }
예제 #24
0
        private void OnStart()
        {
            OnStartException = null;
            try
            {
                var processStartInfo = new ProcessStartInfo(_processPath)
                {
                    Arguments = _arguments,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = _captureStdErr,
                    UseShellExecute        = false,
                    CreateNoWindow         = true,
                    WorkingDirectory       = _workingDirectory
                };

                // Copy over environment variables
                if (_environmentVariables != null)
                {
                    foreach (string key in _environmentVariables.Keys)
                    {
                        processStartInfo.EnvironmentVariables[key] = _environmentVariables[key];
                    }
                }

                // Start the process and capture it's output.
                _process = new Process
                {
                    StartInfo           = processStartInfo,
                    EnableRaisingEvents = true
                };
                _process.OutputDataReceived += (_, args) => OutputDataReceived?.Invoke(args.Data);
                if (_captureStdErr)
                {
                    _process.ErrorDataReceived += (_, args) => ErrorDataReceived?.Invoke(args.Data);
                }
                _process.Exited += (sender, args) =>
                {
                    _taskQueue.Enqueue(() =>
                    {
                        _processStateMachine.Fire(Trigger.ProcessExit);
                    });
                };
                _process.Start();
                _process.BeginOutputReadLine();
                if (_captureStdErr)
                {
                    _process.BeginErrorReadLine();
                }

                ProcessInfo = new ProcessInfo(_process);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Failed to start process {_processPath}");
                _processStateMachine.Fire(_startErrorTrigger, ex);
            }
        }
예제 #25
0
        internal void Run(IProcessInfo processInfo)
        {
            _processInfo = processInfo;

            _process.StartInfo.Arguments = processInfo.Arguments;
            _process.Start();
            _process.BeginErrorReadLine();
            _process.BeginOutputReadLine();
            _process.WaitForExit();
        }
예제 #26
0
 public Task <ActionResult> GetGcDump(
     ProcessFilter?processFilter)
 {
     return(this.InvokeService(async() =>
     {
         IProcessInfo processInfo = await _diagnosticServices.GetProcessAsync(processFilter, HttpContext.RequestAborted);
         Stream result = await _diagnosticServices.GetGcDump(processInfo, this.HttpContext.RequestAborted);
         return File(result, "application/octet-stream", FormattableString.Invariant($"{GetFileNameTimeStampUtcNow()}_{processInfo.ProcessId}.gcdump"));
     }));
 }
예제 #27
0
        private async Task <StreamWithCleanupResult> StartTrace(
            ProcessFilter?processFilter,
            MonitoringSourceConfiguration configuration,
            TimeSpan duration)
        {
            IProcessInfo processInfo = await _diagnosticServices.GetProcessAsync(processFilter, HttpContext.RequestAborted);

            IStreamWithCleanup result = await _diagnosticServices.StartTrace(processInfo, configuration, duration, this.HttpContext.RequestAborted);

            return(new StreamWithCleanupResult(result, "application/octet-stream", FormattableString.Invariant($"{GetFileNameTimeStampUtcNow()}_{processInfo.ProcessId}.nettrace")));
        }
        private void NAppendAndTryStartProcessInfoWithDevices(IProcessInfo processInfo)
        {
            foreach (var device in processInfo.Devices)
            {
                _processesInfoByDevicesDict[device] = processInfo;
            }

            processInfo.OnFinish += OnFinishProcessWithDevicesHandler;

            processInfo.Start();
        }
        private bool NTryAppendProcessInfo(IProcessInfo processInfo)
        {
            if (_processesInfoList.Contains(processInfo))
            {
                return(false);
            }

            _processesInfoList.Add(processInfo);

            return(true);
        }
        /// <inheritdoc/>
        public override void AppendProcessInfo(IProcessInfo processInfo)
        {
            lock (_processLockObj)
            {
#if DEBUG
                //Log($"processInfo = {processInfo}");
#endif

                NTryAppendProcessInfo(processInfo);
            }
        }
예제 #31
0
 public static ProcessModel FromProcessInfo(IProcessInfo processInfo)
 {
     return(new ProcessModel()
     {
         CommandLine = processInfo.CommandLine,
         Name = processInfo.ProcessName,
         OperatingSystem = processInfo.OperatingSystem,
         ProcessArchitecture = processInfo.ProcessArchitecture,
         Pid = processInfo.ProcessId,
         Uid = processInfo.RuntimeInstanceCookie
     });
 }
예제 #32
0
 internal static ProcessInfo FromProcessInfo(IProcessInfo processInfo)
 {
     return(new ProcessInfo()
     {
         CommandLine = processInfo.CommandLine,
         Name = processInfo.ProcessName,
         OperatingSystem = processInfo.OperatingSystem,
         ProcessArchitecture = processInfo.ProcessArchitecture,
         Pid = processInfo.EndpointInfo.ProcessId,
         Uid = processInfo.EndpointInfo.RuntimeInstanceCookie
     });
 }
예제 #33
0
        private static DataTarget AttachWithMode(IProcessInfo process, DebugMode mode)
        {
            switch(mode)
            {
                case DebugMode.Snapshot: return DataTarget.AttachToProcess(process.Pid, 0, AttachFlag.NonInvasive);

                // This takes some time. Specifying a timeout of 0 appears to always fail.
                case DebugMode.Control: return DataTarget.AttachToProcess(process.Pid, 5000, AttachFlag.Invasive);

                case DebugMode.Observe:
                default:
                    return DataTarget.AttachToProcess(process.Pid, 0, AttachFlag.Passive);
            }
        }
예제 #34
0
 private string DescribeCLRVersions(IProcessInfo process)
 {
     try
     {
         var versions = ProcessFinder.EnumerateClrVersions(process).Select(v => $"{v.Major}.{v.Minor}").Distinct().ToArray();
         if(!versions.Any()) return "-";
         return String.Join(", ", versions);
     }
     catch(Requires32BitEnvironmentException)
     {
         return "(unknown, 32-bit)";
     }
     catch(Requires64BitEnvironmentException)
     {
         return "(unknown, 64-bit)";
     }
 }
예제 #35
0
 public IDebugJob CreateJob(IProcessInfo process)
 {
     return new DumpStacksJob(process, ActivelyAttachToProcess);
 }
예제 #36
0
 public IDebugJob CreateJob(IProcessInfo process)
 {
     return new DumpHeapJob(process);
 }
예제 #37
0
 public DumpHeapJob(IProcessInfo process)
 {
     this.process = process;
 }
예제 #38
0
파일: IProcess.cs 프로젝트: ReubenBond/Yams
 public ProcessExitedArgs(IProcessInfo processInfo, string message)
 {
     ProcessInfo = processInfo;
     Message = message;
 }