diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -967,6 +967,7 @@ .if ${MK_CDDL} != "no" _dtrace_provs= dtrace_audit.4 \ + dtrace_fbt.4 \ dtrace_io.4 \ dtrace_ip.4 \ dtrace_kinst.4 \ diff --git a/share/man/man4/dtrace_fbt.4 b/share/man/man4/dtrace_fbt.4 new file mode 100644 --- /dev/null +++ b/share/man/man4/dtrace_fbt.4 @@ -0,0 +1,189 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright (c) 2025 Mateusz Piotrowski <0mp@FreeBSD.org> +.\" +.Dd June 14, 2025 +.Dt DTRACE_FBT 4 +.Os +.Sh NAME +.Nm dtrace_fbt +.Nd a DTrace provider for function boundary tracing +.Sh SYNOPSIS +.Sm off +.Nm fbt Cm \&: Ar module Cm \&: Ar function Cm \&: Ar name +.Sm on +.Sh DESCRIPTION +The Function Boundary Tracing +.Pq Nm fbt +provider instruments the entry and return of every almost every function +in the kernel and modules. +It will always instrument function entry, +and it will instrument function return so long as it can find a +.Ql ret +instruction +.Pq a return via a tail call is never instrumented . +.Pp +Users can use the +.Nm fbt +provider to trace most function calls. +Refer to the +.Sx Frame Pointer +subsection for more details. +.Sh IMPLEMENTATION NOTES +The +.Nm fbt +probes are by definition tightly coupled to kernel code; if the code underlying +a script changes, the script may fail to run or may produce incorrect results. +Scripts written for one version of +.Fx +might not work on another, +and almost certainly will not work on other operating systems. +.Pp +Individual +.Nm fbt +probes often do not correspond nicely to logical system events. +For example, consider a DTrace script which prints the destination +address of every IP packet as the kernel hands them over +to the network card driver. +It turns out that this is a discouragingly difficult task: +it involves instrumenting at least four different functions in different parts +of the IPv4 and IPv6 code. +Users should try available +.Xr dtrace 1 +providers first +.Po such as +.Xr dtrace_ip 4 Pc , +before implementing a custom script with the +.Nm fbt +provider. +Another potential solution is adding statically-defined tracing probes +.Pq Xr SDT 9 . +.Pp +The +.Nm fbt +provider cannot attach to functions inside DTrace provider modules. +.Ss Frame Pointer +Inline functions are not instrumentable by +.Nm fbt +as they lack a frame pointer. +A developer might explicitly disable inlining by adding the +.Ql __noinline +attribute to a function definition, +but of course this requires a recompile of the kernel. +Building the kernel with +.Fl fno-omit-frame-pointer +is another way of preserving frame pointers. +Note, that sometimes compilers will omit frame pointer usage in leaf functions +even when configured with +.Fl fno-omit-frame-pointer . +.Pp +Function returns via a tail call are also not instrumentable by +.Nm fbt . +As a result, +a function might have an entry probe +and a mix of instrumented and uninstrumentable returns. +.Pp +Use +.Xr dtrace_kinst 4 +to trace arbitrary instructions inside kernel functions +and work around some of the +.Nm fbt +limitations. +.Sh EXAMPLES +.Ss Example 1 : No Listing Available FBT Probes +.Bd -literal -offset 2n +.No # Nm dtrace Fl l Fl P Cm fbt + ID PROVIDER MODULE FUNCTION NAME +[...] +31868 fbt kernel hammer_time entry +31869 fbt kernel hammer_time return +[...] +.Ed +.Ss Example 2 : No Counting Kernel Slab Memory Allocation by Function +.Bd -literal -offset 2n +.No # Nm dtrace Fl n Cm 'fbt::kmem*:entry { @[probefunc] = count(); }' +dtrace: description 'fbt::kmem*:entry ' matched 47 probes +.Ic ^C + kmem_alloc_contig 1 + kmem_alloc_contig_domainset 1 + kmem_cache_reap_active 1 + kmem_alloc_contig_pages 2 + kmem_free 2 + kmem_std_destructor 19 + kmem_std_constructor 26 + kmem_cache_free 151 + kmem_cache_alloc 181 +.Ed +.Ss Example 3 : No Counting Kernel Slab Memory Allocation by Calling Function +.Bd -literal -offset 2n +.No # Nm dtrace Fl q Fl n Cm 'fbt::kmem*:entry { @[caller] = count(); } END { printa("%40a %@16d\en", @); }' +.Ic ^C + kernel`contigmalloc+0x33 1 + kernel`free+0xd3 1 + kernel`kmem_alloc_contig+0x29 1 +kernel`kmem_alloc_contig_domainset+0x19a 1 + zfs.ko`arc_reap_cb_check+0x16 1 +.Ed +.Ss Example 4 : No Counting Kernel malloc()'s by Calling Function +.Bd -literal -offset 2n +.No # Nm dtrace Fl q Fl n Cm 'fbt::malloc:entry { @[caller] = count(); } END { printa("%45a %@16d\en", @); }' +.Ic ^C + kernel`devclass_get_devices+0xa8 1 + kernel`sys_ioctl+0xb7 1 + dtrace.ko`dtrace_ioctl+0x15c1 1 + dtrace.ko`dtrace_ioctl+0x972 2 + dtrace.ko`dtrace_dof_create+0x35 2 + kernel`kern_poll_kfds+0x2f0 4 + kernel`kern_poll_kfds+0x28a 19 +.Ed +.Ss Example 5 : No Counting Kernel malloc()'s by Kernel Stack Trace +.Bd -literal -offset 2n +.No # Nm dtrace Fl q Fl n Cm 'fbt::malloc:entry { @[stack()] = count(); }' +.Ic ^C + dtrace.ko`dtrace_dof_create+0x35 + dtrace.ko`dtrace_ioctl+0x827 + kernel`devfs_ioctl+0xd1 + kernel`VOP_IOCTL_APV+0x2a + kernel`vn_ioctl+0xb6 + kernel`devfs_ioctl_f+0x1e + kernel`kern_ioctl+0x286 + kernel`sys_ioctl+0x12f + kernel`amd64_syscall+0x169 + kernel`0xffffffff81092b0b + 2 +.Ed +.Ss Example 6 : No Summarizing vmem_alloc()'s by Arena Name and Size Distribution +.Bd -literal -offset 2n +.No # Nm dtrace Fl n Cm 'fbt::vmem_alloc:entry { @[args[0]->vm_name] = quantize(arg1); }' +dtrace: description 'fbt::vmem_alloc:entry ' matched 1 probe +.Ic ^C + + kernel arena dom + value ------------- Distribution ------------- count + 2048 | 0 + 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4 + 8192 |@@@@@@@@@@@@@ 2 + 16384 | 0 + +.Ed +.Sh SEE ALSO +.Xr dtrace 1 +.Rs +.%A Brendan Gregg +.%A Jim Mauro +.%B DTrace: Dynamic Tracing in Oracle Solaris, Mac OS X and FreeBSD +.%I Prentice Hall +.%P pp. 898\(en903 +.%D 2011 +.%U https://www.brendangregg.com/dtracebook/ +.Re +.Rs +.%B The illumos Dynamic Tracing Guide +.%O Chapter fbt Provider +.%D 2008 +.%U https://illumos.org/books/dtrace/chp-fbt.html#chp-fbt +.Re +.Sh AUTHORS +This manual page was written by +.An Mateusz Piotrowski Aq Mt 0mp@FreeBSD.org .