* [PATCH] examples: add script fcalls.d
@ 2025-08-04 23:42 eugene.loh
2025-08-05 0:06 ` Eugene Loh
0 siblings, 1 reply; 3+ messages in thread
From: eugene.loh @ 2025-08-04 23:42 UTC (permalink / raw)
To: dtrace, dtrace-devel
From: Ruud van der Pas <ruud.vanderpas@oracle.com>
This is a script to list and count function calls.
dtrace/ChangeLog
2025-08-01 Ruud van der Pas <ruud.vanderpas@oracle.com>
* examples/fcalls.d: List and count function calls.
Signed-off-by: Ruud van der Pas <ruud.vanderpas@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",@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",@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",@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",@counts_per_thr_and_function);
+}
--
2.43.5
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] examples: add script fcalls.d
2025-08-04 23:42 [PATCH] examples: add script fcalls.d eugene.loh
@ 2025-08-05 0:06 ` Eugene Loh
2025-08-06 18:50 ` Kris Van Hees
0 siblings, 1 reply; 3+ messages in thread
From: Eugene Loh @ 2025-08-05 0:06 UTC (permalink / raw)
To: dtrace, dtrace-devel
Reviewed-by: Eugene Loh <eugene.loh@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@oracle.com wrote:
> From: Ruud van der Pas <ruud.vanderpas@oracle.com>
>
> This is a script to list and count function calls.
>
> dtrace/ChangeLog
> 2025-08-01 Ruud van der Pas <ruud.vanderpas@oracle.com>
>
> * examples/fcalls.d: List and count function calls.
>
> Signed-off-by: Ruud van der Pas <ruud.vanderpas@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",@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",@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",@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",@counts_per_thr_and_function);
> +}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] examples: add script fcalls.d
2025-08-05 0:06 ` Eugene Loh
@ 2025-08-06 18:50 ` Kris Van Hees
0 siblings, 0 replies; 3+ messages in thread
From: Kris Van Hees @ 2025-08-06 18:50 UTC (permalink / raw)
To: Eugene Loh; +Cc: dtrace, dtrace-devel
On Mon, Aug 04, 2025 at 08:06:59PM -0400, Eugene Loh wrote:
> Reviewed-by: Eugene Loh <eugene.loh@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@oracle.com wrote:
> > From: Ruud van der Pas <ruud.vanderpas@oracle.com>
> >
> > This is a script to list and count function calls.
> >
> > dtrace/ChangeLog
> > 2025-08-01 Ruud van der Pas <ruud.vanderpas@oracle.com>
> >
> > * examples/fcalls.d: List and count function calls.
> >
> > Signed-off-by: Ruud van der Pas <ruud.vanderpas@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",@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",@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",@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",@counts_per_thr_and_function);
> > +}
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-08-06 18:50 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-04 23:42 [PATCH] examples: add script fcalls.d eugene.loh
2025-08-05 0:06 ` Eugene Loh
2025-08-06 18:50 ` Kris Van Hees
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).