[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