[DTrace-devel] [PATCH] examples: add script fcalls.d

Eugene Loh eugene.loh at oracle.com
Tue Aug 5 00:06:59 UTC 2025


Reviewed-by: Eugene Loh <eugene.loh at oracle.com>

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