sprof(1)
๐ sprof โ read & display shared object profiling data ๐
okay bestie, welcome to the sprof page โจ this is a General Commands Manual situation, and it is lowkey one of the most satisfying little tools ever. let's get into it ๐ซถ
โจ NAME โจ
sprof โ read and display shared object profiling data ๐๐ธ
๐ฆ SYNOPSIS ๐ฆ
sprof [option ...] shared-object-path [profile-data-path]
๐ DESCRIPTION ๐
so like, the way sprof works is: it displays a profiling summary for the shared object (aka shared library) you hand it as the first command-line argument. that's the whole main character job ๐
and where does that summary come from?? it gets created using previously generated profiling data that you pass as the (optional!) second command-line argument. so yeah, it doesn't generate anything new โ it's reading the receipts you already collected ๐งพโจ
and if you're feeling lazy and skip the profiling data pathname?? no worries, sprof will attempt to deduce it using the soname of the shared object. it goes looking for a file named <soname>.profile in the current directory. that's the vibe. ๐
๐ธ OPTIONS ๐ธ
these first ones are the ones that decide what kind of profile output you actually get, so pick your fighter:
--call-pairs,-cโ prints a list of pairs of call paths for the interfaces exported by the shared object, plus the number of times each path is used ๐ฏ--flat-profile,-pโ generates a flat profile of all of the functions in the monitored object, with counts and ticks โ--graph,-qโ generates a call graph ๐ธ๏ธ
and if you specify none of the above options?? the default behavior is to display a flat profile AND a call graph. cute, generous, default-on โจ
and here's the additional command-line options, the little support squad:
--help,-?โ displays a summary of command-line options and arguments, then exits ๐--usageโ displays a short usage message, then exits ๐--version,-Vโ displays the program version, then exits ๐ท๏ธ
๐ STANDARDS ๐
GNU. that's it, that's the standard. iconic. periodt. ๐
๐ EXAMPLES ๐
okok this is the fun part. the following example demonstrates the use of sprof. the example consists of a main program that calls two functions in a shared object. buckle up buttercup, we're doing this step by step ๐ง
first, the code of the main program:
$ cat prog.c;
#include <stdlib.h>
void x1(void);
void x2(void);
int
main(int argc, char *argv[])
{
x1();
x2();
exit(EXIT_SUCCESS);
}
the functions x1() and x2() are defined in the following source file, which is what we use to construct the shared object:
$ cat libdemo.c;
#include <unistd.h>
void
consumeCpu1(int lim)
{
for (unsigned int j = 0; j < lim; j++)
getppid();
}
void
x1(void) {
for (unsigned int j = 0; j < 100; j++)
consumeCpu1(200000);
}
void
consumeCpu2(int lim)
{
for (unsigned int j = 0; j < lim; j++)
getppid();
}
void
x2(void)
{
for (unsigned int j = 0; j < 1000; j++)
consumeCpu2(10000);
}
now we construct the shared object with the real name libdemo.so.1.0.1, and the soname libdemo.so.1:
$ cc -g -fPIC -shared -Wl,-soname,libdemo.so.1 \
-o libdemo.so.1.0.1 libdemo.c;
then we construct symbolic links for the library soname and the library linker name ๐:
$ ln -sf libdemo.so.1.0.1 libdemo.so.1;
$ ln -sf libdemo.so.1 libdemo.so;
next, we compile the main program, linking it against the shared object, and then list the dynamic dependencies of the program:
$ cc -g -o prog prog.c -L. -ldemo;
$ ldd prog;
linux-vdso.so.1 => (0x00007fff86d66000)
libdemo.so.1 => not found
libc.so.6 => /lib64/libc.so.6 (0x00007fd4dc138000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd4dc51f000)
in order to get profiling information for the shared object, we define the environment variable LD_PROFILE with the soname of the library:
$ export LD_PROFILE=libdemo.so.1;
we then define the environment variable LD_PROFILE_OUTPUT with the pathname of the directory where profile output should be written, and create that directory if it does not exist already ๐:
$ export LD_PROFILE_OUTPUT=$(pwd)/prof_data;
$ mkdir -p $LD_PROFILE_OUTPUT;
heads up bestie โ LD_PROFILE causes profiling output to be appended to the output file if it already exists, so we ensure that there is no preexisting profiling data. we do NOT want stale numbers ruining the vibe ๐ซ
$ rm -f $LD_PROFILE_OUTPUT/$LD_PROFILE.profile;
then we run the program to produce the profiling output, which is written to a file in the directory specified in LD_PROFILE_OUTPUT:
$ LD_LIBRARY_PATH=. ./prog;
$ ls prof_data;
libdemo.so.1.profile
we then use the sprof -p option to generate a flat profile with counts and ticks:
$ sprof -p libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile;
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls us/call us/call name
60.00 0.06 0.06 100 600.00 consumeCpu1
40.00 0.10 0.04 1000 40.00 consumeCpu2
0.00 0.10 0.00 1 0.00 x1
0.00 0.10 0.00 1 0.00 x2
the sprof -q option generates a call graph ๐ธ๏ธ:
$ sprof -q libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile;
index % time self children called name
0.00 0.00 100/100 x1 [1]
[0] 100.0 0.00 0.00 100 consumeCpu1 [0]
-----------------------------------------------
0.00 0.00 1/1 <UNKNOWN>
[1] 0.0 0.00 0.00 1 x1 [1]
0.00 0.00 100/100 consumeCpu1 [0]
-----------------------------------------------
0.00 0.00 1000/1000 x2 [3]
[2] 0.0 0.00 0.00 1000 consumeCpu2 [2]
-----------------------------------------------
0.00 0.00 1/1 <UNKNOWN>
[3] 0.0 0.00 0.00 1 x2 [3]
0.00 0.00 1000/1000 consumeCpu2 [2]
-----------------------------------------------
above and below, the "<UNKNOWN>" strings represent identifiers that are outside of the profiled object โ in this example, these are instances of main() ๐
the sprof -c option generates a list of call pairs and the number of their occurrences:
$ sprof -c libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile;
<UNKNOWN> x1 1
x1 consumeCpu1 100
<UNKNOWN> x2 1
x2 consumeCpu2 1000
๐ฅ SEE ALSO ๐ฅ
aaand that's the whole thing bestie, you ate that ๐๐ this little bundle of joy shipped as part of Linux man-pages, version 6.20, dated 2026-02-08 โ go profile something and slay โจ๐
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: Linux-man-pages-copyleft
- Copyright 2014, Michael Kerrisk <mtk.manpages@gmail.com>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms