CPU profiling a Cocoa app in the field - macos

I have a user complaining that my app is taking a lot of CPU time when it should be idle. This is a Cocoa app on Mac OS Leopard. What I would love to do is have a background thread periodically grab stack traces of the main thread and log them. Alternatively, if I could have him run a command line program to grab all the threads' stacks (or better yet, a call graph with CPU profiling info), he could do that and send me the results. I know there's CPU profiling built into XCode, but this problem is only reproducible on the user's machine, so XCode is not an option (I don't want to ask him to install it).
I can't find a command line tool that would dump stack traces on OSX, nor can I find an API for accessing other threads' stacks. I guess GDB could do it, but that would be really hard to explain to a user.

Tell your user to launch Activity Monitor (in /Applications/Utilities). In Activity Monitor, your user can select the row corresponding to your application and press the "Sample" button in the toolbar. This will take a 10-second sample of your app. He can then save this to disk and email the file to you.
Edit: If you want a command-line version of this, look at /usr/bin/sample. It does effectively the same thing, though Activity Monitor should be a lot easier for an end-user to use.

Related

Read Performance counter in Mac from terminal

I would like to know how to get
performance monitoring counter measurements on a Mac. With Linux, we
can use the "perf stat" command to get measurements. With a Mac it's
harder. Specifically, I would like to know how I can get the number of
branch mispredictions and the number of branches executed for a
program running from the command line, preferably without recompiling
the program. I have done some Googling but what I need is a solution;
if you can show me how you brought up a terminal, typed in some
command (maybe using some tool you downloaded), and got the number of
mispredictions for, say /bin/ls, that would be great.
Official macOS tool to work with profiling, both based on software events and on hardware events (performance counters), is Instruments tool - https://help.apple.com/instruments/mac/current/. It seems to be part of XCode development tools.
This tool have some limited variants to collect profiles from command-line mode, check https://help.apple.com/instruments/mac/current/#/devb14ffaa5
https://help.apple.com/instruments/mac/current/#/devba105ecc
Launch Instruments from the command line
You can use the open command to launch any app in OS X via Terminal,
including Instruments.
Launch Terminal (in /Applications/Utilities/).
Run the following command:
open /Applications/Xcode.app/Contents/Applications/Instruments.app
The Instruments app launches.
Note: You can also use either of two command-line utilities to profile
an app without actually displaying the Instruments user interface.
instruments — This utility profiles an app using a specified template. The results can be saved to a file and then manually opened
in the main Instruments app for viewing and analysis. To learn more,
go to Profile with the instruments command-line tool.
To get IPC or branches, use GUI to create profile with usage of counters usage (1 or 2) and save it as template, and then use CLI tool instruments to collect trace data. Trace file can be viewed with Instruments GUI; there was incomplete attempt to decode that files.
The page https://medium.com/#pavelkucera/counting-branch-mispredictions-on-macos-7397ae8c5b51 also lists another variant to work with hardware counters on macOS, the https://github.com/opcm/pcm project:
You first have to build the tool, but then it is easy to use:
run pmu-query.py
enter “BR_INST_RETIRED.NOT_TAKEN”, the result should be similar to: cpu/umask=0x10,event=0xC4,name=BR_INST_RETIRED.NOT_TAKEN/
run ./pcm-core.x -e event where “event” stands for the result from the previous step
This gives you continuous results for all the running processes. Find
info on how to profile a single process in ./pmc-core.x --help
The good news is that results are easily readable as they can be
output as csv file. The bad news is that profiling a single process
still includes activity from other processes.

What file access woke the sleeping disk in Windows?

Every now and then, my sleeping disk wakes up, does what sounds like a single read, and then sits idle until it falls asleep again. Sometimes a program that I am using completely freezes for about 10 seconds while the disk spins up, even though that program doesn't seem to need to read from that drive.
Is there an api for listening to file accesses as they happen, or similar, so I can figure out what is read from that drive, so I can move it? If not on Windows, can I do this on Linux?
This is also applicable for figuring out what files/folders a program is accessing in general, so I wouldn't say it only applies to my very narrow problem.
There's a simple tool called What's My Computer Doing? that you can use to get a quick idea of what's causing activity on your computer.
Install and run it, and leave it running in the background. Once you use this tool to narrow down which process is causing the disk activity, you'll want a more comprehensive tool. I use Process Monitor from Sysinternals/Microsoft.
It can be a bit daunting at first, but that's mainly because it is so powerful. It can also alter the behavior of the computer. When it's running, it backs up the huge quantity of data it collects to the disk. So that's why I suggest using the 'What's My Computer Doing?' tool first. Once you know which process is generating the disk access you can add a new filter rule (keep all the defaults, as they mask out a bunch of normal system processes) and select "Process Name" "is" "process_name", or select "PID" "is" "actual_PID".
There are plenty of tutorials like this one that can help you get started with Process Monitor.

osx - What's the best way to "pause" a 3rd-party macOS app during launch in Swift?

I've been playing around with NSRunningApplication in Swift 3, and I've come up with a few questions.
What's the best way to "pause" an application while it's launching. Don't quit it, but don't let it launch completely either. Just keep the icon bouncing in the dock (i.e. "freeze" the launch) for some arbitrary time. After that time, if I decide I want to quit the app after all, I can do NSRunningApplication(withBundleIdentifier: "xyz").terminate() or .forceTerminate(), and I can confirm with .isTerminated(). Otherwise, I can just "unfreeze" the app and let it finish launching.
What's the least power-hungry way of checking constantly for an app launch? I could just schedule a Timer to check every half-second or so, but I believe that hogs a fair amount of memory. Can I set a listener or notification to check for a 3rd-party app launch? (i.e. to run a function every time the Notes app changes isTerminated state).
Thanks!
You can't reliably target another process and control it from Swift (or any other User-mode program), as you really need to do that in the kernel, with a kernel extension (Kext).
Apple's official framework for this is the Kernel Authorization framework (KAuth). Using the File Operation Scope (described in the documentation), a kernel extension will be notified of various operations, including a program's execution and can allow or deny its access.
A working example of its usage can be seen in the open source code of Google Santa, which they use to manage their own employees' computers. As its documentation states:
It consists of a kernel extension that monitors for executions, a userland daemon that makes execution decisions based on the contents of a SQLite database, a GUI agent that notifies the user in case of a block decision and a command-line utility for managing the system and synchronizing the database with a server.

Background process shows as "not responding" on OS X

I'm attempting to resolve this weird problem with our OS X application.
As part of it's normal operation, it starts a long running background process — specifically a Web server, written in node.js.
After some time running, the background process shows up in the activity monitor as "Not Responding".
It's still functioning normally though, responding to requests from the web browser and not eating a high percentage of CPU or anything.
I would like to understand what exactly might be causing this status to be displayed, since it's not even a GUI application in the first place. What exactly does OS X use to determine if a command line application is not responding, if it doesn't have a Cocoa event loop?
Is it possible to flag it somehow as a background process so that the system does not query it for responses?
Thanks in advance.
Update: Just checked, the same seems to happen when launching the task from the command line. What makes a background app "Not respond" on the activity monitor?
Okay so as sergio pointed out in his comment, it was indeed something specific to Node.JS.
The dev responsible for Node.JS portion of our app was able to trace back the source of the problem to the usage of the process.title property in Node.JS.
It looks like the implementation of process.title in libuv does a lot of Core Foundation tricks to set the process title, so these are probably getting the process flagged as a GUI app by whatever heuristics the Activity Monitor uses to tell Cocoa apps apart from CLI apps.
We have filed a bug report on libuv about this, but for now we're skipping process.title as simply setting it causes the server to show up as "not responding" on the Activity Monitor after a couple minutes.
Update: This is now fixed in libuv as of this commit. It still hasn't propagated to a node release yet.
According to Apple's Process Manager Reference, GetCurrentProcess, GetFrontProcess (et al.) are deprecated in OS X 10.9 and causes the "not responding" issue in Activity Monitor (my observation).

Sample a process on Mac OS X from a C/C++ program

The Sample Process feature in Activity Monitor is quite a useful thing. However, I need to do the same thing (take samples) of a certain process from another running process (C/C++) or a command line.
Is there any way to do this? I have been googling for this since a few days without any luck.
There is a command-line utility sample.
Example:
sample Safari -file /dev/stdout
It will get exactly the same output with Activity Monitor.
There are some few commandsline application that come in handy: sample and top.
If you want to write your own program, you can use the sysctl system call to get such information. However, it's quite tedious.
I would recommend installing procfs file system (built with MacFUSE). This would create a new "directory" at /proc that contains a lot of useful information for each application (e.g. memory usage, cpu usage, locks, opened files, sockets, threads, etc). The site gives a sample of how it can be accessed. Then you can simply script your access to those files.

Resources