Runtime: Process Property TotalProcessorTime throws InvalidOperationException exception on macOS

Created on 20 May 2020  路  9Comments  路  Source: dotnet/runtime

Description

I'm trying to get information about current running processes. And I'm getting InvalidOperationException exception accessing TotalProcessorTime Process property.
Please see the configuration and the error message below.

Here is my example code (I've created a test console app here)

        static void Main(string[] args)
        {
            var processes = Process.GetProcesses();

            try
            {
                var timeInformationToBeUsed = processes.Select(x => x.TotalProcessorTime).ToList();
            }
            catch (Exception e)
            {
                Console.WriteLine($"Hi dear, I'm {e.GetType()}!");
                Console.WriteLine("Why am I happening? :P");
                Console.WriteLine($"Message: {e.Message}");
                Console.WriteLine($"StackTrace: {e.StackTrace}");
            }

            Console.ReadKey();
        }

Configuration

SDK: 3.1.101
Framework: .NETCoreApp v3.1 (I've tried v2.1 too - the same result)
OS: macOS Catalina Version 10.15.4

Not sure if it's possible to reproduce it on other configurations.

Regression?

I've tried .NETCoreApp v2.1 too - the same result

Other information

Message: Failed to set or retrieve rusage information. See the error code for OS-specific error information.

StackTrace:
at Interop.libproc.proc_pid_rusage(Int32 pid)
at System.Diagnostics.Process.get_TotalProcessorTime()
at TotalProcessorTimeOsxProblem.Program.<>c.

b__0_0(Process x) in /Projects/TotalProcessorTimeOsxProblem/TotalProcessorTimeOsxProblem/Program.cs:line 15
at System.Linq.Enumerable.SelectArrayIterator2.ToList() at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
at TotalProcessorTimeOsxProblem.Program.Main(String[] args) in /Projects/TotalProcessorTimeOsxProblem/TotalProcessorTimeOsxProblem/Program.cs:line 15

So the exception is happening in Process.OSX.cs

        public TimeSpan TotalProcessorTime
        {
            get
            {
                EnsureState(State.HaveNonExitedId);
                Interop.libproc.rusage_info_v3 info = Interop.libproc.proc_pid_rusage(_processId);
                return new TimeSpan(Convert.ToInt64((info.ri_system_time + info.ri_user_time) / NanosecondsTo100NanosecondsFactor));
            }
        }
area-System.Diagnostics.Process

Most helpful comment

I don't know the cause of your problem, but I think we'd welcome a PR to include the error code in the exception at least - the message suggests to look at it but doesn't include it!
```c#
// Get the PIDs rusage info
int result = proc_pid_rusage(pid, RUSAGE_INFO_V3, &info);
if (result < 0)
{
throw new InvalidOperationException(SR.RUsageFailure);
}

        return info;

```

All 9 comments

Tagging subscribers to this area: @eiriktsarpalis
Notify danmosemsft if you want to be subscribed.

same problem with UserProcessorTime and PrivilegedProcessorTime

Interop.libproc.rusage_info_v3 info = Interop.libproc.proc_pid_rusage(_processId);

I don't know the cause of your problem, but I think we'd welcome a PR to include the error code in the exception at least - the message suggests to look at it but doesn't include it!
```c#
// Get the PIDs rusage info
int result = proc_pid_rusage(pid, RUSAGE_INFO_V3, &info);
if (result < 0)
{
throw new InvalidOperationException(SR.RUsageFailure);
}

        return info;

```

Ideally it could append the actual message from the system corresponding to the code. That might be done with Interop.Sys.StrError(result)

on Windows it throws another exception:
System.ComponentModel.Win32Exception

Message: Access is denied.
StackTrace:    at System.Diagnostics.ProcessManager.OpenProcess(Int32 processId, Int32 access, Boolean throwIfExited)
   at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
   at System.Diagnostics.Process.GetProcessTimes()
   at System.Diagnostics.Process.get_TotalProcessorTime()
   at TotalProcessorTimeOsxProblem.Program.<>c.<Main>b__0_0(Process x) in C:\Users\xxx\Documents\TotalProcessorTimeOsxProblem-master\TotalProcessorTimeOsxProblem-master\TotalProcessorTimeOsxProblem\Program.cs:line 15
   at System.Linq.Enumerable.SelectArrayIterator`2.ToList()
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at TotalProcessorTimeOsxProblem.Program.Main(String[] args) in C:\Users\xxx\Documents\TotalProcessorTimeOsxProblem-master\TotalProcessorTimeOsxProblem-master\TotalProcessorTimeOsxProblem\Program.cs:line 15

so looks like it might be some system processes which are not accessible

likely a different cause : need that Mac error code

I've updated my test project a bit to get more info about the processes which I can't get an access to.

All of them have empty ProcessName. So I guess it might mean all of them are some system processes.

@DmitryKhryukin any interest in offering a PR to add such code?

@danmosemsft yep, I'll have a look soon. cheers

Was this page helpful?
0 / 5 - 0 ratings