[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