[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