summaryrefslogtreecommitdiffstats
path: root/man1/sprof.1
blob: 6d9796b435ec9904691b0bfeb73a641f9b62a5a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
.\" Copyright (C) 2014 Michael Kerrisk <mtk.manpages@gmail.com>
.\"
.\" SPDX-License-Identifier: Linux-man-pages-copyleft
.\"
.TH sprof 1 2023-10-31 "Linux man-pages 6.7"
.SH NAME
sprof \- read and display shared object profiling data
.SH SYNOPSIS
.nf
.BR sprof " [\fIoption\fP]... \fIshared-object-path\fP \
[\fIprofile-data-path\fP]"
.fi
.SH DESCRIPTION
The
.B sprof
command displays a profiling summary for the
shared object (shared library) specified as its first command-line argument.
The profiling summary is created using previously generated
profiling data in the (optional) second command-line argument.
If the profiling data pathname is omitted, then
.B sprof
will attempt to deduce it using the soname of the shared object,
looking for a file with the name
.I <soname>.profile
in the current directory.
.SH OPTIONS
The following command-line options specify the profile output
to be produced:
.TP
.B \-\-call\-pairs
.TQ
.B \-c
Print a list of pairs of call paths for the interfaces exported
by the shared object,
along with the number of times each path is used.
.TP
.B \-\-flat\-profile
.TQ
.B \-p
Generate a flat profile of all of the functions in the monitored object,
with counts and ticks.
.TP
.B \-\-graph
.TQ
.B \-q
Generate a call graph.
.P
If none of the above options is specified,
then the default behavior is to display a flat profile and a call graph.
.P
The following additional command-line options are available:
.TP
.B \-\-help
.TQ
.B \-?
Display a summary of command-line options and arguments and exit.
.TP
.B \-\-usage
Display a short usage message and exit.
.TP
.B \-\-version
.TQ
.B \-V
Display the program version and exit.
.SH STANDARDS
GNU.
.SH EXAMPLES
The following example demonstrates the use of
.BR sprof .
The example consists of a main program that calls two functions
in a shared object.
First, the code of the main program:
.P
.in +4n
.EX
$ \fBcat prog.c\fP
#include <stdlib.h>
\&
void x1(void);
void x2(void);
\&
int
main(int argc, char *argv[])
{
    x1();
    x2();
    exit(EXIT_SUCCESS);
}
.EE
.in
.P
The functions
.IR x1 ()
and
.IR x2 ()
are defined in the following source file that is used to
construct the shared object:
.P
.in +4n
.EX
$ \fBcat libdemo.c\fP
#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);
}
.EE
.in
.P
Now we construct the shared object with the real name
.IR libdemo.so.1.0.1 ,
and the soname
.IR libdemo.so.1 :
.P
.in +4n
.EX
$ \fBcc \-g \-fPIC \-shared \-Wl,\-soname,libdemo.so.1 \e\fP
        \fB\-o libdemo.so.1.0.1 libdemo.c\fP
.EE
.in
.P
Then we construct symbolic links for the library soname and
the library linker name:
.P
.in +4n
.EX
$ \fBln \-sf libdemo.so.1.0.1 libdemo.so.1\fP
$ \fBln \-sf libdemo.so.1 libdemo.so\fP
.EE
.in
.P
Next, we compile the main program, linking it against the shared object,
and then list the dynamic dependencies of the program:
.P
.in +4n
.EX
$ \fBcc \-g \-o prog prog.c \-L. \-ldemo\fP
$ \fBldd prog\fP
	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)
.EE
.in
.P
In order to get profiling information for the shared object,
we define the environment variable
.B LD_PROFILE
with the soname of the library:
.P
.in +4n
.EX
$ \fBexport LD_PROFILE=libdemo.so.1\fP
.EE
.in
.P
We then define the environment variable
.B 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:
.P
.in +4n
.EX
$ \fBexport LD_PROFILE_OUTPUT=$(pwd)/prof_data\fP
$ \fBmkdir \-p $LD_PROFILE_OUTPUT\fP
.EE
.in
.P
.B LD_PROFILE
causes profiling output to be
.I appended
to the output file if it already exists,
so we ensure that there is no preexisting profiling data:
.P
.in +4n
.EX
$ \fBrm \-f $LD_PROFILE_OUTPUT/$LD_PROFILE.profile\fP
.EE
.in
.P
We then run the program to produce the profiling output,
which is written to a file in the directory specified in
.BR LD_PROFILE_OUTPUT :
.P
.in +4n
.EX
$ \fBLD_LIBRARY_PATH=. ./prog\fP
$ \fBls prof_data\fP
libdemo.so.1.profile
.EE
.in
.P
We then use the
.B sprof \-p
option to generate a flat profile with counts and ticks:
.P
.in +4n
.EX
$ \fBsprof \-p libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile\fP
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
.EE
.in
.P
The
.B sprof \-q
option generates a call graph:
.P
.in +4n
.EX
$ \fBsprof \-q libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile\fP
\&
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]
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
.EE
.in
.P
Above and below, the "<UNKNOWN>" strings represent identifiers that
are outside of the profiled object (in this example, these are instances of
.IR main() ).
.P
The
.B sprof \-c
option generates a list of call pairs and the number of their occurrences:
.P
.in +4n
.EX
$ \fBsprof \-c libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile\fP
<UNKNOWN>                  x1                                 1
x1                         consumeCpu1                      100
<UNKNOWN>                  x2                                 1
x2                         consumeCpu2                     1000
.EE
.in
.SH SEE ALSO
.BR gprof (1),
.BR ldd (1),
.BR ld.so (8)