[DTrace-devel] [PATCH] examples: add script fcalls.d
Kris Van Hees
kris.van.hees at oracle.com
Wed Aug 6 18:50:42 UTC 2025
On Mon, Aug 04, 2025 at 08:06:59PM -0400, Eugene Loh wrote:
> Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
I am confused... is this a R-b that means that the patch can go in as-is, or
are you expecting changes? I also see discussion about a README. Is that a
prerequisite or companion patch that is expected to go in with this one, or
is this one separete and could potentially go in on its own before a README?
> I wouldn't mind a blank line separating each clause from the comment block
> that follows it.
>
> Incidentally, when git applies a patch with "git am", it squeaks when there
> is trailing white space. In this case, "both" (at the end of a line) was
> followed by a space. (That trailing space was removed for this patch, but
> might still be in the original.)
>
> Depending on where we want to go with this, it'd be nice to have tests for
> examples, so that if an example is going to break that we'll know about it.
> There is currently a test/demo directory with a similar purpose but
> antiquated tests. Maybe there could be a test/examples directory. The
> trigger code could possibly be something we already have. E.g., in
> test/triggers/* -- something that terminates by itself (or not) and has
> nontrivial call stack (for this example) or even multithreaded! And
> predictable (checkable) behavior. Possibilities include:
> test/triggers/futex
> test/triggers/libproc-dlmadopen (multithreaded)
> test/triggers/ustack-tst-basic
> but one could argue that's beyond the scope of this patch.
>
> On 8/4/25 19:42, eugene.loh at oracle.com wrote:
> > From: Ruud van der Pas <ruud.vanderpas at oracle.com>
> >
> > This is a script to list and count function calls.
> >
> > dtrace/ChangeLog
> > 2025-08-01 Ruud van der Pas <ruud.vanderpas at oracle.com>
> >
> > * examples/fcalls.d: List and count function calls.
> >
> > Signed-off-by: Ruud van der Pas <ruud.vanderpas at oracle.com>
> > ---
> > examples/fcalls.d | 88 +++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 88 insertions(+)
> > create mode 100755 examples/fcalls.d
> >
> > diff --git a/examples/fcalls.d b/examples/fcalls.d
> > new file mode 100755
> > index 000000000..8116ecc6f
> > --- /dev/null
> > +++ b/examples/fcalls.d
> > @@ -0,0 +1,88 @@
> > +#!/usr/sbin/dtrace -s
> > +
> > +/*
> > + * NAME
> > + * fcalls.d - list the functions executed by an application
> > + *
> > + * SYNOPSIS
> > + * sudo ./fcalls.d -c "<name-of-application> [app options]"
> > + *
> > + * DESCRIPTION
> > + * This program lists the functions executed by the target
> > + * application. In addition to this, the number of calls to
> > + * each function is printed. This information is given on a
> > + * per-thread basis, as well as aggregated over all threads.
> > + *
> > + * NOTES
> > + * - Since a.out is used in the probe definitions, library calls
> > + * are excluded. If a library like libc should be included,
> > + * duplicate the probe definitions and in the copied lines
> > + * replace a.out by libc.so.
> > + * For example:
> > + * pid$target:a.out::entry,pid$target:libc.so::entry
> > + * { ... }
> > + * - It is assumed that a function called main is executed.
> > + * If this is not the case, this is not a critical error.
> > + * The first probe is used to capture the name of the executable,
> > + * but this is not critical. The probe and printf statement
> > + * can safely be removed, or replaced by a suitable alternative.
> > + */
> > +
> > +/*
> > + * Suppress the default output from the dtrace command and
> > + * have printa() print the data sorted by the first field.
> > + */
> > +#pragma D option quiet
> > +#pragma D option aggsortkey=1
> > +#pragma D option aggsortkeypos=0
> > +
> > +/*
> > + * Store the name of the target application. The probe
> > + * is restricted to main only, because the exec name needs
> > + * to be captured only once.
> > + */
> > +pid$target:a.out:main:entry
> > +{
> > + executable_name = execname;
> > +}
> > +/*
> > + * Use 4 aggregations to store the total number of function
> > + * calls, the counts per function and per thread, both
> > + * seperately and differentiated by thread and function.
> > + */
> > +pid$target:a.out::entry
> > +{
> > + @total_call_counts = count();
> > + @call_counts_per_function[probefunc] = count();
> > + @call_counts_per_thr[tid] = count();
> > + @counts_per_thr_and_function[tid,probefunc] = count();
> > +}
> > +/*
> > + * Print the results. Use format strings to create a
> > + * table lay-out.
> > + */
> > +END {
> > + printf("===========================================\n");
> > + printf(" Function Call Count Statistics\n");
> > + printf("===========================================\n");
> > + printf("Name of the executable: %s\n" ,executable_name);
> > + printa("Total function calls : %@d\n", at total_call_counts);
> > +
> > + printf("\n===========================================\n");
> > + printf(" Aggregated Function Call Counts\n");
> > + printf("===========================================\n");
> > + printf("%-25s %12s\n\n","Function name","Count");
> > + printa("%-25s %@12d\n", at call_counts_per_function);
> > +
> > + printf("\n===========================================\n");
> > + printf(" Function Call Counts Per Thread\n");
> > + printf("===========================================\n");
> > + printf("%-7s %12s\n\n", "TID","Count");
> > + printa("%-7d %@12d\n", at call_counts_per_thr);
> > +
> > + printf("\n===========================================\n");
> > + printf(" Thread Level Function Call Counts\n");
> > + printf("===========================================\n");
> > + printf("%-7s %-25s %8s\n\n","TID","Function name","Count");
> > + printa("%-7d %-25s %@8d\n", at counts_per_thr_and_function);
> > +}
More information about the DTrace-devel
mailing list