]>
Commit | Line | Data |
---|---|---|
2adccceb MK |
1 | .\" Copyright (C) 2014 Michael Kerrisk <mtk.manpages@gmail.com> |
2 | .\" | |
3 | .\" %%%LICENSE_START(VERBATIM) | |
4 | .\" Permission is granted to make and distribute verbatim copies of this | |
5 | .\" manual provided the copyright notice and this permission notice are | |
6 | .\" preserved on all copies. | |
7 | .\" | |
8 | .\" Permission is granted to copy and distribute modified versions of this | |
9 | .\" manual under the conditions for verbatim copying, provided that the | |
10 | .\" entire resulting derived work is distributed under the terms of a | |
11 | .\" permission notice identical to this one. | |
12 | .\" | |
13 | .\" Since the Linux kernel and libraries are constantly changing, this | |
14 | .\" manual page may be incorrect or out-of-date. The author(s) assume no | |
15 | .\" responsibility for errors or omissions, or for damages resulting from | |
16 | .\" the use of the information contained herein. The author(s) may not | |
17 | .\" have taken the same level of care in the production of this manual, | |
18 | .\" which is licensed free of charge, as they might when working | |
19 | .\" professionally. | |
20 | .\" | |
21 | .\" Formatted or processed versions of this manual, if unaccompanied by | |
22 | .\" the source, must acknowledge the copyright and authors of this work. | |
23 | .\" %%%LICENSE_END | |
24 | .\" | |
9ba01802 | 25 | .TH SPROF 1 2019-03-06 "Linux" "Linux User Manual" |
2adccceb MK |
26 | .SH NAME |
27 | sprof \- read and display shared object profiling data | |
28 | .SH SYNOPSIS | |
29 | .nf | |
4c9b3247 MK |
30 | .BR sprof " [\fIoption\fP]... \fIshared-object-path\fP \ |
31 | [\fIprofile-data-path\fP]" | |
2adccceb MK |
32 | .fi |
33 | .SH DESCRIPTION | |
34 | The | |
35 | .B sprof | |
36 | command displays a profiling summary for the | |
43151de3 | 37 | shared object (shared library) specified as its first command-line argument. |
2adccceb MK |
38 | The profiling summary is created using previously generated |
39 | profiling data in the (optional) second command-line argument. | |
40 | If the profiling data pathname is omitted, then | |
41 | .B sprof | |
42 | will attempt to deduce it using the soname of the shared object, | |
43 | looking for a file with the name | |
a28b73cd | 44 | .I <soname>.profile |
2adccceb MK |
45 | in the current directory. |
46 | .SH OPTIONS | |
47 | The following command-line options specify the profile output | |
48 | to be produced: | |
49 | .TP | |
50 | .BR \-c ", " \-\-call\-pairs | |
51 | Print a list of pairs of call paths for the interfaces exported | |
52 | by the shared object, | |
53 | along with the number of times each path is used. | |
54 | .TP | |
55 | .BR \-p ", " \-\-flat\-profile | |
56 | Generate a flat profile of all of the functions in the monitored object, | |
57 | with counts and ticks. | |
58 | .TP | |
59 | .BR \-q ", " \-\-graph | |
60 | Generate a call graph. | |
61 | .PP | |
62 | If none of the above options is specified, | |
63 | then the default behavior is to display a flat profile and a call graph. | |
64 | .PP | |
65 | The following additional command-line options are available: | |
66 | .TP | |
67 | .BR \-? ", " \-\-help | |
68 | Display a summary of command-line options and arguments and exit. | |
69 | .TP | |
a28b73cd | 70 | .B \-\-usage |
2adccceb MK |
71 | Display a short usage message and exit. |
72 | .TP | |
73 | .BR \-V ", " \-\-version | |
74 | Display the program version and exit. | |
75 | .SH CONFORMING TO | |
76 | The | |
77 | .B sprof | |
78 | command is a GNU extension, not present in POSIX.1. | |
79 | .SH EXAMPLE | |
80 | The following example demonstrates the use of | |
81 | .BR sprof . | |
82 | The example consists of a main program that calls two functions | |
43151de3 | 83 | in a shared object. |
2adccceb | 84 | First, the code of the main program: |
2a86152e | 85 | .PP |
2adccceb | 86 | .in +4n |
60d3774e | 87 | .EX |
2adccceb MK |
88 | $ \fBcat prog.c\fP |
89 | #include <stdlib.h> | |
90 | ||
91 | void x1(void); | |
92 | void x2(void); | |
93 | ||
94 | int | |
95 | main(int argc, char *argv[]) | |
96 | { | |
97 | x1(); | |
98 | x2(); | |
99 | exit(EXIT_SUCCESS); | |
100 | } | |
60d3774e | 101 | .EE |
2adccceb MK |
102 | .in |
103 | .PP | |
104 | The functions | |
a28b73cd | 105 | .IR x1 () |
2adccceb | 106 | and |
a28b73cd | 107 | .IR x2 () |
2adccceb | 108 | are defined in the following source file that is used to |
43151de3 | 109 | construct the shared object: |
2a86152e | 110 | .PP |
2adccceb | 111 | .in +4n |
60d3774e | 112 | .EX |
2adccceb MK |
113 | $ \fBcat libdemo.c\fP |
114 | #include <unistd.h> | |
115 | ||
116 | void | |
117 | consumeCpu1(int lim) | |
118 | { | |
119 | int j; | |
120 | ||
121 | for (j = 0; j < lim; j++) | |
122 | getppid(); | |
123 | } | |
124 | ||
125 | void | |
126 | x1(void) { | |
127 | int j; | |
128 | ||
129 | for (j = 0; j < 100; j++) | |
130 | consumeCpu1(200000); | |
131 | } | |
132 | ||
133 | void | |
134 | consumeCpu2(int lim) | |
135 | { | |
136 | int j; | |
137 | ||
138 | for (j = 0; j < lim; j++) | |
139 | getppid(); | |
140 | } | |
141 | ||
142 | void | |
143 | x2(void) | |
144 | { | |
145 | int j; | |
146 | ||
147 | for (j = 0; j < 1000; j++) | |
148 | consumeCpu2(10000); | |
149 | } | |
60d3774e | 150 | .EE |
2adccceb MK |
151 | .in |
152 | .PP | |
43151de3 | 153 | Now we construct the shared object with the real name |
2adccceb MK |
154 | .IR libdemo.so.1.0.1 , |
155 | and the soname | |
156 | .IR libdemo.so.1 : | |
2a86152e | 157 | .PP |
2adccceb | 158 | .in +4n |
60d3774e | 159 | .EX |
2adccceb MK |
160 | $ \fBcc \-g \-fPIC \-shared \-Wl,\-soname,libdemo.so.1 \e\fP |
161 | \fB\-o libdemo.so.1.0.1 libdemo.c\fP | |
60d3774e | 162 | .EE |
2adccceb MK |
163 | .in |
164 | .PP | |
165 | Then we construct symbolic links for the library soname and | |
166 | the library linker name: | |
2a86152e | 167 | .PP |
2adccceb | 168 | .in +4n |
60d3774e | 169 | .EX |
2adccceb MK |
170 | $ \fBln \-sf libdemo.so.1.0.1 libdemo.so.1\fP |
171 | $ \fBln \-sf libdemo.so.1 libdemo.so\fP | |
60d3774e | 172 | .EE |
2adccceb MK |
173 | .in |
174 | .PP | |
43151de3 | 175 | Next, we compile the main program, linking it against the shared object, |
2adccceb | 176 | and then list the dynamic dependencies of the program: |
2a86152e | 177 | .PP |
2adccceb | 178 | .in +4n |
60d3774e | 179 | .EX |
2adccceb MK |
180 | $ \fBcc \-g \-o prog prog.c \-L. \-ldemo\fP |
181 | $ \fBldd prog\fP | |
182 | linux\-vdso.so.1 => (0x00007fff86d66000) | |
183 | libdemo.so.1 => not found | |
184 | libc.so.6 => /lib64/libc.so.6 (0x00007fd4dc138000) | |
185 | /lib64/ld\-linux\-x86\-64.so.2 (0x00007fd4dc51f000) | |
60d3774e | 186 | .EE |
2adccceb MK |
187 | .in |
188 | .PP | |
43151de3 | 189 | In order to get profiling information for the shared object, |
2adccceb | 190 | we define the environment variable |
a28b73cd | 191 | .B LD_PROFILE |
2adccceb | 192 | with the soname of the library: |
2a86152e | 193 | .PP |
2adccceb | 194 | .in +4n |
60d3774e | 195 | .EX |
2adccceb | 196 | $ \fBexport LD_PROFILE=libdemo.so.1\fP |
60d3774e | 197 | .EE |
2adccceb MK |
198 | .in |
199 | .PP | |
200 | We then define the environment variable | |
a28b73cd | 201 | .B LD_PROFILE_OUTPUT |
2adccceb MK |
202 | with the pathname of the directory where profile output should be written, |
203 | and create that directory if it does not exist already: | |
2a86152e | 204 | .PP |
2adccceb | 205 | .in +4n |
60d3774e | 206 | .EX |
2adccceb MK |
207 | $ \fBexport LD_PROFILE_OUTPUT=$(pwd)/prof_data\fP |
208 | $ \fBmkdir \-p $LD_PROFILE_OUTPUT\fP | |
60d3774e | 209 | .EE |
2adccceb MK |
210 | .in |
211 | .PP | |
212 | .B LD_PROFILE | |
213 | causes profiling output to be | |
214 | .I appended | |
215 | to the output file if it already exists, | |
216 | so we ensure that there is no preexisting profiling data: | |
2a86152e | 217 | .PP |
2adccceb | 218 | .in +4n |
60d3774e | 219 | .EX |
2adccceb | 220 | $ \fBrm \-f $LD_PROFILE_OUTPUT/$LD_PROFILE.profile\fP |
60d3774e | 221 | .EE |
2adccceb MK |
222 | .in |
223 | .PP | |
224 | We then run the program to produce the profiling output, | |
225 | which is written to a file in the directory specified in | |
226 | .BR LD_PROFILE_OUTPUT : | |
2a86152e | 227 | .PP |
2adccceb | 228 | .in +4n |
60d3774e | 229 | .EX |
2adccceb MK |
230 | $ \fBLD_LIBRARY_PATH=. ./prog\fP |
231 | $ \fBls prof_data\fP | |
232 | libdemo.so.1.profile | |
60d3774e | 233 | .EE |
2adccceb MK |
234 | .in |
235 | .PP | |
236 | We then use the | |
a28b73cd | 237 | .B sprof \-p |
2adccceb | 238 | option to generate a flat profile with counts and ticks: |
2a86152e | 239 | .PP |
2adccceb | 240 | .in +4n |
60d3774e | 241 | .EX |
2adccceb MK |
242 | $ \fBsprof \-p libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile\fP |
243 | Flat profile: | |
244 | ||
245 | Each sample counts as 0.01 seconds. | |
246 | % cumulative self self total | |
247 | time seconds seconds calls us/call us/call name | |
248 | 60.00 0.06 0.06 100 600.00 consumeCpu1 | |
249 | 40.00 0.10 0.04 1000 40.00 consumeCpu2 | |
250 | 0.00 0.10 0.00 1 0.00 x1 | |
251 | 0.00 0.10 0.00 1 0.00 x2 | |
60d3774e | 252 | .EE |
2adccceb MK |
253 | .in |
254 | .PP | |
255 | The | |
a28b73cd | 256 | .B sprof \-q |
2adccceb | 257 | option generates a call graph: |
2a86152e | 258 | .PP |
2adccceb | 259 | .in +4n |
60d3774e | 260 | .EX |
2adccceb MK |
261 | $ \fBsprof \-q libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile\fP |
262 | ||
263 | index % time self children called name | |
264 | ||
265 | 0.00 0.00 100/100 x1 [1] | |
266 | [0] 100.0 0.00 0.00 100 consumeCpu1 [0] | |
267 | \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- | |
268 | 0.00 0.00 1/1 <UNKNOWN> | |
269 | [1] 0.0 0.00 0.00 1 x1 [1] | |
270 | 0.00 0.00 100/100 consumeCpu1 [0] | |
271 | \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- | |
272 | 0.00 0.00 1000/1000 x2 [3] | |
273 | [2] 0.0 0.00 0.00 1000 consumeCpu2 [2] | |
274 | \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- | |
275 | 0.00 0.00 1/1 <UNKNOWN> | |
276 | [3] 0.0 0.00 0.00 1 x2 [3] | |
277 | 0.00 0.00 1000/1000 consumeCpu2 [2] | |
278 | \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- | |
60d3774e | 279 | .EE |
2adccceb MK |
280 | .in |
281 | .PP | |
282 | Above and below, the "<UNKNOWN>" strings represent identifiers that | |
283 | are outside of the profiled object (in this example, these are instances of | |
284 | .IR main() ). | |
285 | .PP | |
286 | The | |
a28b73cd | 287 | .B sprof \-c |
2adccceb | 288 | option generates a list of call pairs and the number of their occurrences: |
2a86152e | 289 | .PP |
2adccceb | 290 | .in +4n |
60d3774e | 291 | .EX |
2adccceb MK |
292 | $ \fBsprof \-c libdemo.so.1 $LD_PROFILE_OUTPUT/libdemo.so.1.profile\fP |
293 | <UNKNOWN> x1 1 | |
294 | x1 consumeCpu1 100 | |
295 | <UNKNOWN> x2 1 | |
296 | x2 consumeCpu2 1000 | |
60d3774e | 297 | .EE |
2adccceb MK |
298 | .in |
299 | .SH SEE ALSO | |
300 | .BR gprof (1), | |
301 | .BR ldd (1), | |
302 | .BR ld.so (8) |