简体   繁体   中英

How to profile from the command line on Mac OS X?

I'm trying to profile C/C++ code on Mac OS X using command line tools, I use -pg option with gcc to run gprof on Linux, but I can't seem to find the gprof on Mac even though I have a description in this page: Additional Command-Line Tools (iOS) or Additional Command-Line Tools (mac) .

gprof:Produces execution profiles based on an execution analysis of a program.

I installed command line tools, so other command line tools such as otool and atos are available. I googled to find this page ( https://apple.stackexchange.com/questions/154289/installing-gprof-on-mac ) that says gprof is not supported, but I'm not sure when I have an Apple doc describing the tool; anyway, I tried to use brew to download gprof , but it didn't work.

I found Attempting to use gprof with C++ code on a Mac , but I have no output with instruments -t . I also found Profiling c++ on mac os x , but I don't want to open Instruments, as I would like to automate some of the processes and try to keep cross platform system.

  • How to use gprof on Mac OS X? I use OS X 10.10.
  • How can I profile from the command line, with or without gprof ?

It is strange to hear that there is no gprof profiler for OSX. OSX is certified unix and the profiler of unix is gprof (based on profil syscall/library function which is there: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/profil.2.html ).

There are problems with GNU gprof (part of binutils) according to https://apple.stackexchange.com/questions/154289/installing-gprof-on-mac (2014; thanks to Sreekanth Nagareddy user - deleted answer), brew install -v binutils "*** This configuration is not supported in the following subdirectories: .. ld gas gprof"; OSX is not listed in GNU gprof readme: http://code.metager.de/source/xref/gnu/src/gprof/README (2012) in "Supported Platforms" (only OSF/1, SunOS, Solaris, HP-UX listed; I think it should work on Hurd and works on Linuxes).

But there is also BSD implementation of gprof (check https://en.wikipedia.org/wiki/gprof for history and references). Didn't try to get it running on OSX (have no OSX nor bitten apples newer than 1995 desktop&notebook).

There are different sources of BSD gprof, for example, FreeBSD's version ( https://github.com/freebsd/freebsd/tree/af3e10e5a78d3af8cef6088748978c6c612757f0/usr.bin/gprof ) or ancient 4.3BSD original http://www.retro11.de/ouxr/43bsd/usr/src/ucb/gprof/ . Both variants have no support of Mach-O format used in OSX.

There is even Apple's own gprof (based on BSD gprof from NetBSD/OpenBSD) in cctools of Darwin (Darwin is UNIX part both kernel and user-space of OSX; it is/was/will open-source): https://github.com/LeoTestard/Darwin/tree/master/cctools/gprof / https://github.com/darwin-on-arm/darwin-sdk/tree/master/cctools/gprof / http://src.gnu-darwin.org/src/usr.bin/gprof/gprof.c.html (some older mix of FreeBSD code and GNU crazy ideas of freedom).

The availability of gprof may depend on exact OSX version or Xcode version/packages; there were gprof for 10.6.1, according to http://louise.hu/poet/gprof-on-osx/ or on some version from 2012 - https://rachelbythebay.com/w/2012/09/14/mac/ or even in 2001: http://lists.apple.com/archives/darwin-development/2001/Apr/msg00617.html

There is variant of using instruments (part of Xcode Tools?) in command-line, don't know how exactly, but know that instruments is modern and feature-rich profiler.

There is also iprofiler command-line interface to collect profiles for Instruments.app , just noted man page of it https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/iprofiler.1.html (part of Xcode Tools version 5.0; manpage from legacy part of site).

There are third-party profilers, declared to support OSX. I know two of them: valgrind and gperftools (google-perftools).

valgrind is not a profiler; it is a (slow) dynamic instrumentation platform with many tools built on top of it. It includes two tools, capable of profiling: callgrind and cachegrind . Valgrind and both tools are not native profiler, they do not profile application as it will run on real cpu in real life. Instead, valgrind executes program on the virtual machine and callgrind/cachegrind instruments machine code with counters.

callgrind ( http://valgrind.org/docs/manual/cl-manual.html ) uses counter per linear block of instructions to count "how many times every instruction will be executed" ("Ir" event, used to get profile - sort functions by percent of time used); it also records calls/returns to build callgraph. "Ir" event count is correct to get instruction execution counts (it may also emulate branch prediction); but it can't be used to estimate real running time. Real cpu (high performance cpus called superscalar; out-of-order cpus are superscalar too) able to execute more than one instruction per cpu clock cycle; and it is also often incapable of executing any instruction because they may want some data to be started (data from far cache or from memory or from syscall or from other high-latency instruction; or cpu mispredicted branch leads to instruction address not yet read/decoded). Most progressive cpus may even not execute some commands (some can execute up to 8 " nop "s per cycle, several Intel's Sandy/Ivy Bridges and newer will not spend any time on " xor eax,eax " to write zero into register; they just remap next register usage to zeroed physical register). callgrind has typical 10-20 slowdown on profiling run compared to real run on hardware CPU.

Cachegrind implements same instrumentation as callgrind ("Ir", branches), but also can emulate cache hierarchy (cache loads/stores/misses events). And it is slower than callgrind.

Output from callgrind and cachegrind can be viewed with GUI tool kcachegrind ( http://kcachegrind.sourceforge.net/ , it may work in OS) or in command-line tool callgrind_annotate .

Other tool is gperftools (google-perftools, https://github.com/gperftools/gperftools ), which run the program on real CPU. To use it, install it with homebrew, then link the program with libprofiler (add -Lpath_to_installed_gperftools -lprofiler ) and run with CPUPROFILE environment variable set to some filename ( CPUPROFILE=profile01 ./the_program). It will profile the program using interval timer ( CPUPROFILE=profile01 ./the_program). It will profile the program using interval timer ( setitimer ) and output profiling data to the filename, defined in CPUPROFILE env var. Then you can view profile data in command-line or with svg/web browser using env var. Then you can view profile data in command-line or with svg/web browser using pprof perl script from gperftools ( pprof ./the_program profile01`).

How can I profile from the command line, with or without gprof?

This seems to work in MacOS Monterey 12.5

xctrace record --output <path/to/folder> --template "Time Profiler" --time-limit 10s --attach <pid>

The results will be a.trace file which you can open with

open path/to/name-of-file.trace

If you want to launch the app instead of attach to an existing app then use --launch -- command arugments . --launch must be the last argument

for more info

man xctrace

On a sperate question of mine (CrazyPython), I was able to use gperftools ( pprof ) with the assistance of @osgx. Here is the question and here is the GitHub gist of the script. For your convenience, here is the script inline:

#!/usr/bin/env bash
# Licensed under the Unlicense. Full text at (http://unlicense.org/) - CrazyPython
g++ -std=c++11 $1 -o ./.executables/profiler/$(basename $1 .cpp) -g -O -lprofiler
echo "Finished compiling + linking"
CPUPROFILE=$1.out ./.executables/profiler/$(basename $1 .cpp)
./.executables/profiler/$(basename $1 .cpp)
pprof ./.executables/profiler/$(basename $1 .cpp) $1.out

Warning: I tried to clean it up a bit. It likely contains quite a few unnecessary options.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM