stackcount(8)

πŸ“¦ version 0.36.1, in centos-stream 10, centos-stream 9, fedora 43, fedora 44

πŸ’– stackcount(8) πŸ’–

(System Manager's Manual, bestie, it's literally giving official docs πŸ“–)

✨ NAME ✨

okay so stackcount is the tool that counts function calls along with their whole stack traces πŸ”₯ It runs on Linux eBPF/bcc, so yes, it's very modern and very fast.

πŸŽ€ SYNOPSIS πŸŽ€

stackcount [-h] [-p PID] [-c CPU] [-i INTERVAL] [-D DURATION] [-T]
              [-r] [-s] [-P] [-K] [-U] [-v] [-d] [-f] [--debug] pattern

πŸ¦‹ DESCRIPTION πŸ¦‹

okay this is the main character of the whole page πŸ’… stackcount traces functions and frequency counts them along with their entire stack trace, kernel stack and user stack. The summarizing happens in-kernel for efficiency, which means higher frequency events are actually studiable now πŸ™ˆ The output is a list of unique stack traces along with how many times each one occurred. Kernel and user functions are covered, and so are kernel tracepoints and USDT tracepoints ✨

The pattern is a string with optional * wildcards, kind of like file globbing 🌸 If you'd rather use regular expressions, just throw in the -r option 🧚

⚠️ bestie, this tool only works on Linux 4.6+. Stack traces come from the new BPF_STACK_TRACE APIs. For kernels older than 4.6, go check the version under tools/old instead πŸ’€

🧁 REQUIREMENTS 🧁

You need CONFIG_BPF and bcc 🫢

πŸ‘‘ OPTIONS πŸ‘‘

  • -h β€” Prints the usage message. Basically the cheat sheet πŸ“
  • -r β€” Lets the search pattern use regular expressions. By default you only get "*" wildcards, so this one unlocks the good stuff πŸ”“
  • -s β€” Shows address offsets 🌈
  • -P β€” Displays stacks separately for each process πŸ’œ
  • -K β€” Shows the kernel stack only πŸ”₯
  • -U β€” Shows the user stack only 🌸
  • -T β€” Adds a timestamp to interval output ⭐
  • -v β€” Shows raw addresses πŸ¦‹
  • -d β€” Prints a delimiter (--) between the kernel and user stacks, so they don't get mixed up 🫢
  • --debug β€” Prints the source of the BPF program when it loads. This is for debugging purposes, so it's a dev-girl move 🧚
  • -i interval β€” Sets the summary interval, in seconds ⏰
  • -D duration β€” Sets the total duration of the trace, in seconds ⏳
  • -f β€” Folded output format πŸ“
  • -p PID β€” Traces this process ID only (filtered in-kernel) 🎯
  • -c CPU β€” Traces this CPU only (filtered in-kernel) πŸ’…
  • pattern β€” A function name or a search pattern. It can include wildcards ("*"), and if you use -r, it can include regular expressions too 🌟

πŸ“ EXAMPLES πŸ“

okay here's the fun part, the examples are literally so good 😭

  • Count kernel and user stack traces for submit_bio(): # stackcount submit_bio
  • Count stacks with a delimiter for submit_bio(): # stackcount -d submit_bio
  • Count the kernel stack trace only for submit_bio(): # stackcount -K submit_bio
  • Count the user stack trace only for submit_bio(): # stackcount -U submit_bio
  • Count stack traces for ip_output(): # stackcount ip_output
  • Show symbol offsets: # stackcount -s ip_output
  • Show offsets and raw addresses (verbose): # stackcount -sv ip_output
  • Count stacks for kernel functions matching tcp_send*: # stackcount 'tcp_send*'
  • Same as the previous one, but with regular expressions: # stackcount -r '^tcp_send.*'
  • Output every 5 seconds, with timestamps: # stackcount -Ti 5 ip_output
  • Only count stacks when PID 185 is on-CPU: # stackcount -p 185 ip_output
  • Only count stacks for CPU 1: # stackcount -c 1 put_prev_entity
  • Count user stacks for dynamic heap allocations with malloc in PID 185: # stackcount -p 185 c:malloc
  • Count user stacks for thread creation (USDT tracepoint) in PID 185: # stackcount -p 185 u:pthread:pthread_create
  • Count stacks for context switch events using a kernel tracepoint: # stackcount t:sched:sched_switch

🌊 OVERHEAD 🌊

This one is lowkey the most impressive part ✨ It summarizes unique stack traces in-kernel, so it can trace a higher rate of function calls than methods that post-process in user space. Stack trace data only gets copied to user space when the output is printed, which usually happens just once 🫢 The stack walking also runs in an optimized kernel code path thanks to the new BPF_STACK_TRACE table APIs, which should be more efficient than the manual walker in the eBPF tracer that older versions of this script used πŸ”₯ With that in mind, call rates under 10,000/sec should incur negligible overhead. Still, test before production use, no cap πŸ™ˆ You can also use funccount to check function call rates first πŸ’œ

πŸ—ΊοΈ SOURCE πŸ—ΊοΈ

This one comes from bcc 🌈

https://github.com/iovisor/bcc

Also look in the bcc distribution for a companion _examples.txt file with example usage, output, and commentary for this tool πŸ“š

πŸ’» OS πŸ’»

Linux 🐧

πŸ§ͺ STABILITY πŸ§ͺ

🚧 Unstable, it's still in development. Be careful, bestie πŸ™ˆ

πŸŽ“ AUTHOR πŸŽ“

Brendan Gregg and Sasha Goldshtein πŸ‘‘

πŸ”— SEE ALSO πŸ”—

stacksnoop(8), funccount(8) πŸ¦‹


Okay that's the whole page, bestie πŸ’– It's a User Commands manual page dated 2016-01-14, for stackcount(8), so now you're officially a stack-counting queen πŸ‘‘βœ¨

πŸ“¦ where this page comes from