[DTrace-devel] [PATCH 02/05] tp: handle tracepoint argument datatypes with symbolic array size

Kris Van Hees kris.van.hees at oracle.com
Mon May 8 14:02:04 UTC 2023


On Fri, May 05, 2023 at 03:11:21PM -0400, Eugene Loh via DTrace-devel wrote:
> Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
> but I have some questions.  (You can decide if any of the questions warrants
> rescinding the R-b!)
> 
> The main question is why not use this approach for every [] field, even if
> the arrsize spec is strictly numerical... that is, even if it's [4] or
> something?  Using the same approach in each case could simplify this code a
> little: no alternate code path for !alpha, don't care if it is alpha, etc.

The reason I am not doing that (yet) is that the logic needed is quite a bit
more complex because we'd need to handle quite a few more cases.  And then
there is the problem of multi-dimensional arrays.  I.e. how do you determine
X and Y in 'char [X][Y]' based on only the base size (size of char) and the
total size?

So for now, I am only covering what is necessary.

> Also, is the name "alpha" right?  !isdigit() could also mean ' ' or '+' and
> I see some arrsize specs like "[32 + 2]", which would be handled by the new
> mechanism even though the name "alpha" does not quite make sense.

Yes, the variable name 'alpha' is not ideal but I think it covers the load.

> But basically looks fine.
> 
> On 5/5/23 11:30, Kris Van Hees via DTrace-devel wrote:
> > Some kernels expose datatypes for tracepoint elements like this:
> > 
> >    field:char oldcomm[TASK_COMM_LEN]; offset:12; size:16; signed:1;
> > 
> > Since the type compiler and CTF type parser) cannot resolve the value
> > of TASK_COMM_LEN, we synthesize the type ourselves based on the base
> > type (char in this case) and the argument size (16 in this case).
> > 
> > Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> > ---
> >   libdtrace/dt_provider_tp.c | 41 ++++++++++++++++++++++++++++++--------
> >   1 file changed, 33 insertions(+), 8 deletions(-)
> > 
> > diff --git a/libdtrace/dt_provider_tp.c b/libdtrace/dt_provider_tp.c
> > index a08550ab..ff4cc56b 100644
> > --- a/libdtrace/dt_provider_tp.c
> > +++ b/libdtrace/dt_provider_tp.c
> > @@ -7,6 +7,7 @@
> >    * Provider support code for tracepoint-based probes.
> >    */
> >   #include <errno.h>
> > +#include <ctype.h>
> >   #include <stdio.h>
> >   #include <sys/ioctl.h>
> >   #include <linux/perf_event.h>
> > @@ -111,7 +112,7 @@ dt_tp_is_created(const tp_probe_t *tpp)
> >    * the identifier isn't as easy because it may be suffixed by one or more
> >    * array dimension specifiers (and those are part of the type).
> >    *
> > - * All events include a number of fields that we are not interested and that
> > + * All events include a number of fields that we are not interested in and that
> >    * need to be skipped (SKIP_FIELDS_COUNT).  Callers of this function can
> >    * specify an additional number of fields to skip (using the 'skip' parameter)
> >    * before we get to the actual arguments.
> > @@ -187,8 +188,13 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp,
> >   	rewind(f);
> >   	argc = -skip;
> >   	while (getline(&buf, &bufsz, f) >= 0) {
> > -		char	*p = buf;
> > +		char	*p;
> >   		size_t	l;
> > +		size_t	size = 0;
> > +
> > +		p = strstr(buf, "size:");
> > +		if (p != NULL)
> > +			size = strtol(p + 5, NULL, 10);
> >   		if (sscanf(buf, " field:%[^;]", p) <= 0)
> >   			continue;
> > @@ -214,6 +220,7 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp,
> >   		} else {
> >   			char	*s, *q;
> >   			int	n;
> > +			int	alpha = 0;
> >   			/*
> >   			 * The identifier is followed by at least one array
> > @@ -223,7 +230,10 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp,
> >   			 */
> >   			s = p + l - 1;
> >   			for (;;) {
> > -				while (*(--s) != '[') ;
> > +				while (*(--s) != '[') {
> > +					if (!isdigit(*s))
> > +						alpha = 1;
> > +				}
> >   				while (*(--s) == ' ') ;
> >   				if (*s != ']')
> >   					break;
> > @@ -240,11 +250,26 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp,
> >   			if ((q = strrchr(p, ' ')))
> >   				*q = '\0';
> > -			l = q - p;
> > -			memcpy(strp, p, l);
> > -			n = strlen(s);
> > -			memcpy(strp + l, s, n);
> > -			l += n;
> > +			if (alpha) {
> > +				ctf_file_t	*ctfp = dtp->dt_shared_ctf;
> > +				ctf_id_t	type;
> > +				size_t		esize = 1;
> > +
> > +				type = ctf_lookup_by_name(ctfp, p);
> > +				if (type != CTF_ERR)
> > +					esize = ctf_type_size(ctfp, type);
> > +				if (esize != 0)
> > +					size /= esize;
> > +
> > +				l = snprintf(strp, q - p + strlen(s), "%s[%lu]",
> > +					     p, size);
> > +			} else {
> > +				l = q - p;
> > +				memcpy(strp, p, l);
> > +				n = strlen(s);
> > +				memcpy(strp + l, s, n);
> > +				l += n;
> > +			}
> >   		}
> >   		argv[argc].mapping = argc;
> 
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel



More information about the DTrace-devel mailing list