1 Demonstrations of profile, the Linux eBPF/bcc version. 2 3 4 This is a CPU profiler. It works by taking samples of stack traces at timed 5 intervals, and frequency counting them in kernel context for efficiency. 6 7 Example output: 8 9 # ./profile 10 Sampling at 49 Hertz of all threads by user + kernel stack... Hit Ctrl-C to end. 11 ^C 12 filemap_map_pages 13 handle_mm_fault 14 __do_page_fault 15 do_page_fault 16 page_fault 17 [unknown] 18 - cp (9036) 19 1 20 21 [unknown] 22 [unknown] 23 - sign-file (8877) 24 1 25 26 __clear_user 27 iov_iter_zero 28 read_iter_zero 29 __vfs_read 30 vfs_read 31 sys_read 32 entry_SYSCALL_64_fastpath 33 read 34 - dd (25036) 35 4 36 37 func_a 38 main 39 __libc_start_main 40 [unknown] 41 - func_ab (13549) 42 5 43 44 [...] 45 46 native_safe_halt 47 default_idle 48 arch_cpu_idle 49 default_idle_call 50 cpu_startup_entry 51 rest_init 52 start_kernel 53 x86_64_start_reservations 54 x86_64_start_kernel 55 - swapper/0 (0) 56 72 57 58 native_safe_halt 59 default_idle 60 arch_cpu_idle 61 default_idle_call 62 cpu_startup_entry 63 start_secondary 64 - swapper/1 (0) 65 75 66 67 The output was long; I truncated some lines ("[...]"). 68 69 This default output prints stack traces, followed by a line to describe the 70 process (a dash, the process name, and a PID in parenthesis), and then an 71 integer count of how many times this stack trace was sampled. 72 73 The output above shows the most frequent stack was from the "swapper/1" 74 process (PID 0), running the native_safe_halt() function, which was called 75 by default_idle(), which was called by arch_cpu_idle(), and so on. This is 76 the idle thread. Stacks can be read top-down, to follow ancestry: child, 77 parent, grandparent, etc. 78 79 The func_ab process is running the func_a() function, called by main(), 80 called by __libc_start_main(), and called by "[unknown]" with what looks 81 like a bogus address (1st column). That's evidence of a broken stack trace. 82 It's common for user-level software that hasn't been compiled with frame 83 pointers (in this case, libc). 84 85 The dd process has called read(), and then enters the kernel via 86 entry_SYSCALL_64_fastpath(), calling sys_read(), and so on. Yes, I'm now 87 reading it bottom up. That way follows the code flow. 88 89 90 The dd process is actually "dd if=/dev/zero of=/dev/null": it's a simple 91 workload to analyze that just moves bytes from /dev/zero to /dev/null. 92 Profiling just that process: 93 94 # ./profile -p 25036 95 Sampling at 49 Hertz of PID 25036 by user + kernel stack... Hit Ctrl-C to end. 96 ^C 97 [unknown] 98 [unknown] 99 - dd (25036) 100 1 101 102 __write 103 - dd (25036) 104 1 105 106 read 107 - dd (25036) 108 1 109 110 [...] 111 112 [unknown] 113 [unknown] 114 - dd (25036) 115 2 116 117 entry_SYSCALL_64_fastpath 118 __write 119 [unknown] 120 - dd (25036) 121 3 122 123 entry_SYSCALL_64_fastpath 124 read 125 - dd (25036) 126 3 127 128 __clear_user 129 iov_iter_zero 130 read_iter_zero 131 __vfs_read 132 vfs_read 133 sys_read 134 entry_SYSCALL_64_fastpath 135 read 136 [unknown] 137 - dd (25036) 138 3 139 140 __clear_user 141 iov_iter_zero 142 read_iter_zero 143 __vfs_read 144 vfs_read 145 sys_read 146 entry_SYSCALL_64_fastpath 147 read 148 - dd (25036) 149 7 150 151 Again, I've truncated some lines. Now we're just analyzing the dd process. 152 The filtering is performed in kernel context, for efficiency. 153 154 This output has some "[unknown]" frames that probably have valid addresses, 155 but we're lacking the symbol translation. This is a common for all profilers 156 on Linux, and is usually fixable. See the DEBUGGING section of the profile(8) 157 man page. 158 159 160 Lets add delimiters between the user and kernel stacks, using -d: 161 162 # ./profile -p 25036 -d 163 ^C 164 __vfs_write 165 sys_write 166 entry_SYSCALL_64_fastpath 167 -- 168 __write 169 - dd (25036) 170 1 171 172 -- 173 [unknown] 174 [unknown] 175 - dd (25036) 176 1 177 178 iov_iter_init 179 __vfs_read 180 vfs_read 181 sys_read 182 entry_SYSCALL_64_fastpath 183 -- 184 read 185 - dd (25036) 186 1 187 188 [...] 189 190 __clear_user 191 iov_iter_zero 192 read_iter_zero 193 __vfs_read 194 vfs_read 195 sys_read 196 entry_SYSCALL_64_fastpath 197 -- 198 read 199 - dd (25036) 200 9 201 202 In this mode, the delimiters are "--". 203 204 205 206 Here's another example, a func_ab program that runs two functions, func_a() and 207 func_b(). Profiling it for 5 seconds: 208 209 # ./profile -p `pgrep -n func_ab` 5 210 Sampling at 49 Hertz of PID 2930 by user + kernel stack for 5 secs. 211 212 func_a 213 main 214 __libc_start_main 215 [unknown] 216 - func_ab (2930) 217 2 218 219 func_b 220 main 221 __libc_start_main 222 [unknown] 223 - func_ab (2930) 224 3 225 226 func_a 227 main 228 __libc_start_main 229 [unknown] 230 - func_ab (2930) 231 5 232 233 func_b 234 main 235 __libc_start_main 236 [unknown] 237 - func_ab (2930) 238 12 239 240 func_b 241 main 242 __libc_start_main 243 [unknown] 244 - func_ab (2930) 245 19 246 247 func_a 248 main 249 __libc_start_main 250 [unknown] 251 - func_ab (2930) 252 22 253 254 func_b 255 main 256 __libc_start_main 257 [unknown] 258 - func_ab (2930) 259 64 260 261 func_a 262 main 263 __libc_start_main 264 [unknown] 265 - func_ab (2930) 266 72 267 268 Note that the same stack (2nd column) seems to be repeated. Weren't we doing 269 frequency counting and only printing unique stacks? We are, but in terms of 270 the raw addresses, not the symbols. See the 1st column: those stacks are 271 all unique. 272 273 274 We can output in "folded format", which puts the stack trace on one line, 275 separating frames with semi-colons. Eg: 276 277 # ./profile -f -p `pgrep -n func_ab` 5 278 func_ab;[unknown];__libc_start_main;main;func_a 2 279 func_ab;[unknown];__libc_start_main;main;func_b 2 280 func_ab;[unknown];__libc_start_main;main;func_a 11 281 func_ab;[unknown];__libc_start_main;main;func_b 12 282 func_ab;[unknown];__libc_start_main;main;func_a 23 283 func_ab;[unknown];__libc_start_main;main;func_b 28 284 func_ab;[unknown];__libc_start_main;main;func_b 57 285 func_ab;[unknown];__libc_start_main;main;func_a 64 286 287 I find this pretty useful for writing to files and later grepping. 288 289 290 Folded format can also be used by flame graph stack visualizers, including 291 the original implementation: 292 293 https://github.com/brendangregg/FlameGraph 294 295 I'd include delimiters, -d. For example: 296 297 # ./profile -df -p `pgrep -n func_ab` 5 > out.profile 298 # git clone https://github.com/brendangregg/FlameGraph 299 # ./FlameGraph/flamegraph.pl < out.profile > out.svg 300 301 (Yes, I could pipe profile directly into flamegraph.pl, however, I like to 302 keep the raw folded profiles around: can be useful for regenerating flamegraphs 303 with different options, and, for differential flame graphs.) 304 305 306 Some flamegraph.pl palettes recognize kernel annotations, which can be added 307 with -a. It simply adds a "_[k]" at the end of kernel function names. 308 For example: 309 310 # ./profile -adf -p `pgrep -n dd` 10 311 dd;[unknown] 1 312 dd;[unknown];[unknown] 1 313 dd;[unknown];[unknown] 1 314 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];__fsnotify_parent_[k] 1 315 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];__fsnotify_parent_[k] 1 316 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];__fdget_pos_[k] 1 317 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];apparmor_file_permission_[k] 1 318 dd;[unknown] 1 319 dd;[unknown];[unknown] 1 320 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 321 dd;[unknown] 1 322 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];__fget_light_[k] 1 323 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];__fsnotify_parent_[k] 1 324 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 325 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];__fget_light_[k] 1 326 dd;[unknown];[unknown] 1 327 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k] 1 328 dd;[unknown];[unknown] 1 329 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 330 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 331 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];read_iter_zero_[k] 1 332 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__fsnotify_parent_[k] 1 333 dd;[unknown];[unknown] 1 334 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k];common_file_perm_[k] 1 335 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];__fsnotify_parent_[k] 1 336 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];fsnotify_[k] 1 337 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];security_file_permission_[k] 1 338 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];__fdget_pos_[k] 1 339 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k] 1 340 dd;[unknown];[unknown] 1 341 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k] 1 342 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 343 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];__fget_light_[k] 1 344 dd;[unknown] 1 345 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 346 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k] 1 347 dd;[unknown];[unknown] 1 348 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k] 1 349 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];__fsnotify_parent_[k] 1 350 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 351 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];security_file_permission_[k] 1 352 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k];__clear_user_[k] 1 353 dd;[unknown];[unknown] 1 354 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 355 dd;[unknown];[unknown] 1 356 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k];common_file_perm_[k] 1 357 dd;read 1 358 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];security_file_permission_[k] 1 359 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];fsnotify_[k] 1 360 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];fsnotify_[k] 1 361 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];apparmor_file_permission_[k] 1 362 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];__fsnotify_parent_[k] 1 363 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];apparmor_file_permission_[k] 1 364 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k] 1 365 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];iov_iter_init_[k] 1 366 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];__fsnotify_parent_[k] 1 367 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];__vfs_write_[k];write_null_[k] 1 368 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];__clear_user_[k] 1 369 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];security_file_permission_[k] 1 370 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k];common_file_perm_[k] 1 371 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k] 1 372 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 373 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 374 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k] 1 375 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];__fget_light_[k] 1 376 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k] 1 377 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k] 1 378 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];__vfs_read_[k] 1 379 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];__vfs_write_[k] 1 380 dd;[unknown] 1 381 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 382 dd;[unknown] 1 383 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k] 1 384 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];__fsnotify_parent_[k] 1 385 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 386 dd;[unknown];[unknown] 1 387 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 388 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 389 dd;[unknown];__write;-;sys_write_[k] 1 390 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];__fsnotify_parent_[k] 1 391 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];common_file_perm_[k] 1 392 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 393 dd;[unknown];[unknown] 1 394 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k];__clear_user_[k] 1 395 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k] 1 396 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];__fget_light_[k] 1 397 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k] 1 398 dd;read;-;entry_SYSCALL_64_fastpath_[k];vfs_read_[k] 1 399 dd;__write 1 400 dd;read;-;entry_SYSCALL_64_fastpath_[k];vfs_read_[k] 1 401 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k];common_file_perm_[k] 1 402 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 403 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];__fget_light_[k] 1 404 dd;[unknown];[unknown] 1 405 dd;[unknown] 1 406 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 407 dd;[unknown] 1 408 dd;[unknown] 1 409 dd;[unknown];[unknown] 1 410 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 411 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 412 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k] 1 413 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k] 1 414 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k] 1 415 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k];common_file_perm_[k] 1 416 dd;__write 1 417 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];__fget_light_[k] 1 418 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k] 1 419 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k] 1 420 dd;[unknown] 1 421 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];__fget_light_[k] 1 422 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k] 1 423 dd;[unknown];[unknown] 1 424 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];__fdget_pos_[k] 1 425 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k] 1 426 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k] 1 427 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];_cond_resched_[k] 1 428 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];iov_iter_init_[k] 1 429 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];__fsnotify_parent_[k] 1 430 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k] 1 431 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];rw_verify_area_[k] 1 432 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];apparmor_file_permission_[k] 1 433 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 434 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k] 1 435 dd;[unknown] 1 436 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];fsnotify_[k] 1 437 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k] 1 438 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];__fdget_pos_[k] 1 439 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k] 1 440 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 441 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];__vfs_write_[k] 1 442 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];apparmor_file_permission_[k] 1 443 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k] 1 444 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k];common_file_perm_[k] 1 445 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 446 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 447 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];__fget_light_[k] 1 448 dd;[unknown] 1 449 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];fsnotify_[k] 1 450 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k];common_file_perm_[k] 1 451 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k] 1 452 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 1 453 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];fsnotify_[k] 1 454 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 1 455 dd;__write;-;entry_SYSCALL_64_fastpath_[k];vfs_write_[k] 1 456 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k] 1 457 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k] 1 458 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k];common_file_perm_[k] 1 459 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k] 1 460 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];fsnotify_[k] 1 461 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];apparmor_file_permission_[k] 2 462 dd;read;-;entry_SYSCALL_64_fastpath_[k];__fdget_pos_[k] 2 463 dd;[unknown];[unknown] 2 464 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];__fdget_pos_[k] 2 465 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k];common_file_perm_[k] 2 466 dd;[unknown];[unknown] 2 467 dd;[unknown];[unknown] 2 468 dd;[unknown];[unknown] 2 469 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k] 2 470 dd;[unknown];[unknown] 2 471 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];__clear_user_[k] 2 472 dd;__write;-;entry_SYSCALL_64_fastpath_[k];__fdget_pos_[k] 2 473 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k] 2 474 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k] 2 475 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k];__clear_user_[k] 2 476 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k];__clear_user_[k] 2 477 dd;[unknown];[unknown] 2 478 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];__fget_light_[k] 2 479 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];rw_verify_area_[k];security_file_permission_[k];fsnotify_[k] 2 480 dd;__write;-;sys_write_[k] 2 481 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];fsnotify_[k] 2 482 dd;[unknown];[unknown] 2 483 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k] 2 484 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 2 485 dd;read;-;SyS_read_[k] 2 486 dd;[unknown] 2 487 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k] 2 488 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];__fget_light_[k] 2 489 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k] 2 490 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k];rw_verify_area_[k];security_file_permission_[k];apparmor_file_permission_[k] 2 491 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];__clear_user_[k] 2 492 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];rw_verify_area_[k] 2 493 dd;[unknown];[unknown] 3 494 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];rw_verify_area_[k] 3 495 dd;[unknown];[unknown] 3 496 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k];__clear_user_[k] 3 497 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 3 498 dd;[unknown];[unknown] 3 499 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 3 500 dd;[unknown];[unknown] 3 501 dd;[unknown];[unknown] 3 502 dd;__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 3 503 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k] 3 504 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k];__clear_user_[k] 3 505 dd;[unknown] 4 506 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k] 4 507 dd;[unknown];[unknown] 4 508 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k] 4 509 dd;[unknown] 4 510 dd;[unknown];[unknown] 4 511 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k] 4 512 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k];__clear_user_[k] 5 513 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k];sys_write_[k];vfs_write_[k] 5 514 dd;[unknown];[unknown] 5 515 dd;[unknown];[unknown] 5 516 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k] 6 517 dd;read 15 518 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k];__clear_user_[k] 19 519 dd;[unknown];__write;-;entry_SYSCALL_64_fastpath_[k] 20 520 dd;read;-;entry_SYSCALL_64_fastpath_[k] 23 521 dd;read;-;entry_SYSCALL_64_fastpath_[k];SyS_read_[k];vfs_read_[k];__vfs_read_[k];read_iter_zero_[k];iov_iter_zero_[k];__clear_user_[k] 24 522 dd;__write;-;entry_SYSCALL_64_fastpath_[k] 25 523 dd;__write 29 524 dd;[unknown];read;-;entry_SYSCALL_64_fastpath_[k] 31 525 526 This can be made into a flamegraph. Eg: 527 528 # ./profile -adf -p `pgrep -n func_ab` 10 > out.profile 529 # git clone https://github.com/brendangregg/FlameGraph 530 # ./FlameGraph/flamegraph.pl --color=java < out.profile > out.svg 531 532 It will highlight the kernel frames in orange, and user-level in red (and Java 533 in green, and C++ in yellow). If you copy-n-paste the above output into a 534 out.profile file, you can try it out. 535 536 537 You can increase or decrease the sample frequency. Eg, sampling at 9 Hertz: 538 539 # ./profile -F 9 540 Sampling at 9 Hertz of all threads by user + kernel stack... Hit Ctrl-C to end. 541 ^C 542 func_b 543 main 544 __libc_start_main 545 [unknown] 546 - func_ab (2930) 547 1 548 549 [...] 550 551 native_safe_halt 552 default_idle 553 arch_cpu_idle 554 default_idle_call 555 cpu_startup_entry 556 start_secondary 557 - swapper/3 (0) 558 8 559 560 native_safe_halt 561 default_idle 562 arch_cpu_idle 563 default_idle_call 564 cpu_startup_entry 565 rest_init 566 start_kernel 567 x86_64_start_reservations 568 x86_64_start_kernel 569 - swapper/0 (0) 570 8 571 572 573 You can also restrict profiling to just kernel stacks (-K) or user stacks (-U). 574 For example, just user stacks: 575 576 # ./profile -C 7 2 577 Sampling at 49 Hertz of all threads by user + kernel stack on CPU#7 for 2 secs. 578 579 PyEval_EvalFrameEx 580 [unknown] 581 [unknown] 582 - python (2827439) 583 1 584 585 PyDict_GetItem 586 [unknown] 587 - python (2827439) 588 1 589 590 [unknown] 591 - python (2827439) 592 1 593 594 PyEval_EvalFrameEx 595 [unknown] 596 [unknown] 597 - python (2827439) 598 1 599 600 PyEval_EvalFrameEx 601 - python (2827439) 602 1 603 604 [unknown] 605 [unknown] 606 - python (2827439) 607 608 in this example python application was busylooping on a single core/cpu (#7) 609 we were collecting stack traces only from it 610 611 # ./profile -U 612 Sampling at 49 Hertz of all threads by user stack... Hit Ctrl-C to end. 613 ^C 614 [unknown] 615 [unknown] 616 - dd (2931) 617 1 618 619 [unknown] 620 [unknown] 621 - dd (2931) 622 1 623 624 [unknown] 625 [unknown] 626 - dd (2931) 627 1 628 629 [unknown] 630 [unknown] 631 - dd (2931) 632 1 633 634 [unknown] 635 [unknown] 636 - dd (2931) 637 1 638 639 func_b 640 main 641 __libc_start_main 642 [unknown] 643 - func_ab (2930) 644 1 645 646 [unknown] 647 - dd (2931) 648 1 649 650 [unknown] 651 - dd (2931) 652 1 653 654 func_a 655 main 656 __libc_start_main 657 [unknown] 658 - func_ab (2930) 659 3 660 661 __write 662 [unknown] 663 - dd (2931) 664 3 665 666 func_a 667 main 668 __libc_start_main 669 [unknown] 670 - func_ab (2930) 671 4 672 673 func_b 674 main 675 __libc_start_main 676 [unknown] 677 - func_ab (2930) 678 7 679 680 - swapper/6 (0) 681 10 682 683 func_b 684 main 685 __libc_start_main 686 [unknown] 687 - func_ab (2930) 688 10 689 690 __write 691 - dd (2931) 692 10 693 694 func_a 695 main 696 __libc_start_main 697 [unknown] 698 - func_ab (2930) 699 11 700 701 read 702 - dd (2931) 703 12 704 705 read 706 [unknown] 707 - dd (2931) 708 14 709 710 - swapper/7 (0) 711 46 712 713 - swapper/0 (0) 714 46 715 716 - swapper/2 (0) 717 46 718 719 - swapper/1 (0) 720 46 721 722 - swapper/3 (0) 723 46 724 725 - swapper/4 (0) 726 46 727 728 729 If there are too many unique stack traces for the kernel to save, a warning 730 will be printed. Eg: 731 732 # ./profile 733 [...] 734 WARNING: 8 stack traces could not be displayed. Consider increasing --stack-storage-size. 735 736 Run ./profile -h to see the default. 737 738 739 USAGE message: 740 741 # ./profile -h 742 usage: profile [-h] [-p PID] [-U | -K] [-F FREQUENCY | -c COUNT] [-d] [-a] 743 [-f] [--stack-storage-size STACK_STORAGE_SIZE] 744 [duration] 745 746 Profile CPU stack traces at a timed interval 747 748 positional arguments: 749 duration duration of trace, in seconds 750 751 optional arguments: 752 -h, --help show this help message and exit 753 -p PID, --pid PID profile this PID only 754 -U, --user-stacks-only 755 show stacks from user space only (no kernel space 756 stacks) 757 -K, --kernel-stacks-only 758 show stacks from kernel space only (no user space 759 stacks) 760 -F FREQUENCY, --frequency FREQUENCY 761 sample frequency, Hertz 762 -c COUNT, --count COUNT 763 sample period, number of events 764 -d, --delimited insert delimiter between kernel/user stacks 765 -a, --annotations add _[k] annotations to kernel frames 766 -f, --folded output folded format, one line per stack (for flame 767 graphs) 768 --stack-storage-size STACK_STORAGE_SIZE 769 the number of unique stack traces that can be stored 770 and displayed (default 2048) 771 -C CPU, --cpu CPU cpu number to run profile on 772 773 examples: 774 ./profile # profile stack traces at 49 Hertz until Ctrl-C 775 ./profile -F 99 # profile stack traces at 99 Hertz 776 ./profile -c 1000000 # profile stack traces every 1 in a million events 777 ./profile 5 # profile at 49 Hertz for 5 seconds only 778 ./profile -f 5 # output in folded format for flame graphs 779 ./profile -p 185 # only profile threads for PID 185 780 ./profile -U # only show user space stacks (no kernel) 781 ./profile -K # only show kernel space stacks (no user) 782