[DTrace-devel] [PATCH 08/61] Fix fbt:::return and pid:::return arg1

Kris Van Hees kris.van.hees at oracle.com
Mon Jul 11 16:55:44 UTC 2022


On Fri, Jul 08, 2022 at 10:44:52AM -0400, eugene.loh--- via DTrace-devel wrote:
> From: Eugene Loh <eugene.loh at oracle.com>
> 
> Meanwhile, set fbt:::return arg0=-1 to indicate we do not know the
> real value.
> 
> Also, remove the unused PT_REGS_BPF_*().
> 
> Signed-off-by: Eugene Loh <eugene.loh at oracle.com>

Reviewed-by: Kris Van Hees <kris.van.hees at oracle.com>

... and I will push to dev (since I have it on my pre-push branch already).

> ---
>  libdtrace/dt_cg.c                       | 24 +++++++++++-
>  libdtrace/dt_cg.h                       |  1 +
>  libdtrace/dt_prov_fbt.c                 | 20 +++++++++-
>  libdtrace/dt_prov_pid.c                 |  5 ++-
>  libdtrace/dt_pt_regs.h                  | 25 ++-----------
>  test/unittest/fbtprovider/tst.return0.d |  6 +--
>  test/unittest/fbtprovider/tst.return0.r |  1 +
>  test/unittest/fbtprovider/tst.return1.d | 50 +++++++++++++++++++++++++
>  test/unittest/fbtprovider/tst.return1.r |  1 +
>  test/unittest/pid/tst.ret1.d            |  3 +-
>  test/unittest/pid/tst.ret2.d            |  3 +-
>  11 files changed, 105 insertions(+), 34 deletions(-)
>  create mode 100644 test/unittest/fbtprovider/tst.return0.r
>  create mode 100644 test/unittest/fbtprovider/tst.return1.d
>  create mode 100644 test/unittest/fbtprovider/tst.return1.r
> 
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 3c97a6c9..4729710d 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -279,7 +279,7 @@ dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp)
>  
>  	/*
>  	 *	for (i = 0; i < PT_REGS_ARGC; i++)
> -	 *		dctx->mst->argv[i] = PT_REGS_BPF_ARGi((dt_pt_regs *)rp);
> +	 *		dctx->mst->argv[i] = PT_REGS_ARGi((dt_pt_regs *)rp);
>  	 *				// lddw %r0, [%rp + PT_REGS_ARGi]
>  	 *				// stdw [%r7 + DMST_ARG(i)], %r0
>  	 */
> @@ -369,6 +369,28 @@ dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp)
>  	}
>  }
>  
> +/*
> + * Copy return value from a dt_pt_regs structure referenced by the 'rp' argument.
> + * to mst->arg[1].  Zero the other args.
> + *
> + * The caller must ensure that %r7 contains the value set by the
> + * dt_cg_tramp_prologue*() functions.
> + */
> +void
> +dt_cg_tramp_copy_rval_from_regs(dt_pcb_t *pcb, int rp)
> +{
> +	dt_irlist_t	*dlp = &pcb->pcb_ir;
> +	int		i;
> +
> +	emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_ARG(0), 0));
> +
> +	emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_RET));
> +	emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_0));
> +
> +	for (i = 2; i < ARRAY_SIZE(((dt_mstate_t *)0)->argv); i++)
> +		emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_7, DMST_ARG(i), 0));
> +}
> +
>  typedef struct {
>  	dt_irlist_t	*dlp;
>  	dt_activity_t	act;
> diff --git a/libdtrace/dt_cg.h b/libdtrace/dt_cg.h
> index 5752151b..bc592fea 100644
> --- a/libdtrace/dt_cg.h
> +++ b/libdtrace/dt_cg.h
> @@ -25,6 +25,7 @@ extern void dt_cg_tramp_prologue(dt_pcb_t *pcb);
>  extern void dt_cg_tramp_clear_regs(dt_pcb_t *pcb);
>  extern void dt_cg_tramp_copy_regs(dt_pcb_t *pcb, int rp);
>  extern void dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int rp);
> +extern void dt_cg_tramp_copy_rval_from_regs(dt_pcb_t *pcb, int rp);
>  extern void dt_cg_tramp_call_clauses(dt_pcb_t *pcb, const dt_probe_t *prp,
>  				     dt_activity_t act);
>  extern void dt_cg_tramp_return(dt_pcb_t *pcb);
> diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
> index 62fea51e..ff2fd364 100644
> --- a/libdtrace/dt_prov_fbt.c
> +++ b/libdtrace/dt_prov_fbt.c
> @@ -167,9 +167,25 @@ static void trampoline(dt_pcb_t *pcb)
>  	 *				//     (%r7 = dctx->mst)
>  	 *				//     (%r8 = dctx->ctx)
>  	 */
> -
>  	dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
> -	dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
> +	if (strcmp(pcb->pcb_probe->desc->prb, "return") == 0) {
> +		dt_irlist_t *dlp = &pcb->pcb_ir;
> +
> +		dt_cg_tramp_copy_rval_from_regs(pcb, BPF_REG_8);
> +
> +		/*
> +		 * fbt:::return arg0 should be the function offset for
> +		 * return instruction.  Since we use kretprobes, however,
> +		 * which do not fire until the function has returned to
> +		 * its caller, information about the returning instruction
> +		 * in the callee has been lost.
> +		 *
> +		 * Set arg0=-1 to indicate that we do not know the value.
> +		 */
> +		dt_cg_xsetx(dlp, NULL, DT_LBL_NONE, BPF_REG_0, -1);
> +		emit(dlp,  BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
> +	} else
> +		dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
>  	dt_cg_tramp_epilogue(pcb);
>  }
>  
> diff --git a/libdtrace/dt_prov_pid.c b/libdtrace/dt_prov_pid.c
> index af894f79..d2b1b0d7 100644
> --- a/libdtrace/dt_prov_pid.c
> +++ b/libdtrace/dt_prov_pid.c
> @@ -211,7 +211,10 @@ static void trampoline(dt_pcb_t *pcb)
>  	 */
>  
>  	dt_cg_tramp_copy_regs(pcb, BPF_REG_8);
> -	dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
> +	if (strcmp(pcb->pcb_probe->desc->prb, "return") == 0)
> +		dt_cg_tramp_copy_rval_from_regs(pcb, BPF_REG_8);
> +	else
> +		dt_cg_tramp_copy_args_from_regs(pcb, BPF_REG_8);
>  
>  	/*
>  	 * Retrieve the PID of the process that caused the probe to fire.
> diff --git a/libdtrace/dt_pt_regs.h b/libdtrace/dt_pt_regs.h
> index 5f851573..057f1fdb 100644
> --- a/libdtrace/dt_pt_regs.h
> +++ b/libdtrace/dt_pt_regs.h
> @@ -1,6 +1,6 @@
>  /*
>   * Oracle Linux DTrace.
> - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2019, 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.
>   */
> @@ -19,7 +19,7 @@ extern "C" {
>  
>  #if defined(__amd64)
>  typedef struct pt_regs		dt_pt_regs;
> -
> +# define PT_REGS_RET		offsetof(dt_pt_regs, rax)
>  # define PT_REGS_ARG0		offsetof(dt_pt_regs, rdi)
>  # define PT_REGS_ARG1		offsetof(dt_pt_regs, rsi)
>  # define PT_REGS_ARG2		offsetof(dt_pt_regs, rdx)
> @@ -30,17 +30,9 @@ typedef struct pt_regs		dt_pt_regs;
>  # define PT_REGS_ARGSTKBASE	1
>  # define PT_REGS_IP		offsetof(dt_pt_regs, rip)
>  # define PT_REGS_SP		offsetof(dt_pt_regs, rsp)
> -
> -# define PT_REGS_BPF_ARG0(r)	((r)->rdi)
> -# define PT_REGS_BPF_ARG1(r)	((r)->rsi)
> -# define PT_REGS_BPF_ARG2(r)	((r)->rdx)
> -# define PT_REGS_BPF_ARG3(r)	((r)->rcx)
> -# define PT_REGS_BPF_ARG4(r)	((r)->r8)
> -# define PT_REGS_BPF_ARG5(r)	((r)->r9)
> -# define PT_REGS_BPF_IP(r)	((r)->rip)
> -# define PT_REGS_BPF_SP(r)	((r)->rsp)
>  #elif defined(__aarch64__)
>  typedef struct user_pt_regs	dt_pt_regs;
> +# define PT_REGS_RET		offsetof(dt_pt_regs, regs[0])
>  # define PT_REGS_ARG0		offsetof(dt_pt_regs, regs[0])
>  # define PT_REGS_ARG1		offsetof(dt_pt_regs, regs[1])
>  # define PT_REGS_ARG2		offsetof(dt_pt_regs, regs[2])
> @@ -53,17 +45,6 @@ typedef struct user_pt_regs	dt_pt_regs;
>  # define PT_REGS_ARGSTKBASE	0
>  # define PT_REGS_IP		offsetof(dt_pt_regs, pc)
>  # define PT_REGS_SP		offsetof(dt_pt_regs, sp)
> -
> -# define PT_REGS_BPF_ARG0(r)	((r)->regs[0])
> -# define PT_REGS_BPF_ARG1(r)	((r)->regs[1])
> -# define PT_REGS_BPF_ARG2(r)	((r)->regs[2])
> -# define PT_REGS_BPF_ARG3(r)	((r)->regs[3])
> -# define PT_REGS_BPF_ARG4(r)	((r)->regs[4])
> -# define PT_REGS_BPF_ARG5(r)	((r)->regs[5])
> -# define PT_REGS_BPF_ARG6(r)	((r)->regs[6])
> -# define PT_REGS_BPF_ARG7(r)	((r)->regs[7])
> -# define PT_REGS_BPF_IP(r)	((r)->pc)
> -# define PT_REGS_BPF_SP(r)	((r)->sp)
>  #else
>  # error ISA not supported
>  #endif
> diff --git a/test/unittest/fbtprovider/tst.return0.d b/test/unittest/fbtprovider/tst.return0.d
> index 3d58e84f..0b7091b3 100644
> --- a/test/unittest/fbtprovider/tst.return0.d
> +++ b/test/unittest/fbtprovider/tst.return0.d
> @@ -1,18 +1,16 @@
>  /*
>   * Oracle Linux DTrace.
> - * Copyright (c) 2006, 2021, 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.
>   */
>  
>  /*
> - * ASSERTION: simple fbt provider arg0 and probfunc print test.
> + * ASSERTION: simple fbt provider arg0 and probefunc print test.
>   *
>   * SECTION: FBT Provider/Probe arguments
>   */
>  
> -/* @@runtest-opts: -Z */
> -
>  #pragma D option quiet
>  #pragma D option statusrate=10ms
>  
> diff --git a/test/unittest/fbtprovider/tst.return0.r b/test/unittest/fbtprovider/tst.return0.r
> new file mode 100644
> index 00000000..53308c30
> --- /dev/null
> +++ b/test/unittest/fbtprovider/tst.return0.r
> @@ -0,0 +1 @@
> +do_sys_poll ffffffffffffffff returned 0
> diff --git a/test/unittest/fbtprovider/tst.return1.d b/test/unittest/fbtprovider/tst.return1.d
> new file mode 100644
> index 00000000..751e8865
> --- /dev/null
> +++ b/test/unittest/fbtprovider/tst.return1.d
> @@ -0,0 +1,50 @@
> +/*
> + * 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.
> + */
> +
> +/* @@trigger: bogus-ioctl */
> +/* @@trigger-timing: before */
> +/* @@runtest-opts: $_pid */
> +
> +#pragma D option destructive
> +#pragma D option quiet
> +#pragma D option zdefs
> +
> +BEGIN
> +{
> +	niter = 0;
> +	rval = -1;
> +}
> +
> +/* notify the trigger to exit its ioctl() loop */
> +syscall::ioctl:entry
> +/pid == $1/
> +{
> +	raise(SIGUSR1);
> +}
> +
> +/* if we enter open(), reset the expected return value */
> +syscall::open*:entry
> +/pid == $1/
> +{
> +	reset = 1;
> +}
> +
> +/* check the return value (the first probe resets the expected value) */
> +syscall:vmlinux:open*:return,
> +fbt:vmlinux:do_sys_open*:return
> +/pid == $1/
> +{
> +	rval = (reset ? arg1 : rval);
> +	printf("%s", arg1 == rval ? "" : "ERROR mismatch\n");
> +	reset = 0;
> +}
> +
> +syscall::open*:return
> +/pid == $1 && ++niter >= 20/
> +{
> +	exit(0);
> +}
> diff --git a/test/unittest/fbtprovider/tst.return1.r b/test/unittest/fbtprovider/tst.return1.r
> new file mode 100644
> index 00000000..8b137891
> --- /dev/null
> +++ b/test/unittest/fbtprovider/tst.return1.r
> @@ -0,0 +1 @@
> +
> diff --git a/test/unittest/pid/tst.ret1.d b/test/unittest/pid/tst.ret1.d
> index bdf7d274..398e2cc8 100644
> --- a/test/unittest/pid/tst.ret1.d
> +++ b/test/unittest/pid/tst.ret1.d
> @@ -1,10 +1,9 @@
>  /*
>   * 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.
>   */
> -/* @@xfail: dtv2 */
>  /* @@runtest-opts: $_pid */
>  /* @@trigger: pid-tst-ret1 */
>  /* @@trigger-timing: before */
> diff --git a/test/unittest/pid/tst.ret2.d b/test/unittest/pid/tst.ret2.d
> index d3d482e3..a542646a 100644
> --- a/test/unittest/pid/tst.ret2.d
> +++ b/test/unittest/pid/tst.ret2.d
> @@ -1,10 +1,9 @@
>  /*
>   * 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.
>   */
> -/* @@xfail: dtv2 */
>  /* @@runtest-opts: $_pid */
>  /* @@trigger: pid-tst-ret2 */
>  /* @@trigger-timing: before */
> -- 
> 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