[DTrace-devel] [PATCH 1/2] Add support for progenyof() subroutine
Kris Van Hees
kris.van.hees at oracle.com
Fri Apr 22 04:20:51 UTC 2022
On Thu, Feb 17, 2022 at 03:45:30PM -0500, eugene.loh--- via DTrace-devel wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
>
> Also, clean up err*progeny*.d tests. In particular,
>
> *) err.D_FUNC_UNDEF.progenyofbad1.d was failing because it had always
> been wrong: the test was mislabeled. The test was introduced in patch
> c17a42e11dba "Add the OpenSolaris dtrace testsuite."
> with a .r results file that explicitly indicates D_PROTO_LEN,
> even though the test name expects D_FUNC_UNDEF. However, runtest.sh
> did not check the error tag. Though runtest.sh was eventually fixed,
> the test fail was simply dismissed XFAIL.
>
> *) err.D_PROTO_LEN.progenyofbad2.d was passing, but for reasons unrelated
> to progenyof() or its argument checks. The test used progenyof(trace())
> and therefore did not test progenyof() at all; rather, it failed on
> trace(), which is missing its argument.
>
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com
... and I will put it on dev
> ---
> bpf/Build | 1 +
> bpf/progenyof.S | 88 +++++++++++++++++++
> libdtrace/dt_bpf.h | 2 +
> libdtrace/dt_cc.c | 26 ++++++
> libdtrace/dt_cg.c | 30 ++++++-
> libdtrace/dt_dlibs.c | 2 +
> .../funcs/err.D_FUNC_UNDEF.progenyofbad1.r | 2 -
> ...bad2.d => err.D_PROTO_ARG.progenyofbad1.d} | 11 +--
> .../funcs/err.D_PROTO_ARG.progenyofbad1.r | 4 +
> .../funcs/err.D_PROTO_ARG.progenyofbad2.d | 18 ++++
> .../funcs/err.D_PROTO_ARG.progenyofbad2.r | 4 +
> .../funcs/err.D_PROTO_LEN.progenyofbad2.r | 2 -
> .../funcs/err.D_PROTO_LEN.progenyoftoofew.d | 18 ++++
> .../funcs/err.D_PROTO_LEN.progenyoftoofew.r | 2 +
> ...1.d => err.D_PROTO_LEN.progenyoftoomany.d} | 10 +--
> .../funcs/err.D_PROTO_LEN.progenyoftoomany.r | 2 +
> test/unittest/funcs/tst.progenyof.d | 3 +-
> 17 files changed, 203 insertions(+), 22 deletions(-)
> create mode 100644 bpf/progenyof.S
> delete mode 100644 test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.r
> rename test/unittest/funcs/{err.D_PROTO_LEN.progenyofbad2.d => err.D_PROTO_ARG.progenyofbad1.d} (55%)
> create mode 100644 test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.r
> create mode 100644 test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d
> create mode 100644 test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.r
> delete mode 100644 test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.r
> create mode 100644 test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.d
> create mode 100644 test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.r
> rename test/unittest/funcs/{err.D_FUNC_UNDEF.progenyofbad1.d => err.D_PROTO_LEN.progenyoftoomany.d} (59%)
> create mode 100644 test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.r
>
> diff --git a/bpf/Build b/bpf/Build
> index 69a2e4d4..5cf9c45f 100644
> --- a/bpf/Build
> +++ b/bpf/Build
> @@ -30,6 +30,7 @@ bpf_dlib_SOURCES = \
> index.S \
> inet_ntoa.S \
> lltostr.S \
> + progenyof.S \
> probe_error.c \
> rindex.S \
> speculation.c \
> diff --git a/bpf/progenyof.S b/bpf/progenyof.S
> new file mode 100644
> index 00000000..e17eaa98
> --- /dev/null
> +++ b/bpf/progenyof.S
> @@ -0,0 +1,88 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
> + */
> +
> +#define BPF_FUNC_probe_read 4
> +#define BPF_FUNC_get_current_task 35
> +
> + .text
> + .align 4
> + .global dt_progenyof
> + .type dt_progenyof, @function
> +dt_progenyof:
> +#define ARG %r6
> +#define CNT %r7
> +#define PTR %r8
> +#define VAL %r9
> +
> + /* uint64_t dt_progenyof(pid_t arg); */
> + mov ARG, %r1
> + lsh ARG, 32
> + rsh ARG, 32
> +
> + /* assure the BPF verifier there is no infinite loop */
> + mov CNT, 256
> +
> + /* ptr = bpf_get_current_task() */
> + call BPF_FUNC_get_current_task
> + mov PTR, %r0
> +
> +.Lloop:
> + /* if (ptr == 0) goto Lret0 */
> + jeq PTR, 0, .Lret0
> +
> + /* if (count <= 0) goto Lret0 */
> + jsle CNT, 0, .Lret0
> +
> + /* val = *((uint32_t *)(ptr + TASK_PID)), using [%fp+-8] as temp */
> + mov %r1, %fp
> + add %r1, -8
> + mov %r2, 4
> + lddw %r3, TASK_PID
> + add %r3, PTR
> + call BPF_FUNC_probe_read
> + jne %r0, 0, .Lret0
> + ldxw VAL, [%fp+-8]
> + lsh VAL, 32
> + rsh VAL, 32
> +
> + /* if (val == arg) goto Lret1 */
> + jeq VAL, ARG, .Lret1
> +
> + /* val = *((uint64_t *)(ptr + TASK_REAL_PARENT)), using [%fp+-8] as temp */
> + mov %r1, %fp
> + add %r1, -8
> + mov %r2, 8
> + lddw %r3, TASK_REAL_PARENT
> + add %r3, PTR
> + call BPF_FUNC_probe_read
> + jne %r0, 0, .Lret0
> + ldxdw VAL, [%fp+-8]
> +
> + /* if (val == ptr) goto Lret0 */
> + jeq VAL, PTR, .Lret0
> +
> + /* ptr = val */
> + mov PTR, VAL
> +
> + /* count-- */
> + sub CNT, 1
> +
> + /* goto Lloop */
> + ja .Lloop
> +
> +.Lret0:
> + /* return 0 */
> + mov %r0, 0
> + exit
> +
> +.Lret1:
> + /* return 1 */
> + mov %r0, 1
> + exit
> + .size dt_progenyof, .-dt_progenyof
> +#undef ARG
> +#undef CNT
> +#undef PTR
> +#undef VAL
> diff --git a/libdtrace/dt_bpf.h b/libdtrace/dt_bpf.h
> index 5b9bae80..e361d103 100644
> --- a/libdtrace/dt_bpf.h
> +++ b/libdtrace/dt_bpf.h
> @@ -28,6 +28,8 @@ extern "C" {
> #define DT_CONST_BOOTTM 8
> #define DT_CONST_NSPEC 9
> #define DT_CONST_NCPUS 10
> +#define DT_CONST_TASK_REAL_PARENT 11
> +#define DT_CONST_TASK_PID 12
>
> extern int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
> int group_fd, unsigned long flags);
> diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
> index ce824eb5..f5b59109 100644
> --- a/libdtrace/dt_cc.c
> +++ b/libdtrace/dt_cc.c
> @@ -2367,6 +2367,32 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
> return -1;
> nrp->dofr_data = boottime;
> continue;
> + case DT_CONST_TASK_REAL_PARENT: {
> + ctf_file_t *cfp = dtp->dt_shared_ctf;
> + ctf_id_t type = ctf_lookup_by_name(cfp, "struct task_struct");
> + ctf_membinfo_t ctm;
> +
> + if (type == CTF_ERR)
> + return -1;
> +
> + if (ctf_member_info(cfp, type, "real_parent", &ctm) == CTF_ERR)
> + return -1;
> + nrp->dofr_data = ctm.ctm_offset / NBBY;
> + continue;
> + }
> + case DT_CONST_TASK_PID: {
> + ctf_file_t *cfp = dtp->dt_shared_ctf;
> + ctf_id_t type = ctf_lookup_by_name(cfp, "struct task_struct");
> + ctf_membinfo_t ctm;
> +
> + if (type == CTF_ERR)
> + return -1;
> +
> + if (ctf_member_info(cfp, type, "pid", &ctm) == CTF_ERR)
> + return -1;
> + nrp->dofr_data = ctm.ctm_offset / NBBY;
> + continue;
> + }
> default:
> /* probe name -> value is probe id */
> if (strchr(idp->di_name, ':') != NULL)
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index ef04fafd..30f9705f 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -3499,6 +3499,34 @@ dt_cg_subr_lltostr(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> TRACE_REGSET(" subr-lltostr:End ");
> }
>
> +static void
> +dt_cg_subr_progenyof(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> +{
> + dt_ident_t *idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_progenyof");
> + dt_node_t *arg = dnp->dn_args;
> +
> + assert(idp != NULL);
> +
> + TRACE_REGSET(" subr-progenyof:Begin");
> + dt_cg_node(arg, dlp, drp);
> +
> + if (dt_regset_xalloc_args(drp) == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> + emit(dlp, BPF_MOV_REG(BPF_REG_1, arg->dn_reg));
> + dt_regset_free(drp, arg->dn_reg);
> + dt_regset_xalloc(drp, BPF_REG_0);
> + emite(dlp, BPF_CALL_FUNC(idp->di_id), idp);
> + dt_regset_free_args(drp);
> +
> + dnp->dn_reg = dt_regset_alloc(drp);
> + if (dnp->dn_reg == -1)
> + longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
> + emit(dlp, BPF_MOV_REG(dnp->dn_reg, BPF_REG_0));
> + dt_regset_free(drp, BPF_REG_0);
> +
> + TRACE_REGSET(" subr-progenyof:End ");
> +}
> +
> static void
> dt_cg_subr_rand(dt_node_t *dnp, dt_irlist_t *dlp, dt_regset_t *drp)
> {
> @@ -4137,7 +4165,7 @@ static dt_cg_subr_f *_dt_cg_subr[DIF_SUBR_MAX + 1] = {
> [DIF_SUBR_COPYIN] = NULL,
> [DIF_SUBR_COPYINSTR] = NULL,
> [DIF_SUBR_SPECULATION] = &dt_cg_subr_speculation,
> - [DIF_SUBR_PROGENYOF] = NULL,
> + [DIF_SUBR_PROGENYOF] = &dt_cg_subr_progenyof,
> [DIF_SUBR_STRLEN] = &dt_cg_subr_strlen,
> [DIF_SUBR_COPYOUT] = NULL,
> [DIF_SUBR_COPYOUTSTR] = NULL,
> diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
> index ebed0509..a8d112d4 100644
> --- a/libdtrace/dt_dlibs.c
> +++ b/libdtrace/dt_dlibs.c
> @@ -79,6 +79,8 @@ static const dt_ident_t dt_bpf_symbols[] = {
> DT_BPF_SYMBOL_ID(BOOTTM, DT_IDENT_SCALAR, DT_CONST_BOOTTM),
> DT_BPF_SYMBOL_ID(NSPEC, DT_IDENT_SCALAR, DT_CONST_NSPEC),
> DT_BPF_SYMBOL_ID(NCPUS, DT_IDENT_SCALAR, DT_CONST_NCPUS),
> + DT_BPF_SYMBOL_ID(TASK_REAL_PARENT, DT_IDENT_SCALAR, DT_CONST_TASK_REAL_PARENT),
> + DT_BPF_SYMBOL_ID(TASK_PID, DT_IDENT_SCALAR, DT_CONST_TASK_PID),
>
> /* End-of-list marker */
> { NULL, }
> diff --git a/test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.r b/test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.r
> deleted file mode 100644
> index e7a64031..00000000
> --- a/test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.r
> +++ /dev/null
> @@ -1,2 +0,0 @@
> --- @@stderr --
> -dtrace: failed to compile script test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.d: [D_PROTO_LEN] line 19: progenyof( ) prototype mismatch: 2 args passed, 1 expected
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.d b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.d
> similarity index 55%
> rename from test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.d
> rename to test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.d
> index 033b3d54..4a00d08f 100644
> --- a/test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.d
> +++ b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.d
> @@ -1,23 +1,18 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
> + * 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:
> - * progenyof() should return an error if the argument is an
> - * incorrect type.
> + * ASSERTION: progenyof() should take a pid_t argument.
> *
> * SECTION: Actions and Subroutines/progenyof()
> - *
> */
>
> -
> BEGIN
> {
> - progenyof(trace());
> + progenyof("some_string");
> exit(0);
> }
> -
> diff --git a/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.r b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.r
> new file mode 100644
> index 00000000..158eee85
> --- /dev/null
> +++ b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.r
> @@ -0,0 +1,4 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_ARG.progenyofbad1.d: [D_PROTO_ARG] line 16: progenyof( ) argument #1 is incompatible with prototype:
> + prototype: pid_t
> + argument: string
> diff --git a/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d
> new file mode 100644
> index 00000000..67735b79
> --- /dev/null
> +++ b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d
> @@ -0,0 +1,18 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2007, 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: progenyof() should take a pid_t argument.
> + *
> + * SECTION: Actions and Subroutines/progenyof()
> + */
> +
> +BEGIN
> +{
> + progenyof(trace(1));
> + exit(0);
> +}
> diff --git a/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.r b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.r
> new file mode 100644
> index 00000000..73dec003
> --- /dev/null
> +++ b/test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.r
> @@ -0,0 +1,4 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_ARG.progenyofbad2.d: [D_PROTO_ARG] line 16: progenyof( ) argument #1 is incompatible with prototype:
> + prototype: pid_t
> + argument: void
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.r b/test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.r
> deleted file mode 100644
> index 35145323..00000000
> --- a/test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.r
> +++ /dev/null
> @@ -1,2 +0,0 @@
> --- @@stderr --
> -dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.progenyofbad2.d: [D_PROTO_LEN] line 20: trace( ) prototype mismatch: 0 args passed, 1 expected
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.d b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.d
> new file mode 100644
> index 00000000..96bf8b4d
> --- /dev/null
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.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: progenyof() should take one argument.
> + *
> + * SECTION: Actions and Subroutines/progenyof()
> + */
> +
> +BEGIN
> +{
> + progenyof();
> + exit(0);
> +}
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.r b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.r
> new file mode 100644
> index 00000000..e31d0be3
> --- /dev/null
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.progenyoftoofew.d: [D_PROTO_LEN] line 16: progenyof( ) prototype mismatch: 0 args passed, 1 expected
> diff --git a/test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.d b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.d
> similarity index 59%
> rename from test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.d
> rename to test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.d
> index dca7f283..2d4d922a 100644
> --- a/test/unittest/funcs/err.D_FUNC_UNDEF.progenyofbad1.d
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.d
> @@ -1,22 +1,18 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 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.
> */
> -/* @@xfail: dtv2 */
> +
> /*
> - * ASSERTION:
> - * progenyof() should accept one argument - a pid
> + * ASSERTION: progenyof() should take one argument.
> *
> * SECTION: Actions and Subroutines/progenyof()
> - *
> */
>
> -
> BEGIN
> {
> progenyof(1, 2);
> exit(0);
> }
> -
> diff --git a/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.r b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.r
> new file mode 100644
> index 00000000..46b4f985
> --- /dev/null
> +++ b/test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/funcs/err.D_PROTO_LEN.progenyoftoomany.d: [D_PROTO_LEN] line 16: progenyof( ) prototype mismatch: 2 args passed, 1 expected
> diff --git a/test/unittest/funcs/tst.progenyof.d b/test/unittest/funcs/tst.progenyof.d
> index cadeb654..9d73420f 100644
> --- a/test/unittest/funcs/tst.progenyof.d
> +++ b/test/unittest/funcs/tst.progenyof.d
> @@ -1,6 +1,6 @@
> /*
> * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2006, 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.
> */
> @@ -14,7 +14,6 @@
> *
> */
>
> -/* @@xfail: dtv2 */
> /* @@trigger: pid-tst-float */
>
> #pragma D option quiet
> --
> 2.18.4
>
>
> _______________________________________________
> 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