[DTrace-devel] [PATCH] test: clean up orphaned tracing events between tests

Kris Van Hees kris.van.hees at oracle.com
Wed Jun 7 15:25:01 UTC 2023


On Wed, Jun 07, 2023 at 11:09:45AM +0100, Nick Alcock wrote:
> On 7 Jun 2023, Kris Van Hees via DTrace-devel outgrape:
> 
> > Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> 
> Significant changes suggested below: equally significant reduction in
> runtime expected :)

The reduction in runtime is actually minimal, but improvements are welcome
either way.  But... not really significant in the overall cost of the
testsuite by any means.

I'll send a v2.

> > ---
> >  runtest.sh                 |   2 +
> >  test/utils/Build           |   2 +-
> >  test/utils/clean_probes.sh | 102 +++++++++++++++++++++++++++++++++++++
> >  3 files changed, 105 insertions(+), 1 deletion(-)
> >  create mode 100755 test/utils/clean_probes.sh
> >
> > diff --git a/runtest.sh b/runtest.sh
> > index a39a1c91..17589d85 100755
> > --- a/runtest.sh
> > +++ b/runtest.sh
> > @@ -1500,6 +1500,8 @@ for dt in $dtrace; do
> >              cp -f $tmpdir/test.out $base.r
> >          fi
> >  
> > +	test/utils/clean_probes.sh >> $LOGFILE
> > +
> 
> Total pedantry: runtest.sh uses spaces, not tabs :)

OK - why?

> > diff --git a/test/utils/clean_probes.sh b/test/utils/clean_probes.sh
> > new file mode 100755
> > index 00000000..5e931232
> > --- /dev/null
> > +++ b/test/utils/clean_probes.sh
> > @@ -0,0 +1,102 @@
> > +#!/usr/bin/bash
> > +
> > +TRACEFS=/sys/kernel/debug/tracing
> > +EVENTS=${TRACEFS}/available_events
> > +KPROBES=${TRACEFS}/kprobe_events
> > +UPROBES=${TRACEFS}/uprobe_events
> > +
> > +# Check permissions
> > +if [ ! -r ${EVENTS} ]; then
> 
> Throughout: [ is (much) slower than [[ in bash and has awful semantics.
> [[ ... ]] is almost always preferable.

OK.

> > +# Scan the list of events for any orphaned DTrace probes
> > +(
> > +	ps -e
> 
> Rather than using a ps -e and then parsing the heck out of it, why not
> do something like

Um... "parsing the heck out of it" ??  The AWK script was checking the number
of fields in the input line and then looked for /dtrace/.  That's more like
minimal parsing.

But anyway, I like your suuggestion of using a more specific ps command.

> (ps -C dtrace -o pid=
>  echo ===
>  cat ${EVENTS})
> 
> and then accumulate everything you see into pids, then match on /---/
> and treat everything later as an event? Actually we don't even need (),
> we're not changing anything that uses a subprocess: {} is enough.
> 
> This is really quite a lot faster, too -- ps has to do less work, and
> it doesn't collect things it doesn't have to:
> 
> oranix at loom 3010$ strace ps -e 2>&1 >/dev/null | wc -l
> 19372
> oranix at loom 3011$ strace ps -e -o pid 2>&1 >/dev/null | wc -l
> 11576
> oranix at loom 3012$ ps -C dtrace -o pid 2>&1 >/dev/null | wc -l
> 9830
> 
> So... something like:
> 
> { ps -C dtrace -o pid=; echo ===; cat ${EVENTS}; } |
>     awk -v tracefs=${TRACEFS} \
>         'BEGIN { events = 0; }
>         /^===$/ { events = 1; next; }
>         !events { pids = pids "|" int($1); next; }
> 
> ... and then something else, because I'll admit I have no idea what's
> going on in most of the rest of it, !processing and below: it's
> presumably uprobe_events stuff which is probably pretty much ok as is,
> or at least probably not too expensive and too complex like the
> ps-parsing stuff. (I'm not even sure why the variable 'processing'
> exists.)
> 
> (btw, did you know that the format of ps sans -o depends on an
> environment variable, PS_FORMAT? Always, always use -o when using ps in
> scripts.)
> 
> (original below for comparison)
> 
> > +	cat ${EVENTS}
> > +) | \
> > +	awk -v tracefs=${TRACEFS} \
> > +	    'function getTimestamp(dt) {
> > +#		 cmd = "date --rfc-3339=ns";
> > +		 cmd = "date +\"%s.%N\"";
> > +		 cmd | getline dt;
> > +		 close(cmd);
> > +		 return dt;
> > +	     }
> > +
> > +	     function timeDiff(t0, t1, s0, n0, s1, n1) {
> > +		 tmp = $0;
> > +
> > +		 $0 = t0;
> > +		 sub(/\./, " ");
> > +		 s0 = int($1);
> > +		 n0 = int($2);
> > +		 $0 = t1;
> > +		 sub(/\./, " ");
> > +		 s1 = int($1);
> > +		 n1 = int($2);
> > +
> > +		 if (n1 < n0) {
> > +		     s1--;
> > +		     n1 += 1000000000;
> > +		 }
> > +
> > +		 $0 = tmp;
> > +
> > +		 return sprintf("%d.%09d", s1 - s0, n1 - n0);
> > +	     }
> > +
> > +	     BEGIN { start = getTimestamp(); }
> > +
> > +	     NF > 1 {
> > +		 if (/dtrace/)
> > +		     pids = pids "|" int($1);
> > +		 next;
> > +	     }
> > +
> > +	     !processing {
> > +		 re = "^dt_" substr(pids, 2) "_";
> > +		 processing = 1;
> > +	     }
> > +
> > +	     $1 !~ /^dt_[0-9]/ { next; }
> > +	     $1 ~ re { next; }
> > +	     { sub(/:/, "/"); }
> > +
> > +	     {
> > +		 if (/_fbt_/)
> > +		     kpv[kpc++] = $0;
> > +		 else
> > +		     upv[upc++] = $0;
> > +	     }
> > +
> > +	     END {
> > +		 fn = tracefs"/kprobe_events";
> > +		 for (i = 0; i < kpc; i++) {
> > +		     print "-:"kpv[i] >> fn;
> > +		     if (i % 20 == 19)
> > +			 close(fn);
> > +		 }
> > +		 close(fn);
> > +
> > +		 fn = tracefs"/uprobe_events";
> > +		 for (i = 0; i < upc; i++) {
> > +		     print "-:"upv[i] >> fn;
> > +		     if (i % 20 == 19)
> > +			 close(fn);
> > +		 }
> > +		 close(fn);
> > +
> > +		 diff = timeDiff(start, getTimestamp());
> > +		 txt = sprintf(" (%d kprobes, %d uprobes)", kpc, upc);
> > +		 print "Cleaning took " diff txt;
> > +	     }'
> > +
> > +exit 0



More information about the DTrace-devel mailing list