pfunct(1)

πŸ“¦ version 1.32, in fedora 43, fedora 44, nixpkgs unstable

πŸ’– pfunct(1) πŸ’–

okay bestie, welcome to the manual page for pfunct, part of the dwarves crew, living in section 1 of your manual. she's that girl who reads your debug info and spills everything about your functions. no gatekeeping. πŸ’…


✨ NAME ✨

pfunct β€” Shows function information in debug information.


πŸ¦‹ SYNOPSIS πŸ¦‹

pfunct [options] files

🌸 DESCRIPTION 🌸

so pfunct shows functions, their parameters and associated statistics encoded in debugging information formats β€” and the supported formats are DWARF and BTF. that's it, that's the vibe. πŸ’–

the files you hand her must have associated debugging information. and like, that info can live inside the file itself in ELF sections, or it can chill in another file entirely. she'll find it.

one way to get that info in there is to pass the -g option to the compiler when you're building. when you do that, the info gets stored in an ELF section. for the DWARF debugging information format, this adds β€” among others β€” the .debug_info ELF section. for CTF it's found in just one ELF section, .SUNW_ctf. BTF comes in at least the .BTF ELF section, and may come also with the .BTF.ext ELF section. 😌✨

the debuginfo packages available in most Linux distributions are also supported by pfunct, where the debugging information is available in a separate file. so if your distro ships them, you're already set, periodt. 🫢

if no files are specified, then it will look if the /sys/kernel/btf/vmlinux is present, using the BTF information present in it about the running kernel β€” i.e. this works:

$ pfunct ip_send_skb
int ip_send_skb(struct net * net, struct sk_buff * skb);

alternatively a file can be specified:

$ pfunct --format_path=dwarf ip_send_skb /path/2/vmlinux
int ip_send_skb(struct net * net, struct sk_buff * skb);
Split BTF β€” like the BTF for a kernel module β€” references types in a base BTF, normally the BTF for vmlinux. use --btf_base to supply that base BTF when loading a detached split-BTF file. and for files under /sys/kernel/btf/ other than vmlinux itself, pfunct automatically uses /sys/kernel/btf/vmlinux as the base BTF. she's got you, fr fr. πŸ’œ

πŸ‘‘ OPTIONS πŸ‘‘

pfunct supports the following options. buckle up bestie, there's a lot of them and honestly? iconic. ✨

  • -C, --class_name=CLASS_NAMES β€” Show just these classes. This can be a comma separated list of class names or file URLs (e.g.: file://class_list.txt)
  • -a, --addr=ADDR β€” Show just the function where ADDR is.
  • -a,--all β€” Show all the functions that match the filter, or show all function prototypes if no filter is specified.
  • -b,--expand_types β€” Expand types needed by the prototype.
  • -c,--class=CLASS β€” Filter for functions that have CLASS pointer parameters.
  • -E,--externals β€” Show just external functions (DWARF only).
  • -f,--function=FUNCTION β€” Show just FUNCTION.
  • -F, --format_path β€” Allows specifying a list of debugging formats to try, in order. Right now this includes "btf", "ctf" and "dwarf". The default format path used is equivalent to "-F dwarf,btf,ctf".
  • --btf_base=PATH β€” Use PATH as the base BTF when loading split BTF. If no format path is given, this selects BTF loading. This option is not needed for kernel module BTF read from /sys/kernel/btf/MODULE, where the vmlinux BTF is selected automatically.
  • -g,--goto_labels β€” Show number of goto labels (DWARF only).
  • -G--cc_unlinlined β€” Declared inline, uninlined by the compiler (DWARF only).
  • -H, --cc_inlined β€” Not declared inline, inlined by compiler (DWARF only).
  • -i, --inline_expansions β€” Show inline expansion stats (DWARF only).
  • -l, --decl_info β€” Show source code info.
  • -t, --total_inline_stats β€” Show multi-CU total inline expansion stats (DWARF only).
  • -s, --sizes β€” Show sizes of functions.
  • -N,--function_name_len β€” Show size of function names.
  • -p, --nr_parms β€” Show number of parameters.
  • -P, --show_function_prototypes β€” Show function prototypes.
  • -S, --nr_variables β€” Show number of variables.
  • -T, --variables β€” Show variables.
  • -V, --verbose β€” Be verbose.
  • --symtab=NAME β€” Show symbol table NAME (default .symtab).
  • --compile β€” Generate compilable source code with types expanded (Default all functions).
  • --no_parm_names β€” Do not show parameter names.

🧚 NOTES 🧚

to enable the generation of debugging information in the Linux kernel build process, select CONFIG_DEBUG_INFO. you can do this using make menuconfig by this path: "Kernel Hacking" -> "Compile-time checks and compiler options" -> "Compile the kernel with debug info". consider as well enabling CONFIG_DEBUG_INFO_BTF by going thru the aforementioned menuconfig path and then selecting "Generate BTF typeinfo". most modern distributions with eBPF support should come with that in all its kernels, greatly facilitating the use of pahole. slay. πŸ”₯

many distributions also come with debuginfo packages, so just enable it in your package manager repository configuration and install the kernel-debuginfo, or any other userspace program written in a language that the compiler generates debuginfo (C, C++, for instance). πŸ’–


🌈 EXAMPLES 🌈

show a function (using /sys/kernel/btf/vmlinux):

$ pfunct ip_send_skb
int ip_send_skb(struct net * net, struct sk_buff * skb);
$

show a function in DWARF in file vmlinux:

$ pfunct --format_path=DWARF ip_send_skb vmlinux
int ip_send_skb(struct net * net, struct sk_buff * skb);

show all functions in detached split BTF using its vmlinux base:

$ pfunct --btf_base=vmlinux.btf --all module.btf
...

show functions that were not declared with "inline" but were inlined:

$ pfunct --cc_inlined ~/src/bpf-next/vmlinux
clean_cache_range
copy_from_user_nmi
__insn_get_emulate_prefix

πŸŽ€ SEE ALSO πŸŽ€

pahole(1), readelf(1), objdump(1).

please send bug reports to <dwarves@vger.kernel.org>.

no subscription is required. 🫢


dwarves Β· September 2, 2026 β€” and that's the whole page bestie, you ate it up, go read your debug info now πŸ’…βœ¨πŸ¦‹

πŸ“¦ where this page comes from