[DTrace-devel] [PATCH v3] Add support for array/struct/union to trace()

Kris Van Hees kris.van.hees at oracle.com
Tue Feb 1 22:15:30 UTC 2022


On Tue, Feb 01, 2022 at 01:50:28PM -0500, Eugene Loh via DTrace-devel wrote:
> Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
> 
> But were you going to change the clp2() comment beyond "range 1-8" since
> clp2() makes the effort to be more applicable than that limited range?  In
> any case, the clp2() code movement should be eliminated entirely since it
> isn't necessary at all any more with the align=2 approach.

No point in changing its comment if I am not going to use it for anything,
so the usage case remains the same.  And yes, I can remove the movement, since
there is no point in touching it.

> Is the output in tst.array.r stable?  Or are only the first 7 bytes
> ("dtrace\0") stable?  The current tst.array.r might work for a broad range
> of cases, but strictly speaking it probably ought to be fixed.  E.g., maybe
> add some .r.p file that does
> sed 's/ 0: 64 74 72 61 63 65 00 .*  dtrace\..*/ 0: 64 74 72 61 63 65 00 00
> 00 00 00 00 00 00 00 00  dtrace........../'

It is stable.

> The additional tst.struct<n>.d tests are nice, but we often try to name
> tests more meaningfully.  That would be easy enough to do here.  E.g.
> tst.struct-int8.d and so on.

I don't think that adds any value.

> On 2/1/22 12:32 AM, Kris Van Hees via DTrace-devel wrote:
> > Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> > ---
> >   libdtrace/dt_cg.c                         | 73 +++++++++++++++--------
> >   test/unittest/actions/trace/tst.array.d   | 18 ++++++
> >   test/unittest/actions/trace/tst.array.r   |  8 +++
> >   test/unittest/actions/trace/tst.struct.d  | 27 +++++++++
> >   test/unittest/actions/trace/tst.struct.r  |  8 +++
> >   test/unittest/actions/trace/tst.struct2.d | 23 +++++++
> >   test/unittest/actions/trace/tst.struct2.r |  8 +++
> >   test/unittest/actions/trace/tst.struct3.d | 23 +++++++
> >   test/unittest/actions/trace/tst.struct3.r |  8 +++
> >   test/unittest/actions/trace/tst.struct4.d | 23 +++++++
> >   test/unittest/actions/trace/tst.struct4.r |  8 +++
> >   test/unittest/actions/trace/tst.struct5.d | 23 +++++++
> >   test/unittest/actions/trace/tst.struct5.r |  8 +++
> >   test/unittest/actions/trace/tst.union.d   | 25 ++++++++
> >   test/unittest/actions/trace/tst.union.r   |  8 +++
> >   15 files changed, 267 insertions(+), 24 deletions(-)
> >   create mode 100644 test/unittest/actions/trace/tst.array.d
> >   create mode 100644 test/unittest/actions/trace/tst.array.r
> >   create mode 100644 test/unittest/actions/trace/tst.struct.d
> >   create mode 100644 test/unittest/actions/trace/tst.struct.r
> >   create mode 100644 test/unittest/actions/trace/tst.struct2.d
> >   create mode 100644 test/unittest/actions/trace/tst.struct2.r
> >   create mode 100644 test/unittest/actions/trace/tst.struct3.d
> >   create mode 100644 test/unittest/actions/trace/tst.struct3.r
> >   create mode 100644 test/unittest/actions/trace/tst.struct4.d
> >   create mode 100644 test/unittest/actions/trace/tst.struct4.r
> >   create mode 100644 test/unittest/actions/trace/tst.struct5.d
> >   create mode 100644 test/unittest/actions/trace/tst.struct5.r
> >   create mode 100644 test/unittest/actions/trace/tst.union.d
> >   create mode 100644 test/unittest/actions/trace/tst.union.r
> > 
> > diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> > index c8421109..fcf96429 100644
> > --- a/libdtrace/dt_cg.c
> > +++ b/libdtrace/dt_cg.c
> > @@ -1,6 +1,6 @@
> >   /*
> >    * Oracle Linux DTrace.
> > - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
> > + * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
> >    * Licensed under the Universal Permissive License v 1.0 as shown at
> >    * http://oss.oracle.com/licenses/upl.
> >    */
> > @@ -905,6 +905,25 @@ static const uint_t	ldstw[] = {
> >   					0,	0,	0, BPF_DW,
> >   				};
> > +/*
> > + * When loading bit-fields, we want to convert a byte count in the range
> > + * 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc).  The clp2() function
> > + * is a clever implementation from "Hacker's Delight" by Henry Warren, Jr.
> > + */
> > +static size_t
> > +clp2(size_t x)
> > +{
> > +	x--;
> > +
> > +	x |= (x >> 1);
> > +	x |= (x >> 2);
> > +	x |= (x >> 4);
> > +	x |= (x >> 8);
> > +	x |= (x >> 16);
> > +
> > +	return x + 1;
> > +}
> > +
> >   static int
> >   dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
> >   		dt_pfargv_t *pfp, int arg)
> > @@ -1002,6 +1021,31 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
> >   		return 0;
> >   	}
> > +	/* Handle tracing of by-ref values (arrays, struct, union). */
> > +	if (kind == DTRACEACT_DIFEXPR && (arg & DT_NF_REF)) {
> > +		off = dt_rec_add(dtp, dt_cg_fill_gap, kind, size, 2, pfp, arg);
> > +
> > +		TRACE_REGSET("store_val(): Begin ");
> > +		dt_cg_check_notnull(dlp, drp, dnp->dn_reg);
> > +
> > +		if (dt_regset_xalloc_args(drp) == -1)
> > +			longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> > +
> > +		emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_9));
> > +		emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, off));
> > +		emit(dlp, BPF_MOV_IMM(BPF_REG_2, size));
> > +		emit(dlp, BPF_MOV_REG(BPF_REG_3, dnp->dn_reg));
> > +		dt_regset_free(drp, dnp->dn_reg);
> > +		dt_regset_xalloc(drp, BPF_REG_0);
> > +		emit(dlp, BPF_CALL_HELPER(BPF_FUNC_probe_read));
> > +		dt_regset_free_args(drp);
> > +
> > +		dt_regset_free(drp, BPF_REG_0);
> > +		TRACE_REGSET("store_val(): End   ");
> > +
> > +		return 0;
> > +	}
> > +
> >   	return -1;
> >   }
> > @@ -1669,7 +1713,7 @@ dt_cg_act_trace(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
> >   {
> >   	char		n[DT_TYPE_NAMELEN];
> >   	dt_node_t	*arg = dnp->dn_args;
> > -	int		type = 0;
> > +	int		flags = 0;
> >   	if (dt_node_is_void(arg))
> >   		dnerror(arg, D_TRACE_VOID,
> > @@ -1681,11 +1725,11 @@ dt_cg_act_trace(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
> >   			"expression\n");
> >   	if (arg->dn_flags & DT_NF_REF)
> > -		type = DT_NF_REF;
> > +		flags = DT_NF_REF;
> >   	else if (arg->dn_flags & DT_NF_SIGNED)
> > -		type = DT_NF_SIGNED;
> > +		flags = DT_NF_SIGNED;
> > -	if (dt_cg_store_val(pcb, arg, DTRACEACT_DIFEXPR, NULL, type) == -1)
> > +	if (dt_cg_store_val(pcb, arg, DTRACEACT_DIFEXPR, NULL, flags) == -1)
> >   		dnerror(arg, D_PROTO_ARG,
> >   			"trace( ) argument #1 is incompatible with prototype:\n"
> >   			"\tprototype: scalar or string\n\t argument: %s\n",
> > @@ -1934,25 +1978,6 @@ dt_cg_setx(dt_irlist_t *dlp, int reg, uint64_t x)
> >   	dt_cg_xsetx(dlp, NULL, DT_LBL_NONE, reg, x);
> >   }
> > -/*
> > - * When loading bit-fields, we want to convert a byte count in the range
> > - * 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc).  The clp2() function
> > - * is a clever implementation from "Hacker's Delight" by Henry Warren, Jr.
> > - */
> > -static size_t
> > -clp2(size_t x)
> > -{
> > -	x--;
> > -
> > -	x |= (x >> 1);
> > -	x |= (x >> 2);
> > -	x |= (x >> 4);
> > -	x |= (x >> 8);
> > -	x |= (x >> 16);
> > -
> > -	return x + 1;
> > -}
> > -
> >   /*
> >    * Lookup the correct load opcode to use for the specified node and CTF type.
> >    * We determine the size and convert it to a 3-bit index.  Our lookup table
> > diff --git a/test/unittest/actions/trace/tst.array.d b/test/unittest/actions/trace/tst.array.d
> > new file mode 100644
> > index 00000000..104d42e1
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.array.d
> > @@ -0,0 +1,18 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +/*
> > + * ASSERTION: The trace() action prints an array correctly.
> > + *
> > + * SECTION: Actions and Subroutines/trace()
> > + */
> > +
> > +BEGIN
> > +{
> > +	trace(curthread->comm);
> > +	exit(0);
> > +}
> > diff --git a/test/unittest/actions/trace/tst.array.r b/test/unittest/actions/trace/tst.array.r
> > new file mode 100644
> > index 00000000..872f16f6
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.array.r
> > @@ -0,0 +1,8 @@
> > +                   FUNCTION:NAME
> > +                          :BEGIN
> > +             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  0123456789abcdef
> > +         0: 64 74 72 61 63 65 00 00 73 68 00 00 00 00 00 00  dtrace..sh......
> > +
> > +
> > +-- @@stderr --
> > +dtrace: script 'test/unittest/actions/trace/tst.array.d' matched 1 probe
> > diff --git a/test/unittest/actions/trace/tst.struct.d b/test/unittest/actions/trace/tst.struct.d
> > new file mode 100644
> > index 00000000..ec60ea11
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.struct.d
> > @@ -0,0 +1,27 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +/*
> > + * ASSERTION: The trace() action prints a struct correctly.
> > + *
> > + * SECTION: Actions and Subroutines/trace()
> > + */
> > +
> > +struct {
> > +	int	a;
> > +	char	b;
> > +	int	c;
> > +} st;
> > +
> > +BEGIN
> > +{
> > +	st.a = 0x1234;
> > +	st.b = 0;
> > +	st.c = 0x9876;
> > +	trace(st);
> > +	exit(0);
> > +}
> > diff --git a/test/unittest/actions/trace/tst.struct.r b/test/unittest/actions/trace/tst.struct.r
> > new file mode 100644
> > index 00000000..0658ea88
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.struct.r
> > @@ -0,0 +1,8 @@
> > +                   FUNCTION:NAME
> > +                          :BEGIN
> > +             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  0123456789abcdef
> > +         0: 34 12 00 00 00 00 00 00 76 98 00 00              4.......v...
> > +
> > +
> > +-- @@stderr --
> > +dtrace: script 'test/unittest/actions/trace/tst.struct.d' matched 1 probe
> > diff --git a/test/unittest/actions/trace/tst.struct2.d b/test/unittest/actions/trace/tst.struct2.d
> > new file mode 100644
> > index 00000000..36de485f
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.struct2.d
> > @@ -0,0 +1,23 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +/*
> > + * ASSERTION: The trace() action prints a struct { int8_t } correctly.
> > + *
> > + * SECTION: Actions and Subroutines/trace()
> > + */
> > +
> > +struct {
> > +	int8_t	x;
> > +} st;
> > +
> > +BEGIN
> > +{
> > +	st.x = 0x34;
> > +	trace(st);
> > +	exit(0);
> > +}
> > diff --git a/test/unittest/actions/trace/tst.struct2.r b/test/unittest/actions/trace/tst.struct2.r
> > new file mode 100644
> > index 00000000..2154b90e
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.struct2.r
> > @@ -0,0 +1,8 @@
> > +                   FUNCTION:NAME
> > +                          :BEGIN
> > +             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  0123456789abcdef
> > +         0: 34                                               4
> > +
> > +
> > +-- @@stderr --
> > +dtrace: script 'test/unittest/actions/trace/tst.struct2.d' matched 1 probe
> > diff --git a/test/unittest/actions/trace/tst.struct3.d b/test/unittest/actions/trace/tst.struct3.d
> > new file mode 100644
> > index 00000000..642364f2
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.struct3.d
> > @@ -0,0 +1,23 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +/*
> > + * ASSERTION: The trace() action prints a struct { int16_t } correctly.
> > + *
> > + * SECTION: Actions and Subroutines/trace()
> > + */
> > +
> > +struct {
> > +	int16_t	x;
> > +} st;
> > +
> > +BEGIN
> > +{
> > +	st.x = 0x34;
> > +	trace(st);
> > +	exit(0);
> > +}
> > diff --git a/test/unittest/actions/trace/tst.struct3.r b/test/unittest/actions/trace/tst.struct3.r
> > new file mode 100644
> > index 00000000..3b8fb3b3
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.struct3.r
> > @@ -0,0 +1,8 @@
> > +                   FUNCTION:NAME
> > +                          :BEGIN
> > +             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  0123456789abcdef
> > +         0: 34 00                                            4.
> > +
> > +
> > +-- @@stderr --
> > +dtrace: script 'test/unittest/actions/trace/tst.struct3.d' matched 1 probe
> > diff --git a/test/unittest/actions/trace/tst.struct4.d b/test/unittest/actions/trace/tst.struct4.d
> > new file mode 100644
> > index 00000000..94360d90
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.struct4.d
> > @@ -0,0 +1,23 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +/*
> > + * ASSERTION: The trace() action prints a struct { int32_t } correctly.
> > + *
> > + * SECTION: Actions and Subroutines/trace()
> > + */
> > +
> > +struct {
> > +	int32_t	x;
> > +} st;
> > +
> > +BEGIN
> > +{
> > +	st.x = 0x34;
> > +	trace(st);
> > +	exit(0);
> > +}
> > diff --git a/test/unittest/actions/trace/tst.struct4.r b/test/unittest/actions/trace/tst.struct4.r
> > new file mode 100644
> > index 00000000..90fa1a17
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.struct4.r
> > @@ -0,0 +1,8 @@
> > +                   FUNCTION:NAME
> > +                          :BEGIN
> > +             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  0123456789abcdef
> > +         0: 34 00 00 00                                      4...
> > +
> > +
> > +-- @@stderr --
> > +dtrace: script 'test/unittest/actions/trace/tst.struct4.d' matched 1 probe
> > diff --git a/test/unittest/actions/trace/tst.struct5.d b/test/unittest/actions/trace/tst.struct5.d
> > new file mode 100644
> > index 00000000..0ecc9771
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.struct5.d
> > @@ -0,0 +1,23 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +/*
> > + * ASSERTION: The trace() action prints a struct { int64_t } correctly.
> > + *
> > + * SECTION: Actions and Subroutines/trace()
> > + */
> > +
> > +struct {
> > +	int64_t	x;
> > +} st;
> > +
> > +BEGIN
> > +{
> > +	st.x = 0x34;
> > +	trace(st);
> > +	exit(0);
> > +}
> > diff --git a/test/unittest/actions/trace/tst.struct5.r b/test/unittest/actions/trace/tst.struct5.r
> > new file mode 100644
> > index 00000000..687a0e59
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.struct5.r
> > @@ -0,0 +1,8 @@
> > +                   FUNCTION:NAME
> > +                          :BEGIN
> > +             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  0123456789abcdef
> > +         0: 34 00 00 00 00 00 00 00                          4.......
> > +
> > +
> > +-- @@stderr --
> > +dtrace: script 'test/unittest/actions/trace/tst.struct5.d' matched 1 probe
> > diff --git a/test/unittest/actions/trace/tst.union.d b/test/unittest/actions/trace/tst.union.d
> > new file mode 100644
> > index 00000000..56b2ff81
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.union.d
> > @@ -0,0 +1,25 @@
> > +/*
> > + * Oracle Linux DTrace.
> > + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> > + * Licensed under the Universal Permissive License v 1.0 as shown at
> > + * http://oss.oracle.com/licenses/upl.
> > + */
> > +
> > +/*
> > + * ASSERTION: The trace() action prints a union correctly.
> > + *
> > + * SECTION: Actions and Subroutines/trace()
> > + */
> > +
> > +union {
> > +	int	a;
> > +	char	b[3];
> > +	short	c;
> > +} u;
> > +
> > +BEGIN
> > +{
> > +	u.a = 0x12345678;
> > +	trace(u);
> > +	exit(0);
> > +}
> > diff --git a/test/unittest/actions/trace/tst.union.r b/test/unittest/actions/trace/tst.union.r
> > new file mode 100644
> > index 00000000..48098d11
> > --- /dev/null
> > +++ b/test/unittest/actions/trace/tst.union.r
> > @@ -0,0 +1,8 @@
> > +                   FUNCTION:NAME
> > +                          :BEGIN
> > +             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  0123456789abcdef
> > +         0: 78 56 34 12                                      xV4.
> > +
> > +
> > +-- @@stderr --
> > +dtrace: script 'test/unittest/actions/trace/tst.union.d' matched 1 probe
> 
> _______________________________________________
> 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