GPROF(1)
โจ GPROF(1) โจ GNU ๐
๐ซถ NAME ๐ซถ
okay so the name is just gprof, and it's all about displaying call graph profile data ๐โจ
๐ธ SYNOPSIS ๐ธ
okay bestie, here's the whole big list of ways you can call it ๐
gprof [ -[abcDhilLrsTvwxyz] ] [ -[ABCeEfFJnNOpPqQRStZ][name] ]
[ -I dirs ] [ -d[num] ] [ -k from/to ]
[ -m min-count ] [ -R map_file ] [ -t table-length ]
[ --[no-]annotated-source[=name] ]
[ --[no-]exec-counts[=name] ]
[ --[no-]flat-profile[=name] ] [ --[no-]graph[=name] ]
[ --[no-]time=name] [ --all-lines ] [ --brief ]
[ --debug[=level] ] [ --function-ordering ]
[ --file-ordering map_file ] [ --directory-path=dirs ]
[ --display-unused-functions ] [ --file-format=name ]
[ --file-info ] [ --help ] [ --line ] [ --inline-file-names ]
[ --min-count=n ] [ --no-static ] [ --print-path ]
[ --separate-files ] [ --static-call-graph ] [ --sum ]
[ --table-length=len ] [ --traditional ] [ --version ]
[ --width=n ] [ --ignore-non-functions ]
[ --demangle[=STYLE] ] [ --no-demangle ]
[--external-symbol-table=name]
[ image-file ] [ profile-file ... ]
๐ฆ DESCRIPTION ๐ฆ
okay so gprof is literally the tool that makes a execution profile for C, Pascal, or Fortran77 programs ๐
it's giving performance detective ๐ every routine's cost gets folded into the profile of whoever called it, so nothing gets left out ๐
the profile data comes from the call graph profile file (gmon.out is the default) ๐ that file gets created by programs compiled with the -pg option of cc, pc, and f77. the -pg option also links in versions of the library routines that were compiled for profiling, so the library stuff shows up too โจ
then gprof reads the given object file (the default is a.out) and matches up its symbol table with the call graph profile from gmon.out ๐งฉ and if you give it more than one profile file, the output shows the sum of the profile info from all of them. main character energy, collecting all the receipts ๐งพ๐
โ ๏ธ bestie, real talk: if you compile your binaries with gcc 2.95.x or 3.0, you may need to add the-fprofile-arcsto the compile command line so the call graphs actually get stored properly ingmon.out. otherwise the data can be incomplete, and nobody wants that ๐ญ
okay now the math part ๐ค gprof works out how much time gets spent in each routine. next, those times get propagated along the edges of the call graph. cycles get discovered, and any calls into a cycle end up sharing the time of that cycle. it's like the whole thing is passing the tea around ๐ต
there are a few different outputs you can get from the analysis:
- the flat profile ๐ shows how much time your program spent in each function, and how many times that function got called. if you just want to know which functions are burning the most cycles, this is the one, and it says it concisely ๐
- the call graph ๐ธ๏ธ shows, for each function, which functions called it, which other functions it called, and how many times. it also estimates how much time got spent in the subroutines of each function. this is where you can spot calls that use a lot of time and think about getting rid of them ๐
- the annotated source listing ๐ is a copy of your program's source code, labeled with the number of times each line was executed. so cute, you can see exactly which lines are the hot ones ๐ฅ
๐ OPTIONS ๐
these options decide which of the several output formats gprof should produce ๐
a lot of these options can take an optional symspec to pick which functions get included or excluded ๐ฏ and you can repeat these options with different symspecs to include or exclude whole sets of symbols. it's giving customisable ๐
heads up: if you specify any of these options, it overrides the default (-p -q), which would normally print a flat profile and call graph analysis for all functions. so you're basically taking the wheel ๐โจ
-A[symspec],--annotated-source[=symspec]โ this one makesgprofprint annotated source code ๐ if you give it a symspec, it only prints output for the matching symbols ๐ฏ-b,--briefโ with this,gprofskips the verbose blurbs that explain what all the fields in the tables mean ๐ super useful if you're printing the output or you're just tired of seeing those blurbs-Bโ this makesgprofprint the call graph analysis ๐ธ๏ธ-C[symspec],--exec-counts[=symspec]โ this prints a tally of functions and how many times each one was called ๐งฎ if you add a symspec, the tally only shows the matching symbols ๐ฏ
if your profile data file has basic-block count records, then pairing -l with -C makes it tally and display the basic-block execution counts too ๐ค
-i,--file-infoโ this shows summary info about the profile data file(s) and then exits ๐ you get the number of histogram, call graph, and basic-block count records ๐-I dirs,--directory-path=dirsโ this gives a list of search directories wheregprofcan find source files ๐ you can also use the environment variableGPROF_PATHto pass that same info along ๐ง it's mostly used for annotated source output-J[symspec],--no-annotated-source[=symspec]โ the opposite energy ๐ โโ๏ธ this makesgprofnot print annotated source code. if you add a symspec,gprofstill prints annotated source, but leaves out the matching symbols ๐ซ-L,--print-pathโ normally the source filenames get printed with the path part hidden ๐ with-L, you get the full pathname instead ๐บ๏ธ it comes from the symbolic debugging info in the image file and is relative to the directory where the compiler was invoked-p[symspec],--flat-profile[=symspec]โ this makesgprofprint a flat profile ๐ with a symspec, you only get a flat profile for the matching symbols ๐ฏ-P[symspec],--no-flat-profile[=symspec]โ this one suppresses the flat profile ๐ซ if you add a symspec,gprofprints a flat profile but excludes the matching symbols ๐-q[symspec],--graph[=symspec]โ this makesgprofprint the call graph analysis ๐ธ๏ธ with a symspec, you only get the call graph for matching symbols and their children ๐ถ-Q[symspec],--no-graph[=symspec]โ this suppresses the call graph ๐ซ with a symspec,gprofprints a call graph but excludes the matching symbols ๐-t,--table-length=numโ this lists the num most active source lines in each source file when source annotation is turned on ๐ฅ the default is 10 ๐-y,--separate-filesโ this one only affects annotated source output ๐ normallygprofprints annotated source files to standard-output. with this option, the annotated source for a file namedpath/filenamegets generated in the filefilename-ann๐
โ ๏ธ if the underlying file system would truncatefilename-annso it overwrites the original filename,gprofwrites the annotated source tofilename.anninstead. if the original file name has an extension, that extension gets replaced with.ann๐ฌ
-Z[symspec],--no-exec-counts[=symspec]โ this stopsgproffrom printing the tally of functions and how many times each was called ๐ with a symspec, the tally still prints, but the matching symbols get excluded ๐ซถ-r,--function-orderingโ this makesgprofprint a suggested function ordering for your program, based on the profiling data ๐ง the ordering may improve paging, tlb and cache behavior, but only on systems that support arbitrary ordering of functions in an executable ๐
the exact details of how to force the linker to place functions in a particular order are system dependent and out of scope for this manual ๐
-R map_file,--file-ordering map_fileโ this prints a suggested.olink line ordering for your program, based on profiling data ๐งฉ it can help paging, tlb and cache behavior on systems that don't support arbitrary ordering of functions in an executable ๐
bestie, it's highly recommended to use the -a argument with this option ๐
the map_file is a pathname to a file that maps function names to object files ๐บ๏ธ the format is similar to the output of the program nm, kinda like this:
c-parse.o:00000000 T yyparse
c-parse.o:00000004 C yyerrflag
c-lang.o:00000000 T maybe_objc_method_name
c-lang.o:00000000 T print_lang_statistics
c-lang.o:00000000 T recognize_objc_keyword
c-decl.o:00000000 T print_lang_identifier
c-decl.o:00000000 T print_lang_type
...
to make a map_file with GNU nm, type a command like nm --extern-only --defined-only -v --print-file-name program-name ๐ปโจ
-T,--traditionalโ this makesgprofprint its output in "traditional" BSD style ๐-w width,--width=widthโ this sets the width of the output lines to width ๐ right now it's only used when printing the function index at the bottom of the call graph ๐ฆ-x,--all-linesโ another annotated-source-only option ๐ by default, only the lines at the beginning of a basic-block get annotated. with this one, every line in a basic-block gets annotated by repeating the annotation for the first line ๐ it works kinda liketcov's-a๐ค--demangle[=style],--no-demangleโ these control whether C++ symbol names get demangled when printing output ๐ the default is to demangle symbols, and--no-demangleturns that off. different compilers have different mangling styles, so the optional style argument lets you pick the one that matches your compiler ๐ธ
๐ท Analysis Options ๐ท
-a,--no-staticโ this stopsgproffrom printing statically declared (private) functions ๐ซฅ these are the functions whose names aren't listed as global, and which aren't visible outside the file, function, or block where they were defined. the time spent in these functions, and the calls to and from them, all get attributed to the function that was loaded directly before it in the executable file ๐งพ this option affects both the flat profile and the call graph ๐
to be continued in part 2, bestie ๐โจ
-c,--static-call-graphโ okay so this one is a sneaky little heuristic ๐ต๏ธโโ๏ธ. It pokes around the text space of the object file and spots function calls in the binary machine code. Normal call graph records only show up when a function actually gets entered, so this option finds children that could have been called but never were. Calls to functions that weren't compiled with profiling enabled get caught too, but only if they have symbol table entries. Calls into dynamic library routines are usually invisible to it ๐. Parents or children found this way show up in the call graph with a call count of 0 ๐ .-D,--ignore-non-functionsโ this one tellsgprofto ignore any symbols that aren't known to be functions ๐งน. On systems that support it (Solaris and HPUX, for example), you get more accurate profile data โจ.-k from/toโ lets you delete arcs from the call graph. Any arc going from symbols matching symspecfromto symbols matching symspectogets yeeted ๐๏ธ.-l,--lineโ turns on line-by-line profiling ๐, so histogram hits get charged to individual source lines instead of whole functions. Heads up: this only works with programs compiled by older versions of thegcccompiler. Newergccversions are built to work with thegcovtool instead ๐ โโ๏ธ. If the program was compiled with basic-block counting enabled, this option also tells you how many times each line ran ๐ข. It's super helpful for finding where inside a huge function the time is going, but ngl it makesgprofway slower and makes statistical inaccuracies louder ๐ญ.--inline-file-namesโ prints the source file after each symbol in both the flat profile and the call graph ๐. If you pair it with the-Loption, you get the full path to the file ๐ค๏ธ.-m num,--min-count=numโ only affects execution count output ๐ข. Symbols executed fewer than num times get hidden. Bye, low-key functions ๐.-nsymspec,--time=symspecโ the-noption makesgprof, during its call graph analysis, only propagate times for symbols matching symspec ๐ฏ.-Nsymspec,--no-time=symspecโ the-noption makesgprof, during its call graph analysis, not propagate times for symbols matching symspec ๐ซ.-Sfilename,--external-symbol-table=filenameโ tellsgprofto read an external symbol table file, like/proc/kallsyms, instead of reading the symbol table from the object file (the default isa.out) ๐ง. This is the move for profiling kernel modules ๐ฅ.-z,--display-unused-functionsโ with this on,gproflists every function in the flat profile, even ones that were never called and didn't spend any time ๐ฆ. It pairs beautifully with the-coption if you want to find routines that never got called ๐ต๏ธโโ๏ธ.
โจ Miscellaneous Options โจ
-d[num],--debug[=num]โ sets debugging options ๐. If you don't give a num, you get all debugging turned on ๐.-h,--helpโ prints the command line usage ๐.-Oname,--file-format=nameโ picks the format of the profile data files ๐. The recognized formats areauto(the default),bsd,4.4bsd,magic, andprof(not yet supported) ๐.-s,--sumโgprofsummarizes the info from all the profile data files it read and writes it into a new file calledgmon.sum๐ง. That file holds everything from the input files. Fun twist:gmon.sumcan be one of the input files too, which merges the data from the other inputs into it ๐ซถ.
Later on, you can run gprof again without -s to analyze the cumulative data stored in gmon.sum ๐.
-v,--versionโ prints the current version number and then exits ๐ข.
๐ โโ๏ธ Deprecated Options ๐ โโ๏ธ
These options have been replaced with newer versions that use symspecs. Use the newer stuff, bestie ๐.
-e function_nameโ tellsgprofto skip printing info about function_name (and its children...) in the call graph ๐ป. The function still shows up as a child of any functions that call it, but its index number displays as[not printed]. You can give more than one-eoption, but each one only takes a single function_name.-E function_nameโ works like-e, but the time spent in the function (and any children who weren't called from anywhere else) won't count toward the percentages-of-time in the call graph ๐งฎ. Again, you can use more than one-E, with one function_name each.-f function_nameโ limits the call graph to function_name and its children (and their children...) ๐. Multiple-foptions are allowed, one function_name per option.-F function_nameโ works like-f, but only the time spent in the function and its children (and their children...) gets used for total-time and percentages-of-time in the call graph โฑ๏ธ. Multiple-Foptions are allowed, one function_name each. The-Foption overrides the-Eoption ๐.
๐ FILES ๐
a.outโ the namelist and text space ๐งพ.gmon.outโ dynamic call graph and profile ๐.gmon.sumโ summarized dynamic call graph and profile ๐ง.
๐ BUGS ๐
The granularity of the sampling is shown, but it stays statistical at best ๐ฒ. We assume the time for each execution of a function can be expressed as the total time for the function divided by the number of times it's called. So the time propagated along the call graph arcs to a function's parents is directly proportional to how many times that arc gets traversed ๐.
Parents that aren't profiled themselves will have the time of their profiled children propagated to them. They'll look like they were spontaneously invoked in the call graph listing, and their time won't be propagated any further ๐. Signal catchers are similar: even when profiled, they appear spontaneous (for more obscure reasons ๐). Any profiled children of signal catchers should still get their times propagated properly, unless the signal catcher was invoked during the execution of the profiling routine. In that case, all is lost ๐.
The profiled program must call exit(2) or return normally for the profiling information to be saved in the gmon.out file. No exit, no data, no cap ๐ญ.
๐ SEE ALSO ๐
cc(1), prof(1), and the Info entry for gprof ๐.
"An Execution Profiler for Modular Programs", by S. Graham, P. Kessler, M. McKusick; Software - Practice and Experience, Vol. 13, pp. 671-685, 1983 ๐ง.
"gprof: A Call Graph Execution Profiler", by S. Graham, P. Kessler, M. McKusick; Proceedings of the SIGPLAN '82 Symposium on Compiler Construction, SIGPLAN Notices, Vol. 17, No 6, pp. 120-126, June 1982 ๐.
โ๏ธ COPYRIGHT โ๏ธ
Copyright (c) 1988-2025 Free Software Foundation, Inc. ๐
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License" ๐.
That's the whole tea, bestie! ๐ This page belongs to binutils 2.45 and was last updated on 2025-12-03, so go profile something iconic and send me the call graph ๐โจ๐ซถ
๐ฆ where this page comes from
- ubuntu questing: binutils-common 2.45-7ubuntu1.2
- ubuntu questing: binutils-x86-64-linux-gnu 2.45-7ubuntu1.2
- ๐ girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms