Re: [PATCH] examples: add script fcalls.d
Kris Van Hees <[email protected]>
| Newsgroups | dev.linux.lists.dtrace |
|---|---|
| Message-ID | <[email protected]> |
On Mon, Aug 04, 2025 at 08:06:59PM -0400, Eugene Loh wrote: > Reviewed-by: Eugene Loh <[email protected]> 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, [email protected] wrote: > > From: Ruud van der Pas <[email protected]> > > > > This is a script to list and count function calls. > > > > dtrace/ChangeLog > > 2025-08-01 Ruud van der Pas <[email protected]> > > > > * examples/fcalls.d: List and count function calls. > > > > Signed-off-by: Ruud van der Pas <[email protected]> > > --- > > 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); > > +}