Jason Sundram
Jason Sundram

Reputation: 12524

Iterate over pgrep results

Context: Dropbox periodically takes 100% of my CPU, making my laptop borderline unusable. The tool cputhrottle makes it possible to limit the amount of CPU that any given process (PID) uses.

Dropbox actually has several PIDs on my machine, and I'd like to use bash to loop over them.

The closest I've gotten to a one-liner is:

pgrep -f Dropbox | xargs -I{} cputhrottle {} 30 &

This has two problems:

  1. cputhrottle throws an error (which it doesn't when called directly): 1libc++abi.dylib: terminating with uncaught exception of type Process::ManipulatorException: Error on task_for_pid of pid 720, res = 5

  2. backgrounding the processes doesn't seem to work (the first one fails and the process is still in the foreground. I'm not sure if this is a consequence of 1 or a different problem.

I'm not sure if I should give up on a one-liner, but I am not sure how to make the following for-loop work:

for i in $(pgrep -f Dropbox); do 
    cputhrottle $i 30 &
done

which gives syntax error near unexpected token ';'

Upvotes: 2

Views: 692

Answers (1)

Swiss
Swiss

Reputation: 5829

Apple has changed their OS security model in a way that breaks the task_for_pid functionality which cputhrottle relies on. The change appears to break cputhrottle, and I suspect that cputhrottle isn't actually working when you manually call it either.

Apple really seems to want to discourage the use of task_for_pid as well, since it's completely undocumented in the Apple API docs at the moment, and trying to find any reference to it in any documentation anywhere is also very difficult. I have no idea why the author of cputhrottle chose to use this specific function to build his program around.

If you really want to, you may be able to rebuild cputhrottle to have the correct security permissions.

Another solution here would be to find another program to use. Maybe just use the built-in nice functionality?

References to OS API security change:

http://os-tres.net/blog/2010/02/17/mac-os-x-and-task-for-pid-mach-call/ https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/RuntimeProtections/RuntimeProtections.html

Source for the task_for_pid Mach trap, if you're curious:

https://github.com/apple/darwin-xnu/blob/a449c6a3b8014d9406c2ddbdc81795da24aa7443/bsd/vm/vm_unix.c#L783-L929

To better explain the error message you're seeing as well, exit code 5 is actually KERN_FAILURE, which is a generic catch-all to indicate the called kernel function did not succeed. In this case, probably because of invalid security permissions.

https://github.com/apple/darwin-xnu/blob/0a798f6738bc1db01281fc08ae024145e84df927/osfmk/mach/kern_return.h#L94-L96

Upvotes: 3

Related Questions